blob: 9550488ec2455963f7d5bd5932e953db73f13727 [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"
Victor Vasiliev7752898d2019-11-14 21:30:2250#include "net/quic/mock_quic_context.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0851#include "net/quic/mock_quic_data.h"
52#include "net/quic/quic_chromium_alarm_factory.h"
53#include "net/quic/quic_http_stream.h"
54#include "net/quic/quic_http_utils.h"
55#include "net/quic/quic_stream_factory_peer.h"
56#include "net/quic/quic_test_packet_maker.h"
57#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0058#include "net/socket/client_socket_factory.h"
59#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2160#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2861#include "net/socket/socket_performance_watcher.h"
62#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0063#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5864#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5765#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2966#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0167#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4368#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4069#include "net/test/test_with_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5170#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
71#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
72#include "net/third_party/quiche/src/quic/core/quic_framer.h"
73#include "net/third_party/quiche/src/quic/core/quic_utils.h"
74#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
75#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
76#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
77#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
78#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
79#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
80#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
81#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1482#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
83#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2984#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0085#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4886#include "net/url_request/url_request.h"
87#include "net/url_request/url_request_job_factory_impl.h"
88#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0189#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0090#include "testing/gtest/include/gtest/gtest.h"
91#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4692#include "url/gurl.h"
Matt Menke3233d8f22019-08-20 21:01:4993#include "url/origin.h"
[email protected]61a527782013-02-21 03:58:0094
Reilly Grant89a7e512018-01-20 01:57:1695using ::testing::ElementsAre;
96using ::testing::Key;
97
bnc508835902015-05-12 20:10:2998namespace net {
99namespace test {
[email protected]61a527782013-02-21 03:58:00100
101namespace {
102
bnc359ed2a2016-04-29 20:43:45103enum DestinationType {
104 // In pooling tests with two requests for different origins to the same
105 // destination, the destination should be
106 SAME_AS_FIRST, // the same as the first origin,
107 SAME_AS_SECOND, // the same as the second origin, or
108 DIFFERENT, // different from both.
109};
110
rchf114d982015-10-21 01:34:56111static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52112 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12113static const char kQuicAlternativeServiceWithProbabilityHeader[] =
114 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56115static const char kQuicAlternativeServiceDifferentPortHeader[] =
116 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20117
rch9ae5b3b2016-02-11 00:36:29118const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45119const char kDifferentHostname[] = "different.example.com";
120
David Schinazi09e9a6012019-10-03 17:37:57121struct TestParams {
122 quic::ParsedQuicVersion version;
123 bool client_headers_include_h2_stream_dependency;
124};
125
126// Used by ::testing::PrintToStringParamName().
127std::string PrintToString(const TestParams& p) {
128 return quic::QuicStrCat(
129 ParsedQuicVersionToString(p.version), "_",
130 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
131 "Dependency");
132}
133
bnc359ed2a2016-04-29 20:43:45134// Run QuicNetworkTransactionWithDestinationTest instances with all value
135// combinations of version and destination_type.
136struct PoolingTestParams {
Nick Harper23290b82019-05-02 00:02:56137 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45138 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05139 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45140};
141
David Schinazi09e9a6012019-10-03 17:37:57142// Used by ::testing::PrintToStringParamName().
143std::string PrintToString(const PoolingTestParams& p) {
144 const char* destination_string = "";
145 switch (p.destination_type) {
146 case SAME_AS_FIRST:
147 destination_string = "SAME_AS_FIRST";
148 break;
149 case SAME_AS_SECOND:
150 destination_string = "SAME_AS_SECOND";
151 break;
152 case DIFFERENT:
153 destination_string = "DIFFERENT";
154 break;
155 }
156 return quic::QuicStrCat(
157 ParsedQuicVersionToString(p.version), "_", destination_string, "_",
158 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
159 "Dependency");
160}
161
zhongyie537a002017-06-27 16:48:21162std::string GenerateQuicVersionsListForAltSvcHeader(
Nick Harper23290b82019-05-02 00:02:56163 const quic::ParsedQuicVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21164 std::string result = "";
Nick Harper23290b82019-05-02 00:02:56165 for (const quic::ParsedQuicVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21166 if (!result.empty())
167 result.append(",");
Nick Harper23290b82019-05-02 00:02:56168 result.append(base::NumberToString(version.transport_version));
zhongyie537a002017-06-27 16:48:21169 }
170 return result;
171}
172
David Schinazi09e9a6012019-10-03 17:37:57173std::vector<TestParams> GetTestParams() {
174 std::vector<TestParams> params;
175 quic::ParsedQuicVersionVector all_supported_versions =
176 quic::AllSupportedVersions();
177 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43178 params.push_back(TestParams{version, false});
179 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57180 }
181 return params;
182}
183
bnc359ed2a2016-04-29 20:43:45184std::vector<PoolingTestParams> GetPoolingTestParams() {
185 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56186 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40187 quic::AllSupportedVersions();
Nick Harper23290b82019-05-02 00:02:56188 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43189 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
190 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
191 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
192 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
193 params.push_back(PoolingTestParams{version, DIFFERENT, false});
194 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45195 }
196 return params;
197}
bncb07c05532015-05-14 19:07:20198
[email protected]61a527782013-02-21 03:58:00199} // namespace
200
ryansturm49a8cb12016-06-15 16:51:09201class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12202 public:
ryansturm49a8cb12016-06-15 16:51:09203 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12204
ryansturm49a8cb12016-06-15 16:51:09205 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12206
ryansturm49a8cb12016-06-15 16:51:09207 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
208 HttpRequestHeaders* request_headers) {
209 if (!proxy_info.is_http() && !proxy_info.is_https() &&
210 !proxy_info.is_quic()) {
211 return;
212 }
213 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12214 }
215
216 private:
ryansturm49a8cb12016-06-15 16:51:09217 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12218};
219
tbansal0f56a39a2016-04-07 22:03:38220class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40221 public:
tbansal180587c2017-02-16 15:13:23222 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
223 bool* rtt_notification_received)
224 : should_notify_updated_rtt_(should_notify_updated_rtt),
225 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38226 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40227
tbansal180587c2017-02-16 15:13:23228 bool ShouldNotifyUpdatedRTT() const override {
229 return *should_notify_updated_rtt_;
230 }
tbansalfdf5665b2015-09-21 22:46:40231
tbansal0f56a39a2016-04-07 22:03:38232 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
233 *rtt_notification_received_ = true;
234 }
235
236 void OnConnectionChanged() override {}
237
238 private:
tbansal180587c2017-02-16 15:13:23239 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38240 bool* rtt_notification_received_;
241
242 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
243};
244
245class TestSocketPerformanceWatcherFactory
246 : public SocketPerformanceWatcherFactory {
247 public:
248 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23249 : watcher_count_(0u),
250 should_notify_updated_rtt_(true),
251 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38252 ~TestSocketPerformanceWatcherFactory() override {}
253
254 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42255 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41256 const Protocol protocol,
257 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51258 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38259 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51260 }
261 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42262 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23263 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
264 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40265 }
266
tbansalc8a94ea2015-11-02 23:58:51267 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40268
tbansalc8a94ea2015-11-02 23:58:51269 bool rtt_notification_received() const { return rtt_notification_received_; }
270
tbansal180587c2017-02-16 15:13:23271 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
272 should_notify_updated_rtt_ = should_notify_updated_rtt;
273 }
274
tbansalc8a94ea2015-11-02 23:58:51275 private:
tbansal0f56a39a2016-04-07 22:03:38276 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23277 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51278 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38279
280 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51281};
282
Ryan Hamilton8d9ee76e2018-05-29 23:52:52283class QuicNetworkTransactionTest
284 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57285 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05286 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00287 protected:
[email protected]1c04f9522013-02-21 20:32:43288 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57289 : version_(GetParam().version),
290 client_headers_include_h2_stream_dependency_(
291 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56292 supported_versions_(quic::test::SupportedVersions(version_)),
Victor Vasiliev7752898d2019-11-14 21:30:22293 client_maker_(version_,
294 quic::QuicUtils::CreateRandomConnectionId(
295 context_.random_generator()),
296 context_.clock(),
297 kDefaultServerHostName,
298 quic::Perspective::IS_CLIENT,
299 client_headers_include_h2_stream_dependency_),
300 server_maker_(version_,
301 quic::QuicUtils::CreateRandomConnectionId(
302 context_.random_generator()),
303 context_.clock(),
304 kDefaultServerHostName,
305 quic::Perspective::IS_SERVER,
306 false),
307 quic_task_runner_(new TestTaskRunner(context_.mock_clock())),
rtenneti052774e2015-11-24 21:00:12308 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43309 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59310 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11311 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49312 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56313 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19314 request_.method = "GET";
rchf114d982015-10-21 01:34:56315 std::string url("https://");
bncb07c05532015-05-14 19:07:20316 url.append(kDefaultServerHostName);
317 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19318 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10319 request_.traffic_annotation =
320 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22321 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56322
323 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29324 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56325 verify_details_.cert_verify_result.verified_cert = cert;
326 verify_details_.cert_verify_result.is_issued_by_known_root = true;
327 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43328 }
[email protected]61a527782013-02-21 03:58:00329
dcheng67be2b1f2014-10-27 21:47:29330 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00331 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55332 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00333 }
334
dcheng67be2b1f2014-10-27 21:47:29335 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00336 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
337 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55338 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00339 PlatformTest::TearDown();
340 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55341 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40342 session_.reset();
[email protected]61a527782013-02-21 03:58:00343 }
344
Ryan Hamilton8d9ee76e2018-05-29 23:52:52345 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23346 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03347 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52348 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30349 }
350
Ryan Hamilton8d9ee76e2018-05-29 23:52:52351 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23352 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03353 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52354 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58355 }
356
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23358 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52359 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20360 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58361 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20362 }
363
Ryan Hamilton8d9ee76e2018-05-29 23:52:52364 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23365 uint64_t packet_number,
366 uint64_t largest_received,
367 uint64_t smallest_received,
368 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37369 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49370 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37371 }
372
Ryan Hamilton8d9ee76e2018-05-29 23:52:52373 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23374 uint64_t packet_number,
375 uint64_t largest_received,
376 uint64_t smallest_received,
377 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23379 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49380 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23381 ack_delay_time);
382 }
383
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23385 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52386 quic::QuicStreamId stream_id,
387 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23388 uint64_t largest_received,
389 uint64_t smallest_received,
390 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58391 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49392 num, false, stream_id, error_code, largest_received, smallest_received,
393 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20394 }
395
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23397 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52398 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41399 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang46a273ec302018-01-23 17:59:56400 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18401 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56402 }
403
Ryan Hamilton8d9ee76e2018-05-29 23:52:52404 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23405 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
406 uint64_t largest_received,
407 uint64_t smallest_received,
408 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58409 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49410 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20411 }
[email protected]61a527782013-02-21 03:58:00412
Ryan Hamilton8d9ee76e2018-05-29 23:52:52413 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58414 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23415 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52416 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23417 uint64_t largest_received,
418 uint64_t smallest_received,
419 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29421 const std::string& quic_error_details,
422 uint64_t frame_type) {
alyssar2adf3ac2016-05-03 17:12:58423 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12424 num, false, delta_time_largest_observed, largest_received,
Renjie Tangff0d6372019-08-30 22:03:29425 smallest_received, least_unacked, quic_error, quic_error_details,
426 frame_type);
zhongyica364fbb2015-12-12 03:39:12427 }
428
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23430 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12431 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 quic::QuicStreamId stream_id,
433 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58434 return server_maker_.MakeRstPacket(num, include_version, stream_id,
435 error_code);
zhongyica364fbb2015-12-12 03:39:12436 }
437
Ryan Hamilton8d9ee76e2018-05-29 23:52:52438 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02439 uint64_t packet_number) {
440 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37441 }
442
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23444 uint64_t packet_number,
445 uint64_t largest_received,
446 uint64_t smallest_received,
447 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37448 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49449 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37450 }
451
Ryan Hamilton8d9ee76e2018-05-29 23:52:52452 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23453 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57454 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52455 quic::QuicStreamId id,
456 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02457 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57458 return client_maker_.MakePriorityPacket(
459 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02460 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23461 }
462
Ryan Hamilton8d9ee76e2018-05-29 23:52:52463 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25464 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23465 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23466 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23467 uint64_t largest_received,
468 uint64_t smallest_received,
469 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25470 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02471 priority_frames) {
Yixin Wange7ecc472018-03-06 19:00:25472 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23473 packet_number, should_include_version, largest_received,
Ryan Hamilton0d65a8c2019-06-07 00:46:02474 smallest_received, least_unacked, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57475 }
476
zhongyi32569c62016-01-08 02:54:30477 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13478 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
479 const std::string& scheme,
480 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58481 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30482 }
483
484 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13485 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
486 const std::string& scheme,
487 const std::string& path,
488 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50489 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00490 }
491
Ryan Hamilton0239aac2018-05-19 00:03:13492 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56493 return client_maker_.ConnectRequestHeaders(host_port);
494 }
495
Ryan Hamilton0239aac2018-05-19 00:03:13496 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58497 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00498 }
499
zhongyi32569c62016-01-08 02:54:30500 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13501 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
502 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58503 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30504 }
505
Ryan Hamilton8d9ee76e2018-05-29 23:52:52506 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23507 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52508 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05509 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00510 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52511 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17512 return server_maker_.MakeDataPacket(packet_number, stream_id,
513 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00514 }
515
Ryan Hamilton8d9ee76e2018-05-29 23:52:52516 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23517 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52518 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36519 bool should_include_version,
520 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52521 quic::QuicStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17522 return client_maker_.MakeDataPacket(packet_number, stream_id,
523 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36524 }
525
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23527 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56528 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52529 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23530 uint64_t largest_received,
531 uint64_t smallest_received,
532 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56533 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52534 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56535 return client_maker_.MakeAckAndDataPacket(
536 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17537 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56538 }
539
Ryan Hamilton8d9ee76e2018-05-29 23:52:52540 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23541 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52542 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36543 bool should_include_version,
544 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52545 quic::QuicStreamOffset* offset,
546 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36547 return client_maker_.MakeForceHolDataPacket(
548 packet_number, stream_id, should_include_version, fin, offset, data);
549 }
550
Ryan Hamilton8d9ee76e2018-05-29 23:52:52551 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23552 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52553 quic::QuicStreamId stream_id,
554 bool should_include_version,
555 bool fin,
556 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56557 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
558 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02559 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56560 }
561
Ryan Hamilton8d9ee76e2018-05-29 23:52:52562 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23563 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52564 quic::QuicStreamId stream_id,
565 bool should_include_version,
566 bool fin,
567 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02568 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56569 return ConstructClientRequestHeadersPacket(
570 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02571 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30572 }
573
Ryan Hamilton8d9ee76e2018-05-29 23:52:52574 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23575 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52576 quic::QuicStreamId stream_id,
577 bool should_include_version,
578 bool fin,
579 RequestPriority request_priority,
580 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02581 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13582 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56583 ConvertRequestPriorityToQuicPriority(request_priority);
Ryan Hamilton0d65a8c2019-06-07 00:46:02584 return client_maker_.MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56585 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02586 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00587 }
588
Ryan Hamilton8d9ee76e2018-05-29 23:52:52589 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25590 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23591 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52592 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25593 bool should_include_version,
594 bool fin,
595 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13596 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52597 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25598 size_t* spdy_headers_frame_length,
599 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13600 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25601 ConvertRequestPriorityToQuicPriority(request_priority);
602 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
603 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02604 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25605 data_writes);
606 }
607
Ryan Hamilton8d9ee76e2018-05-29 23:52:52608 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23609 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52610 quic::QuicStreamId stream_id,
611 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13612 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13613 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13614 QuicTestPacketMaker* maker) {
615 return maker->MakePushPromisePacket(
616 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02617 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13618 }
619
Ryan Hamilton8d9ee76e2018-05-29 23:52:52620 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23621 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52622 quic::QuicStreamId stream_id,
623 bool should_include_version,
624 bool fin,
625 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02626 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
627 should_include_version, fin,
628 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30629 }
630
Victor Vasiliev076657c2019-03-12 02:46:43631 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56632 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41633 return "";
634 }
Renjief49758b2019-01-11 23:32:41635 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:57636 auto header_length =
637 quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43638 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41639 }
640
Nick Harper23290b82019-05-02 00:02:56641 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41642 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38643 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38644 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05645 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00646
Victor Vasiliev7752898d2019-11-14 21:30:22647 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41648 session_context_.client_socket_factory = &socket_factory_;
649 session_context_.quic_crypto_client_stream_factory =
650 &crypto_client_stream_factory_;
651 session_context_.host_resolver = &host_resolver_;
652 session_context_.cert_verifier = &cert_verifier_;
653 session_context_.transport_security_state = &transport_security_state_;
654 session_context_.cert_transparency_verifier =
655 cert_transparency_verifier_.get();
656 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
657 session_context_.socket_performance_watcher_factory =
658 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59659 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41660 session_context_.ssl_config_service = ssl_config_service_.get();
661 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49662 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41663 session_context_.net_log = net_log_.bound().net_log();
664
665 session_.reset(new HttpNetworkSession(session_params_, session_context_));
Matt Menkeb566c392019-09-11 23:22:43666 session_->quic_stream_factory()
667 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56668 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
669 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00670 }
671
zhongyi86838d52017-06-30 01:19:44672 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21673
David Schinazif832cb82019-11-08 22:25:27674 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
675 const std::string& status_line) {
[email protected]aa9b14d2013-05-10 23:45:19676 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42677 ASSERT_TRUE(response != nullptr);
678 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27679 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19680 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52681 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:08682 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19683 response->connection_info);
684 }
685
David Schinazif832cb82019-11-08 22:25:27686 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
687 CheckWasQuicResponse(trans, "HTTP/1.1 200 OK");
688 }
689
bnc691fda62016-08-12 00:43:16690 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41691 const HttpResponseInfo* response = trans->GetResponseInfo();
692 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37693 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41694 }
695
bnc691fda62016-08-12 00:43:16696 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19697 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42698 ASSERT_TRUE(response != nullptr);
699 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19700 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
701 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52702 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52703 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19704 response->connection_info);
705 }
706
Yixin Wang46a273ec302018-01-23 17:59:56707 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
708 const HttpResponseInfo* response = trans->GetResponseInfo();
709 ASSERT_TRUE(response != nullptr);
710 ASSERT_TRUE(response->headers.get() != nullptr);
711 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
712 EXPECT_TRUE(response->was_fetched_via_spdy);
713 EXPECT_TRUE(response->was_alpn_negotiated);
714 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
715 response->connection_info);
716 }
717
bnc691fda62016-08-12 00:43:16718 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19719 const std::string& expected) {
720 std::string response_data;
bnc691fda62016-08-12 00:43:16721 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19722 EXPECT_EQ(expected, response_data);
723 }
724
bnc691fda62016-08-12 00:43:16725 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19726 TestCompletionCallback callback;
727 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
729 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19730 }
731
732 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16733 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
734 RunTransaction(&trans);
735 CheckWasHttpResponse(&trans);
736 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19737 }
738
tbansalc3308d72016-08-27 10:25:04739 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
740 bool used_proxy,
741 uint16_t port) {
742 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
743 HeadersHandler headers_handler;
744 trans.SetBeforeHeadersSentCallback(
745 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
746 base::Unretained(&headers_handler)));
747 RunTransaction(&trans);
748 CheckWasHttpResponse(&trans);
749 CheckResponsePort(&trans, port);
750 CheckResponseData(&trans, expected);
751 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47752 if (used_proxy) {
753 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
754 } else {
755 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
756 }
tbansalc3308d72016-08-27 10:25:04757 }
David Schinazif832cb82019-11-08 22:25:27758 void SendRequestAndExpectQuicResponse(const std::string& expected,
759 const std::string& status_line) {
760 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
761 status_line);
762 }
tbansalc3308d72016-08-27 10:25:04763
[email protected]aa9b14d2013-05-10 23:45:19764 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56765 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12766 }
767
bnc62a44f022015-04-02 15:59:41768 void SendRequestAndExpectQuicResponseFromProxyOnPort(
769 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46770 uint16_t port) {
bnc62a44f022015-04-02 15:59:41771 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19772 }
773
774 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05775 MockCryptoClientStream::HandshakeMode handshake_mode,
776 const NetworkIsolationKey& network_isolation_key =
777 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19778 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46779 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21780 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12781 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49782 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05783 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07784 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19785 }
786
rchbe69cb902016-02-11 01:10:48787 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27788 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48789 const HostPortPair& alternative) {
790 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46791 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21792 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48793 alternative.port());
794 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49795 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07796 server, NetworkIsolationKey(), alternative_service, expiration,
797 supported_versions_);
rchbe69cb902016-02-11 01:10:48798 }
799
Matt Menkeb32ba5122019-09-10 19:17:05800 void ExpectBrokenAlternateProtocolMapping(
801 const NetworkIsolationKey& network_isolation_key =
802 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46803 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34804 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49805 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05806 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34807 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49808 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05809 alternative_service_info_vector[0].alternative_service(),
810 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19811 }
812
Matt Menkeb32ba5122019-09-10 19:17:05813 void ExpectQuicAlternateProtocolMapping(
814 const NetworkIsolationKey& network_isolation_key =
815 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46816 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34817 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49818 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05819 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34820 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54821 EXPECT_EQ(
822 kProtoQUIC,
823 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49824 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05825 alternative_service_info_vector[0].alternative_service(),
826 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33827 }
828
[email protected]aa9b14d2013-05-10 23:45:19829 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42830 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30831 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30832 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30833 hanging_data->set_connect_data(hanging_connect);
834 hanging_data_.push_back(std::move(hanging_data));
835 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56836 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19837 }
838
Zhongyi Shia6b68d112018-09-24 07:49:03839 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38840 context_.params()->migrate_sessions_on_network_change_v2 = true;
841 context_.params()->migrate_sessions_early_v2 = true;
842 context_.params()->retry_on_alternate_network_before_handshake = true;
Zhongyi Shia6b68d112018-09-24 07:49:03843 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
844 MockNetworkChangeNotifier* mock_ncn =
845 scoped_mock_change_notifier_->mock_network_change_notifier();
846 mock_ncn->ForceNetworkHandlesSupported();
847 mock_ncn->SetConnectedNetworksList(
848 {kDefaultNetworkForTests, kNewNetworkForTests});
849 }
850
tbansalc3308d72016-08-27 10:25:04851 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
852 // alternative proxy. Verifies that if the alternative proxy job returns
853 // |error_code|, the request is fetched successfully by the main job.
854 void TestAlternativeProxy(int error_code) {
855 // Use a non-cryptographic scheme for the request URL since this request
856 // will be fetched via proxy with QUIC as the alternative service.
857 request_.url = GURL("http://example.org/");
858 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27859 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04860 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27861 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04862 };
863
Ryan Sleevib8d7ea02018-05-07 20:01:01864 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04865 socket_factory_.AddSocketDataProvider(&quic_data);
866
867 // Main job succeeds and the alternative job fails.
868 // Add data for two requests that will be read by the main job.
869 MockRead http_reads_1[] = {
870 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
871 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
872 MockRead(ASYNC, OK)};
873
874 MockRead http_reads_2[] = {
875 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
876 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
877 MockRead(ASYNC, OK)};
878
Ryan Sleevib8d7ea02018-05-07 20:01:01879 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
880 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04881 socket_factory_.AddSocketDataProvider(&http_data_1);
882 socket_factory_.AddSocketDataProvider(&http_data_2);
883 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
884 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
885
886 TestProxyDelegate test_proxy_delegate;
887 // Proxy URL is different from the request URL.
888 test_proxy_delegate.set_alternative_proxy_server(
889 ProxyServer::FromPacString("QUIC myproxy.org:443"));
890
Lily Houghton8c2f97d2018-01-22 05:06:59891 proxy_resolution_service_ =
892 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49893 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52894 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04895
896 CreateSession();
897 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
898
899 // The first request should be fetched via the HTTPS proxy.
900 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
901
Reilly Grant89a7e512018-01-20 01:57:16902 // Since the main job succeeded only the alternative proxy server should be
903 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59904 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16905 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04906
907 // Verify that the second request completes successfully, and the
908 // alternative proxy server job is not started.
909 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
910 }
911
Matt Menkeb32ba5122019-09-10 19:17:05912 // Adds a new socket data provider for an HTTP request, and runs a request,
913 // expecting it to be used.
914 void AddHttpDataAndRunRequest() {
915 MockWrite http_writes[] = {
916 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
917 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
918 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
919
920 MockRead http_reads[] = {
921 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
922 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
923 MockRead(SYNCHRONOUS, 5, "http used"),
924 // Connection closed.
925 MockRead(SYNCHRONOUS, OK, 6)};
926 SequencedSocketData http_data(http_reads, http_writes);
927 socket_factory_.AddSocketDataProvider(&http_data);
928 SSLSocketDataProvider ssl_data(ASYNC, OK);
929 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
930 SendRequestAndExpectHttpResponse("http used");
931 EXPECT_TRUE(http_data.AllWriteDataConsumed());
932 EXPECT_TRUE(http_data.AllReadDataConsumed());
933 }
934
935 // Adds a new socket data provider for a QUIC request, and runs a request,
936 // expecting it to be used. The new QUIC session is not closed.
937 void AddQuicDataAndRunRequest() {
938 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22939 version_,
940 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
941 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05942 client_headers_include_h2_stream_dependency_);
943 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22944 version_,
945 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
946 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
947 false);
Matt Menkeb32ba5122019-09-10 19:17:05948 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56949 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05950 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25951 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56952 quic_data.AddWrite(
953 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
954 }
Matt Menkeb32ba5122019-09-10 19:17:05955 quic_data.AddWrite(
956 SYNCHRONOUS,
957 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56958 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
959 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05960 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
961 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
962 quic_data.AddRead(
963 ASYNC, server_maker.MakeResponseHeadersPacket(
964 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
965 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
966 std::string header = ConstructDataHeader(9);
967 quic_data.AddRead(
968 ASYNC, server_maker.MakeDataPacket(
969 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
970 true, header + "quic used"));
971 // Don't care about the final ack.
972 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
973 // No more data to read.
974 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
975 quic_data.AddSocketDataToFactory(&socket_factory_);
976 SendRequestAndExpectQuicResponse("quic used");
977
978 EXPECT_TRUE(quic_data.AllReadDataConsumed());
979 }
980
Fan Yang32c5a112018-12-10 20:06:33981 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56982 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
983 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36984 }
985
Fan Yang32c5a112018-12-10 20:06:33986 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56987 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
988 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36989 }
990
Bence Béky230ac612017-08-30 19:17:08991 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49992 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08993 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49994 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08995 }
996
Nick Harper23290b82019-05-02 00:02:56997 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05998 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56999 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011000 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221001 MockQuicContext context_;
alyssar2adf3ac2016-05-03 17:12:581002 QuicTestPacketMaker client_maker_;
1003 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091004 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421005 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001006 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561007 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051008 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431009 MockHostResolver host_resolver_;
1010 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111011 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421012 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231013 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381014 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071015 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:591016 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421017 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491018 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411019 HttpNetworkSession::Params session_params_;
1020 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191021 HttpRequestInfo request_;
Matt Muellerd9342e3a2019-11-26 01:41:141022 RecordingBoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421023 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561024 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031025 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121026
1027 private:
1028 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1029 const std::string& expected,
bnc62a44f022015-04-02 15:59:411030 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271031 uint16_t port,
1032 const std::string& status_line) {
bnc691fda62016-08-12 00:43:161033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091034 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161035 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091036 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1037 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161038 RunTransaction(&trans);
David Schinazif832cb82019-11-08 22:25:271039 CheckWasQuicResponse(&trans, status_line);
bnc691fda62016-08-12 00:43:161040 CheckResponsePort(&trans, port);
1041 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091042 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471043 if (used_proxy) {
1044 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1045 } else {
1046 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1047 }
tbansal7cec3812015-02-05 21:25:121048 }
David Schinazif832cb82019-11-08 22:25:271049
1050 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1051 const std::string& expected,
1052 bool used_proxy,
1053 uint16_t port) {
1054 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1055 "HTTP/1.1 200 OK");
1056 }
[email protected]61a527782013-02-21 03:58:001057};
1058
David Schinazi09e9a6012019-10-03 17:37:571059INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1060 QuicNetworkTransactionTest,
1061 ::testing::ValuesIn(GetTestParams()),
1062 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201063
Shivani Sharma8ae506c2019-07-21 21:08:271064// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1065// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1066
Ryan Hamiltona64a5bcf2017-11-30 07:35:281067TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381068 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281069 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381070 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281071 HostPortPair::FromString("mail.example.org:443"));
1072 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271073 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281074
Ryan Hamiltonabad59e2019-06-06 04:02:591075 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251076 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231077 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281078 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1079 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1080 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1081
1082 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1083
1084 CreateSession();
1085
1086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1087 TestCompletionCallback callback;
1088 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1090 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1091
1092 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1093 -ERR_INTERNET_DISCONNECTED, 1);
1094 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1095 -ERR_INTERNET_DISCONNECTED, 1);
1096}
1097
1098TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381099 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281100 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381101 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281102 HostPortPair::FromString("mail.example.org:443"));
1103 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271104 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281105
Ryan Hamiltonabad59e2019-06-06 04:02:591106 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251107 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231108 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281109 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1110 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1111 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1112
1113 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1114
1115 CreateSession();
1116
1117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1118 TestCompletionCallback callback;
1119 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1121 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1122
1123 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1124 -ERR_INTERNET_DISCONNECTED, 1);
1125 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1126 -ERR_INTERNET_DISCONNECTED, 1);
1127}
1128
tbansal180587c2017-02-16 15:13:231129TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381130 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231131 HostPortPair::FromString("mail.example.org:443"));
1132
Ryan Hamiltonabad59e2019-06-06 04:02:591133 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231134 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251135 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231136 mock_quic_data.AddWrite(SYNCHRONOUS,
1137 ConstructInitialSettingsPacket(packet_num++));
1138 }
rch5cb522462017-04-25 20:18:361139 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231140 SYNCHRONOUS,
1141 ConstructClientRequestHeadersPacket(
1142 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1143 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431144 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331145 ASYNC, ConstructServerResponseHeadersPacket(
1146 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1147 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431148 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331149 mock_quic_data.AddRead(
1150 ASYNC, ConstructServerDataPacket(
1151 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171152 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231153 mock_quic_data.AddWrite(SYNCHRONOUS,
1154 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231155 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1156
1157 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1158
1159 CreateSession();
1160 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1161
1162 EXPECT_FALSE(
1163 test_socket_performance_watcher_factory_.rtt_notification_received());
1164 SendRequestAndExpectQuicResponse("hello!");
1165 EXPECT_TRUE(
1166 test_socket_performance_watcher_factory_.rtt_notification_received());
1167}
1168
1169TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381170 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231171 HostPortPair::FromString("mail.example.org:443"));
1172
Ryan Hamiltonabad59e2019-06-06 04:02:591173 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231174 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251175 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231176 mock_quic_data.AddWrite(SYNCHRONOUS,
1177 ConstructInitialSettingsPacket(packet_num++));
1178 }
rch5cb522462017-04-25 20:18:361179 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231180 SYNCHRONOUS,
1181 ConstructClientRequestHeadersPacket(
1182 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1183 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431184 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331185 ASYNC, ConstructServerResponseHeadersPacket(
1186 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1187 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431188 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331189 mock_quic_data.AddRead(
1190 ASYNC, ConstructServerDataPacket(
1191 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171192 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231193 mock_quic_data.AddWrite(SYNCHRONOUS,
1194 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231195 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1196
1197 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1198
1199 CreateSession();
1200 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1201
1202 EXPECT_FALSE(
1203 test_socket_performance_watcher_factory_.rtt_notification_received());
1204 SendRequestAndExpectQuicResponse("hello!");
1205 EXPECT_FALSE(
1206 test_socket_performance_watcher_factory_.rtt_notification_received());
1207}
1208
[email protected]1e960032013-12-20 19:00:201209TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381210 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571211 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471212
Ryan Hamiltonabad59e2019-06-06 04:02:591213 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231214 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251215 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231216 mock_quic_data.AddWrite(SYNCHRONOUS,
1217 ConstructInitialSettingsPacket(packet_num++));
1218 }
rch5cb522462017-04-25 20:18:361219 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231220 SYNCHRONOUS,
1221 ConstructClientRequestHeadersPacket(
1222 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1223 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431224 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331225 ASYNC, ConstructServerResponseHeadersPacket(
1226 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1227 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431228 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331229 mock_quic_data.AddRead(
1230 ASYNC, ConstructServerDataPacket(
1231 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171232 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231233 mock_quic_data.AddWrite(SYNCHRONOUS,
1234 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591235 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471236
rcha5399e02015-04-21 19:32:041237 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471238
[email protected]4dca587c2013-03-07 16:54:471239 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471240
[email protected]aa9b14d2013-05-10 23:45:191241 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471242
[email protected]98b20ce2013-05-10 05:55:261243 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541244 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261245 EXPECT_LT(0u, entries.size());
1246
1247 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291248 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001249 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1250 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261251 EXPECT_LT(0, pos);
1252
rchfd527212015-08-25 00:41:261253 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291254 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261255 entries, 0,
mikecirone8b85c432016-09-08 19:11:001256 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1257 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261258 EXPECT_LT(0, pos);
1259
Eric Roman79cc7552019-07-19 02:17:541260 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261261
rchfd527212015-08-25 00:41:261262 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1263 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001264 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1265 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261266 EXPECT_LT(0, pos);
1267
[email protected]98b20ce2013-05-10 05:55:261268 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291269 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001270 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1271 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261272 EXPECT_LT(0, pos);
1273
Eric Roman79cc7552019-07-19 02:17:541274 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251275 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451276 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1277 static_cast<quic::QuicStreamId>(log_stream_id));
1278 } else {
1279 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1280 static_cast<quic::QuicStreamId>(log_stream_id));
1281 }
[email protected]4dca587c2013-03-07 16:54:471282}
1283
rchbd089ab2017-05-26 23:05:041284TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381285 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041286 HostPortPair::FromString("mail.example.org:443"));
1287
Ryan Hamiltonabad59e2019-06-06 04:02:591288 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231289 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251290 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231291 mock_quic_data.AddWrite(SYNCHRONOUS,
1292 ConstructInitialSettingsPacket(packet_num++));
1293 }
rchbd089ab2017-05-26 23:05:041294 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231295 SYNCHRONOUS,
1296 ConstructClientRequestHeadersPacket(
1297 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1298 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131299 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041300 response_headers["key1"] = std::string(30000, 'A');
1301 response_headers["key2"] = std::string(30000, 'A');
1302 response_headers["key3"] = std::string(30000, 'A');
1303 response_headers["key4"] = std::string(30000, 'A');
1304 response_headers["key5"] = std::string(30000, 'A');
1305 response_headers["key6"] = std::string(30000, 'A');
1306 response_headers["key7"] = std::string(30000, 'A');
1307 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451308 quic::QuicStreamId stream_id;
1309 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251310 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451311 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281312 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451313 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451314 } else {
1315 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1316 spdy::SpdyHeadersIR headers_frame(
1317 GetNthClientInitiatedBidirectionalStreamId(0),
1318 std::move(response_headers));
1319 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1320 spdy::SpdySerializedFrame spdy_frame =
1321 response_framer.SerializeFrame(headers_frame);
1322 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1323 }
rchbd089ab2017-05-26 23:05:041324
Fan Yangac867502019-01-28 21:10:231325 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041326 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451327 for (size_t offset = 0; offset < response_data.length();
1328 offset += chunk_size) {
1329 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431330 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451331 ASYNC, ConstructServerDataPacket(
1332 packet_number++, stream_id, false, false,
1333 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041334 }
1335
Victor Vasiliev076657c2019-03-12 02:46:431336 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041337 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331338 ASYNC, ConstructServerDataPacket(
1339 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171340 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041341 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431342 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231343 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1344 mock_quic_data.AddWrite(
1345 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041346
1347 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1348
1349 CreateSession();
1350
1351 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421352 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1353 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041354}
1355
1356TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381357 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1358 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041359 HostPortPair::FromString("mail.example.org:443"));
1360
Ryan Hamiltonabad59e2019-06-06 04:02:591361 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231362 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251363 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231364 mock_quic_data.AddWrite(SYNCHRONOUS,
1365 ConstructInitialSettingsPacket(packet_num++));
1366 }
rchbd089ab2017-05-26 23:05:041367 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231368 SYNCHRONOUS,
1369 ConstructClientRequestHeadersPacket(
1370 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1371 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451372
Ryan Hamilton0239aac2018-05-19 00:03:131373 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041374 response_headers["key1"] = std::string(30000, 'A');
1375 response_headers["key2"] = std::string(30000, 'A');
1376 response_headers["key3"] = std::string(30000, 'A');
1377 response_headers["key4"] = std::string(30000, 'A');
1378 response_headers["key5"] = std::string(30000, 'A');
1379 response_headers["key6"] = std::string(30000, 'A');
1380 response_headers["key7"] = std::string(30000, 'A');
1381 response_headers["key8"] = std::string(30000, 'A');
1382 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451383
1384 quic::QuicStreamId stream_id;
1385 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251386 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451387 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281388 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451389 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451390 } else {
1391 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1392 spdy::SpdyHeadersIR headers_frame(
1393 GetNthClientInitiatedBidirectionalStreamId(0),
1394 std::move(response_headers));
1395 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1396 spdy::SpdySerializedFrame spdy_frame =
1397 response_framer.SerializeFrame(headers_frame);
1398 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1399 }
rchbd089ab2017-05-26 23:05:041400
Fan Yangac867502019-01-28 21:10:231401 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041402 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451403 for (size_t offset = 0; offset < response_data.length();
1404 offset += chunk_size) {
1405 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431406 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451407 ASYNC, ConstructServerDataPacket(
1408 packet_number++, stream_id, false, false,
1409 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041410 }
1411
Victor Vasiliev076657c2019-03-12 02:46:431412 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411413
rchbd089ab2017-05-26 23:05:041414 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331415 ASYNC, ConstructServerDataPacket(
1416 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171417 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041418 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231419 mock_quic_data.AddWrite(ASYNC,
1420 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431421 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331422 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231423 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331424 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041425
1426 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1427
1428 CreateSession();
1429
1430 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1431 TestCompletionCallback callback;
1432 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1433 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1434 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1435}
1436
rcha2bd44b2016-07-02 00:42:551437TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381438 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551439
Ryan Hamilton9835e662018-08-02 05:36:271440 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551441
Ryan Hamiltonabad59e2019-06-06 04:02:591442 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231443 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251444 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231445 mock_quic_data.AddWrite(SYNCHRONOUS,
1446 ConstructInitialSettingsPacket(packet_num++));
1447 }
rch5cb522462017-04-25 20:18:361448 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231449 SYNCHRONOUS,
1450 ConstructClientRequestHeadersPacket(
1451 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1452 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431453 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331454 ASYNC, ConstructServerResponseHeadersPacket(
1455 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1456 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431457 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331458 mock_quic_data.AddRead(
1459 ASYNC, ConstructServerDataPacket(
1460 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171461 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231462 mock_quic_data.AddWrite(SYNCHRONOUS,
1463 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551464 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1465
1466 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1467
1468 CreateSession();
1469
1470 SendRequestAndExpectQuicResponse("hello!");
1471 EXPECT_TRUE(
1472 test_socket_performance_watcher_factory_.rtt_notification_received());
1473}
1474
David Schinazif832cb82019-11-08 22:25:271475// Regression test for https://crbug.com/695225
1476TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381477 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271478
1479 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1480
1481 MockQuicData mock_quic_data(version_);
1482 int packet_num = 1;
1483 if (VersionUsesHttp3(version_.transport_version)) {
1484 mock_quic_data.AddWrite(SYNCHRONOUS,
1485 ConstructInitialSettingsPacket(packet_num++));
1486 }
1487 mock_quic_data.AddWrite(
1488 SYNCHRONOUS,
1489 ConstructClientRequestHeadersPacket(
1490 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1491 true, GetRequestHeaders("GET", "https", "/")));
1492 mock_quic_data.AddRead(
1493 ASYNC, ConstructServerResponseHeadersPacket(
1494 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1495 GetResponseHeaders("408 Request Timeout")));
1496 std::string header = ConstructDataHeader(6);
1497 mock_quic_data.AddRead(
1498 ASYNC, ConstructServerDataPacket(
1499 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1500 header + "hello!"));
1501 mock_quic_data.AddWrite(SYNCHRONOUS,
1502 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1503 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1504
1505 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1506
1507 CreateSession();
1508
1509 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1510}
1511
[email protected]cf3e3cd62014-02-05 16:16:161512TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411513 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591514 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491515 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161516
Ryan Hamiltonabad59e2019-06-06 04:02:591517 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231518 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251519 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231520 mock_quic_data.AddWrite(SYNCHRONOUS,
1521 ConstructInitialSettingsPacket(packet_num++));
1522 }
rch5cb522462017-04-25 20:18:361523 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231524 SYNCHRONOUS,
1525 ConstructClientRequestHeadersPacket(
1526 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1527 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431528 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331529 ASYNC, ConstructServerResponseHeadersPacket(
1530 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1531 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431532 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331533 mock_quic_data.AddRead(
1534 ASYNC, ConstructServerDataPacket(
1535 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171536 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231537 mock_quic_data.AddWrite(SYNCHRONOUS,
1538 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501539 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591540 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161541
rcha5399e02015-04-21 19:32:041542 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161543
tbansal0f56a39a2016-04-07 22:03:381544 EXPECT_FALSE(
1545 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161546 // There is no need to set up an alternate protocol job, because
1547 // no attempt will be made to speak to the proxy over TCP.
1548
rch9ae5b3b2016-02-11 00:36:291549 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161550 CreateSession();
1551
bnc62a44f022015-04-02 15:59:411552 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381553 EXPECT_TRUE(
1554 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161555}
1556
bnc313ba9c2015-06-11 15:42:311557// Regression test for https://crbug.com/492458. Test that for an HTTP
1558// connection through a QUIC proxy, the certificate exhibited by the proxy is
1559// checked against the proxy hostname, not the origin hostname.
1560TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291561 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311562 const std::string proxy_host = "www.example.org";
1563
mmenke6ddfbea2017-05-31 21:48:411564 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591565 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491566 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311567
alyssar2adf3ac2016-05-03 17:12:581568 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591569 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231570 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251571 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231572 mock_quic_data.AddWrite(SYNCHRONOUS,
1573 ConstructInitialSettingsPacket(packet_num++));
1574 }
rch5cb522462017-04-25 20:18:361575 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231576 SYNCHRONOUS,
1577 ConstructClientRequestHeadersPacket(
1578 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1579 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431580 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331581 ASYNC, ConstructServerResponseHeadersPacket(
1582 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1583 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431584 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331585 mock_quic_data.AddRead(
1586 ASYNC, ConstructServerDataPacket(
1587 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171588 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231589 mock_quic_data.AddWrite(SYNCHRONOUS,
1590 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501591 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591592 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311593 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1594
1595 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291596 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311597 ASSERT_TRUE(cert.get());
1598 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241599 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1600 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311601 ProofVerifyDetailsChromium verify_details;
1602 verify_details.cert_verify_result.verified_cert = cert;
1603 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561604 ProofVerifyDetailsChromium verify_details2;
1605 verify_details2.cert_verify_result.verified_cert = cert;
1606 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311607
1608 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091609 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321610 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271611 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311612 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1613}
1614
rchbe69cb902016-02-11 01:10:481615TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381616 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481617 HostPortPair origin("www.example.org", 443);
1618 HostPortPair alternative("mail.example.org", 443);
1619
1620 base::FilePath certs_dir = GetTestCertsDirectory();
1621 scoped_refptr<X509Certificate> cert(
1622 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1623 ASSERT_TRUE(cert.get());
1624 // TODO(rch): the connection should be "to" the origin, so if the cert is
1625 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241626 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1627 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481628 ProofVerifyDetailsChromium verify_details;
1629 verify_details.cert_verify_result.verified_cert = cert;
1630 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1631
alyssar2adf3ac2016-05-03 17:12:581632 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591633 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021634
Renjie Tangaadb84b2019-08-31 01:00:231635 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251636 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231637 mock_quic_data.AddWrite(SYNCHRONOUS,
1638 ConstructInitialSettingsPacket(packet_num++));
1639 }
rch5cb522462017-04-25 20:18:361640 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231641 SYNCHRONOUS,
1642 ConstructClientRequestHeadersPacket(
1643 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1644 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431645 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331646 ASYNC, ConstructServerResponseHeadersPacket(
1647 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1648 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431649 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331650 mock_quic_data.AddRead(
1651 ASYNC, ConstructServerDataPacket(
1652 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171653 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231654 mock_quic_data.AddWrite(SYNCHRONOUS,
1655 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481656 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1657 mock_quic_data.AddRead(ASYNC, 0);
1658 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1659
1660 request_.url = GURL("https://" + origin.host());
1661 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271662 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091663 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321664 CreateSession();
rchbe69cb902016-02-11 01:10:481665
1666 SendRequestAndExpectQuicResponse("hello!");
1667}
1668
zhongyief3f4ce52017-07-05 23:53:281669TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561670 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281671 // Add support for another QUIC version besides |version_|. Also find a
1672 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561673 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281674 if (version == version_)
1675 continue;
1676 if (supported_versions_.size() != 2) {
1677 supported_versions_.push_back(version);
1678 continue;
1679 }
1680 unsupported_version = version;
1681 break;
1682 }
Nick Harper23290b82019-05-02 00:02:561683 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281684
1685 // Set up alternative service to use QUIC with a version that is not
1686 // supported.
1687 url::SchemeHostPort server(request_.url);
1688 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1689 443);
1690 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491691 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071692 server, NetworkIsolationKey(), alternative_service, expiration,
1693 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281694
1695 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491696 http_server_properties_->GetAlternativeServiceInfos(
1697 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281698 EXPECT_EQ(1u, alt_svc_info_vector.size());
1699 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1700 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1701 EXPECT_EQ(unsupported_version,
1702 alt_svc_info_vector[0].advertised_versions()[0]);
1703
1704 // First request should still be sent via TCP as the QUIC version advertised
1705 // in the stored AlternativeService is not supported by the client. However,
1706 // the response from the server will advertise new Alt-Svc with supported
1707 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061708 quic::ParsedQuicVersionVector versions;
1709 for (quic::QuicTransportVersion version :
1710 quic::AllSupportedTransportVersions()) {
1711 versions.push_back(
1712 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1713 }
zhongyief3f4ce52017-07-05 23:53:281714 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061715 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281716 std::string altsvc_header =
1717 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1718 advertised_versions_list_str.c_str());
1719 MockRead http_reads[] = {
1720 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1721 MockRead("hello world"),
1722 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1723 MockRead(ASYNC, OK)};
1724
Ryan Sleevib8d7ea02018-05-07 20:01:011725 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281726 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081727 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281728 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1729
1730 // Second request should be sent via QUIC as a new list of verions supported
1731 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591732 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231733 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251734 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231735 mock_quic_data.AddWrite(SYNCHRONOUS,
1736 ConstructInitialSettingsPacket(packet_num++));
1737 }
zhongyief3f4ce52017-07-05 23:53:281738 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231739 SYNCHRONOUS,
1740 ConstructClientRequestHeadersPacket(
1741 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1742 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431743 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331744 ASYNC, ConstructServerResponseHeadersPacket(
1745 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1746 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431747 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331748 mock_quic_data.AddRead(
1749 ASYNC, ConstructServerDataPacket(
1750 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171751 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231752 mock_quic_data.AddWrite(SYNCHRONOUS,
1753 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281754 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1755 mock_quic_data.AddRead(ASYNC, 0); // EOF
1756
1757 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1758
1759 AddHangingNonAlternateProtocolSocketData();
1760
1761 CreateSession(supported_versions_);
1762
1763 SendRequestAndExpectHttpResponse("hello world");
1764 SendRequestAndExpectQuicResponse("hello!");
1765
1766 // Check alternative service list is updated with new versions.
1767 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491768 session_->http_server_properties()->GetAlternativeServiceInfos(
1769 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281770 EXPECT_EQ(1u, alt_svc_info_vector.size());
1771 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1772 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1773 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561774 std::sort(
1775 supported_versions_.begin(), supported_versions_.end(),
1776 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1777 return a.transport_version < b.transport_version;
1778 });
zhongyief3f4ce52017-07-05 23:53:281779 EXPECT_EQ(supported_versions_[0],
1780 alt_svc_info_vector[0].advertised_versions()[0]);
1781 EXPECT_EQ(supported_versions_[1],
1782 alt_svc_info_vector[0].advertised_versions()[1]);
1783}
1784
bncaccd4962017-04-06 21:00:261785// Regression test for https://crbug.com/546991.
1786// The server might not be able to serve a request on an alternative connection,
1787// and might send a 421 Misdirected Request response status to indicate this.
1788// HttpNetworkTransaction should reset the request and retry without using
1789// alternative services.
1790TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1791 // Set up alternative service to use QUIC.
1792 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1793 // that overrides |enable_alternative_services|.
1794 url::SchemeHostPort server(request_.url);
1795 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1796 443);
1797 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491798 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071799 server, NetworkIsolationKey(), alternative_service, expiration,
1800 supported_versions_);
bncaccd4962017-04-06 21:00:261801
davidbena4449722017-05-05 23:30:531802 // First try: The alternative job uses QUIC and reports an HTTP 421
1803 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1804 // paused at Connect(), so it will never exit the socket pool. This ensures
1805 // that the alternate job always wins the race and keeps whether the
1806 // |http_data| exits the socket pool before the main job is aborted
1807 // deterministic. The first main job gets aborted without the socket pool ever
1808 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591809 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231810 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251811 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231812 mock_quic_data.AddWrite(SYNCHRONOUS,
1813 ConstructInitialSettingsPacket(packet_num++));
1814 }
rch5cb522462017-04-25 20:18:361815 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231816 SYNCHRONOUS,
1817 ConstructClientRequestHeadersPacket(
1818 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1819 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331820 mock_quic_data.AddRead(
1821 ASYNC, ConstructServerResponseHeadersPacket(
1822 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021823 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261824 mock_quic_data.AddRead(ASYNC, OK);
1825 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1826
davidbena4449722017-05-05 23:30:531827 // Second try: The main job uses TCP, and there is no alternate job. Once the
1828 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1829 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261830 // Note that if there was an alternative QUIC Job created for the second try,
1831 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1832 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531833 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1834 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1835 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1836 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1837 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1838 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011839 reads, writes);
bncaccd4962017-04-06 21:00:261840 socket_factory_.AddSocketDataProvider(&http_data);
1841 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1842
bncaccd4962017-04-06 21:00:261843 CreateSession();
1844 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531845
1846 // Run until |mock_quic_data| has failed and |http_data| has paused.
1847 TestCompletionCallback callback;
1848 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1849 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1850 base::RunLoop().RunUntilIdle();
1851
1852 // |mock_quic_data| must have run to completion.
1853 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1854 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1855
1856 // Now that the QUIC data has been consumed, unblock |http_data|.
1857 http_data.socket()->OnConnectComplete(MockConnect());
1858
1859 // The retry logic must hide the 421 status. The transaction succeeds on
1860 // |http_data|.
1861 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261862 CheckWasHttpResponse(&trans);
1863 CheckResponsePort(&trans, 443);
1864 CheckResponseData(&trans, "hello!");
1865}
1866
[email protected]1e960032013-12-20 19:00:201867TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381868 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571869 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301870
Ryan Hamiltonabad59e2019-06-06 04:02:591871 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251872 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231873 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401874 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021875 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591876 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251877 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231878 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301879 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401880 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431881 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401882
1883 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1884 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301885
1886 CreateSession();
1887
tbansal0f56a39a2016-04-07 22:03:381888 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401889 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401891 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161892 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1894 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381895 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531896
1897 NetErrorDetails details;
1898 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521899 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401900 }
[email protected]cebe3282013-05-22 23:49:301901}
1902
tbansalc8a94ea2015-11-02 23:58:511903TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1904 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381905 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571906 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511907
1908 MockRead http_reads[] = {
1909 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1910 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1911 MockRead(ASYNC, OK)};
1912
Ryan Sleevib8d7ea02018-05-07 20:01:011913 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511914 socket_factory_.AddSocketDataProvider(&data);
1915 SSLSocketDataProvider ssl(ASYNC, OK);
1916 socket_factory_.AddSSLSocketDataProvider(&ssl);
1917
1918 CreateSession();
1919
1920 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381921 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511922}
1923
bncc958faa2015-07-31 18:14:521924TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521925 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561926 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1927 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521928 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1929 MockRead(ASYNC, OK)};
1930
Ryan Sleevib8d7ea02018-05-07 20:01:011931 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521932 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081933 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561934 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521935
Ryan Hamiltonabad59e2019-06-06 04:02:591936 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231937 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251938 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231939 mock_quic_data.AddWrite(SYNCHRONOUS,
1940 ConstructInitialSettingsPacket(packet_num++));
1941 }
rch5cb522462017-04-25 20:18:361942 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231943 SYNCHRONOUS,
1944 ConstructClientRequestHeadersPacket(
1945 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1946 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431947 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331948 ASYNC, ConstructServerResponseHeadersPacket(
1949 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1950 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431951 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331952 mock_quic_data.AddRead(
1953 ASYNC, ConstructServerDataPacket(
1954 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171955 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231956 mock_quic_data.AddWrite(SYNCHRONOUS,
1957 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:521958 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591959 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521960
1961 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1962
rtennetib8e80fb2016-05-16 00:12:091963 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321964 CreateSession();
bncc958faa2015-07-31 18:14:521965
1966 SendRequestAndExpectHttpResponse("hello world");
1967 SendRequestAndExpectQuicResponse("hello!");
1968}
1969
Ryan Hamilton64f21d52019-08-31 07:10:511970TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1971 std::string alt_svc_header =
1972 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1973 MockRead http_reads[] = {
1974 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1975 MockRead("hello world"),
1976 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1977 MockRead(ASYNC, OK)};
1978
1979 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1980 socket_factory_.AddSocketDataProvider(&http_data);
1981 AddCertificate(&ssl_data_);
1982 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1983
1984 MockQuicData mock_quic_data(version_);
1985 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251986 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:511987 mock_quic_data.AddWrite(SYNCHRONOUS,
1988 ConstructInitialSettingsPacket(packet_num++));
1989 }
1990 mock_quic_data.AddWrite(
1991 SYNCHRONOUS,
1992 ConstructClientRequestHeadersPacket(
1993 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1994 true, GetRequestHeaders("GET", "https", "/")));
1995 mock_quic_data.AddRead(
1996 ASYNC, ConstructServerResponseHeadersPacket(
1997 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1998 GetResponseHeaders("200 OK")));
1999 std::string header = ConstructDataHeader(6);
2000 mock_quic_data.AddRead(
2001 ASYNC, ConstructServerDataPacket(
2002 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2003 header + "hello!"));
2004 mock_quic_data.AddWrite(SYNCHRONOUS,
2005 ConstructClientAckPacket(packet_num++, 2, 1, 1));
2006 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2007 mock_quic_data.AddRead(ASYNC, 0); // EOF
2008
2009 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2010
2011 AddHangingNonAlternateProtocolSocketData();
2012 CreateSession();
2013
2014 SendRequestAndExpectHttpResponse("hello world");
2015 SendRequestAndExpectQuicResponse("hello!");
2016}
2017
Matt Menke3233d8f22019-08-20 21:01:492018// Much like above, but makes sure NetworkIsolationKey is respected.
2019TEST_P(QuicNetworkTransactionTest,
2020 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2021 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052022 feature_list.InitWithFeatures(
2023 // enabled_features
2024 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2025 features::kPartitionConnectionsByNetworkIsolationKey},
2026 // disabled_features
2027 {});
Matt Menke3233d8f22019-08-20 21:01:492028 // Since HttpServerProperties caches the feature value, have to create a new
2029 // one.
2030 http_server_properties_ = std::make_unique<HttpServerProperties>();
2031
2032 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2033 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2034 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2035 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2036
2037 MockRead http_reads[] = {
2038 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2039 MockRead("hello world"),
2040 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2041 MockRead(ASYNC, OK)};
2042
2043 AddCertificate(&ssl_data_);
2044
2045 // Request with empty NetworkIsolationKey.
2046 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2047 socket_factory_.AddSocketDataProvider(&http_data1);
2048 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2049
2050 // First request with kNetworkIsolationKey1.
2051 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2052 socket_factory_.AddSocketDataProvider(&http_data2);
2053 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2054
2055 // Request with kNetworkIsolationKey2.
2056 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2057 socket_factory_.AddSocketDataProvider(&http_data3);
2058 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2059
2060 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2061 // alternative service infrmation has been received in this context before.
2062 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232063 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252064 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232065 mock_quic_data.AddWrite(SYNCHRONOUS,
2066 ConstructInitialSettingsPacket(packet_num++));
2067 }
Matt Menke3233d8f22019-08-20 21:01:492068 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232069 SYNCHRONOUS,
2070 ConstructClientRequestHeadersPacket(
2071 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2072 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492073 mock_quic_data.AddRead(
2074 ASYNC, ConstructServerResponseHeadersPacket(
2075 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2076 GetResponseHeaders("200 OK")));
2077 std::string header = ConstructDataHeader(6);
2078 mock_quic_data.AddRead(
2079 ASYNC, ConstructServerDataPacket(
2080 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2081 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232082 mock_quic_data.AddWrite(SYNCHRONOUS,
2083 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492084 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2085 mock_quic_data.AddRead(ASYNC, 0); // EOF
2086
2087 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2088
2089 AddHangingNonAlternateProtocolSocketData();
2090 CreateSession();
2091
2092 // This is first so that the test fails if alternative service info is
2093 // written with the right NetworkIsolationKey, but always queried with an
2094 // empty one.
2095 request_.network_isolation_key = NetworkIsolationKey();
2096 SendRequestAndExpectHttpResponse("hello world");
2097 request_.network_isolation_key = kNetworkIsolationKey1;
2098 SendRequestAndExpectHttpResponse("hello world");
2099 request_.network_isolation_key = kNetworkIsolationKey2;
2100 SendRequestAndExpectHttpResponse("hello world");
2101
2102 // Only use QUIC when using a NetworkIsolationKey which has been used when
2103 // alternative service information was received.
2104 request_.network_isolation_key = kNetworkIsolationKey1;
2105 SendRequestAndExpectQuicResponse("hello!");
2106}
2107
zhongyia00ca012017-07-06 23:36:392108TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2109 // Both server advertises and client supports two QUIC versions.
2110 // Only |version_| is advertised and supported.
2111 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2112 // PacketMakers are using |version_|.
2113
2114 // Add support for another QUIC version besides |version_| on the client side.
2115 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562116 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2117 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392118 if (version == version_)
2119 continue;
2120 if (supported_versions_.size() != 2) {
2121 supported_versions_.push_back(version);
2122 continue;
2123 }
2124 advertised_version_2 = version;
2125 break;
2126 }
Nick Harper23290b82019-05-02 00:02:562127 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392128
Nick Harper23290b82019-05-02 00:02:562129 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
2130 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2131 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392132
2133 MockRead http_reads[] = {
2134 MockRead("HTTP/1.1 200 OK\r\n"),
2135 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2136 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2137 MockRead(ASYNC, OK)};
2138
Ryan Sleevib8d7ea02018-05-07 20:01:012139 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392140 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082141 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392142 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2143
Ryan Hamiltonabad59e2019-06-06 04:02:592144 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232145 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252146 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232147 mock_quic_data.AddWrite(SYNCHRONOUS,
2148 ConstructInitialSettingsPacket(packet_num++));
2149 }
zhongyia00ca012017-07-06 23:36:392150 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232151 SYNCHRONOUS,
2152 ConstructClientRequestHeadersPacket(
2153 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2154 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432155 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332156 ASYNC, ConstructServerResponseHeadersPacket(
2157 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2158 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432159 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332160 mock_quic_data.AddRead(
2161 ASYNC, ConstructServerDataPacket(
2162 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172163 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232164 mock_quic_data.AddWrite(SYNCHRONOUS,
2165 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392166 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2167 mock_quic_data.AddRead(ASYNC, 0); // EOF
2168
2169 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2170
2171 AddHangingNonAlternateProtocolSocketData();
2172 CreateSession(supported_versions_);
2173
2174 SendRequestAndExpectHttpResponse("hello world");
2175 SendRequestAndExpectQuicResponse("hello!");
2176}
2177
2178TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
2179 // Client and server mutually support more than one QUIC_VERSION.
2180 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2181 // which is verified as the PacketMakers are using |version_|.
2182
Nick Harper23290b82019-05-02 00:02:562183 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2184 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392185 if (version == version_)
2186 continue;
2187 common_version_2 = version;
2188 break;
2189 }
Nick Harper23290b82019-05-02 00:02:562190 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392191
2192 supported_versions_.push_back(
2193 common_version_2); // Supported but unpreferred.
2194
2195 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562196 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2197 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392198
2199 MockRead http_reads[] = {
2200 MockRead("HTTP/1.1 200 OK\r\n"),
2201 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2202 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2203 MockRead(ASYNC, OK)};
2204
Ryan Sleevib8d7ea02018-05-07 20:01:012205 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392206 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082207 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392208 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2209
Ryan Hamiltonabad59e2019-06-06 04:02:592210 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232211 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252212 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232213 mock_quic_data.AddWrite(SYNCHRONOUS,
2214 ConstructInitialSettingsPacket(packet_num++));
2215 }
zhongyia00ca012017-07-06 23:36:392216 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232217 SYNCHRONOUS,
2218 ConstructClientRequestHeadersPacket(
2219 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2220 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432221 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332222 ASYNC, ConstructServerResponseHeadersPacket(
2223 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2224 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432225 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332226 mock_quic_data.AddRead(
2227 ASYNC, ConstructServerDataPacket(
2228 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172229 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232230 mock_quic_data.AddWrite(SYNCHRONOUS,
2231 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392232 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2233 mock_quic_data.AddRead(ASYNC, 0); // EOF
2234
2235 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2236
2237 AddHangingNonAlternateProtocolSocketData();
2238 CreateSession(supported_versions_);
2239
2240 SendRequestAndExpectHttpResponse("hello world");
2241 SendRequestAndExpectQuicResponse("hello!");
2242}
2243
rchf47265dc2016-03-21 21:33:122244TEST_P(QuicNetworkTransactionTest,
2245 UseAlternativeServiceWithProbabilityForQuic) {
2246 MockRead http_reads[] = {
2247 MockRead("HTTP/1.1 200 OK\r\n"),
2248 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2249 MockRead("hello world"),
2250 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2251 MockRead(ASYNC, OK)};
2252
Ryan Sleevib8d7ea02018-05-07 20:01:012253 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122254 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082255 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122256 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2257
Ryan Hamiltonabad59e2019-06-06 04:02:592258 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232259 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252260 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232261 mock_quic_data.AddWrite(SYNCHRONOUS,
2262 ConstructInitialSettingsPacket(packet_num++));
2263 }
rch5cb522462017-04-25 20:18:362264 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232265 SYNCHRONOUS,
2266 ConstructClientRequestHeadersPacket(
2267 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2268 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432269 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332270 ASYNC, ConstructServerResponseHeadersPacket(
2271 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2272 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432273 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332274 mock_quic_data.AddRead(
2275 ASYNC, ConstructServerDataPacket(
2276 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172277 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232278 mock_quic_data.AddWrite(SYNCHRONOUS,
2279 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122280 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2281 mock_quic_data.AddRead(ASYNC, 0); // EOF
2282
2283 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2284
rtennetib8e80fb2016-05-16 00:12:092285 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122286 CreateSession();
2287
2288 SendRequestAndExpectHttpResponse("hello world");
2289 SendRequestAndExpectQuicResponse("hello!");
2290}
2291
zhongyi3d4a55e72016-04-22 20:36:462292TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2293 MockRead http_reads[] = {
2294 MockRead("HTTP/1.1 200 OK\r\n"),
2295 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2296 MockRead("hello world"),
2297 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2298 MockRead(ASYNC, OK)};
2299
Ryan Sleevib8d7ea02018-05-07 20:01:012300 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462301 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082302 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462303 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2304
2305 CreateSession();
bncb26024382016-06-29 02:39:452306 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462307 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452308 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462309 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402310 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462311 session_->http_server_properties();
2312 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2313 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2314 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462315 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492316 2u, http_server_properties
2317 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2318 .size());
bncb26024382016-06-29 02:39:452319 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492320 http_server_properties
2321 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2322 .empty());
zhongyi3d4a55e72016-04-22 20:36:462323}
2324
2325TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2326 MockRead http_reads[] = {
2327 MockRead("HTTP/1.1 200 OK\r\n"),
2328 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2329 MockRead("hello world"),
2330 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2331 MockRead(ASYNC, OK)};
2332
Ryan Sleevib8d7ea02018-05-07 20:01:012333 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082334 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462335
2336 socket_factory_.AddSocketDataProvider(&http_data);
2337 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2338 socket_factory_.AddSocketDataProvider(&http_data);
2339 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2340
2341 CreateSession();
2342
2343 // Send https request and set alternative services if response header
2344 // advertises alternative service for mail.example.org.
2345 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402346 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462347 session_->http_server_properties();
2348
2349 const url::SchemeHostPort https_server(request_.url);
2350 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342351 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492352 2u, http_server_properties
2353 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2354 .size());
zhongyi3d4a55e72016-04-22 20:36:462355
2356 // Send http request to the same origin but with diffrent scheme, should not
2357 // use QUIC.
2358 request_.url = GURL("http://mail.example.org:443");
2359 SendRequestAndExpectHttpResponse("hello world");
2360}
2361
zhongyie537a002017-06-27 16:48:212362TEST_P(QuicNetworkTransactionTest,
2363 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442364 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562365 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442366 if (version == version_)
2367 continue;
2368 supported_versions_.push_back(version);
2369 break;
2370 }
2371
Ryan Hamilton8380c652019-06-04 02:25:062372 quic::ParsedQuicVersionVector versions;
2373 for (quic::QuicTransportVersion version :
2374 quic::AllSupportedTransportVersions()) {
2375 versions.push_back(
2376 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2377 }
zhongyie537a002017-06-27 16:48:212378 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062379 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212380 std::string altsvc_header =
2381 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2382 advertised_versions_list_str.c_str());
2383 MockRead http_reads[] = {
2384 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2385 MockRead("hello world"),
2386 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2387 MockRead(ASYNC, OK)};
2388
Ryan Sleevib8d7ea02018-05-07 20:01:012389 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212390 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082391 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212392 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2393
Ryan Hamiltonabad59e2019-06-06 04:02:592394 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232395 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252396 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232397 mock_quic_data.AddWrite(SYNCHRONOUS,
2398 ConstructInitialSettingsPacket(packet_num++));
2399 }
zhongyie537a002017-06-27 16:48:212400 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232401 SYNCHRONOUS,
2402 ConstructClientRequestHeadersPacket(
2403 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2404 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432405 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332406 ASYNC, ConstructServerResponseHeadersPacket(
2407 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2408 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432409 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332410 mock_quic_data.AddRead(
2411 ASYNC, ConstructServerDataPacket(
2412 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172413 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232414 mock_quic_data.AddWrite(SYNCHRONOUS,
2415 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212416 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2417 mock_quic_data.AddRead(ASYNC, 0); // EOF
2418
2419 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2420
2421 AddHangingNonAlternateProtocolSocketData();
2422
zhongyi86838d52017-06-30 01:19:442423 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212424
2425 SendRequestAndExpectHttpResponse("hello world");
2426 SendRequestAndExpectQuicResponse("hello!");
2427
2428 // Check alternative service is set with only mutually supported versions.
2429 const url::SchemeHostPort https_server(request_.url);
2430 const AlternativeServiceInfoVector alt_svc_info_vector =
2431 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492432 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212433 EXPECT_EQ(1u, alt_svc_info_vector.size());
2434 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2435 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2436 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562437 std::sort(
2438 supported_versions_.begin(), supported_versions_.end(),
2439 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2440 return a.transport_version < b.transport_version;
2441 });
zhongyi86838d52017-06-30 01:19:442442 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212443 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442444 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212445 alt_svc_info_vector[0].advertised_versions()[1]);
2446}
2447
danzh3134c2562016-08-12 14:07:522448TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562449 std::string altsvc_header = base::StringPrintf(
2450 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072451 MockRead http_reads[] = {
2452 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2453 MockRead("hello world"),
2454 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2455 MockRead(ASYNC, OK)};
2456
Ryan Sleevib8d7ea02018-05-07 20:01:012457 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072458 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082459 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072460 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2461
Ryan Hamiltonabad59e2019-06-06 04:02:592462 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232463 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252464 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232465 mock_quic_data.AddWrite(SYNCHRONOUS,
2466 ConstructInitialSettingsPacket(packet_num++));
2467 }
rch5cb522462017-04-25 20:18:362468 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232469 SYNCHRONOUS,
2470 ConstructClientRequestHeadersPacket(
2471 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2472 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432473 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332474 ASYNC, ConstructServerResponseHeadersPacket(
2475 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2476 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432477 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332478 mock_quic_data.AddRead(
2479 ASYNC, ConstructServerDataPacket(
2480 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172481 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232482 mock_quic_data.AddWrite(SYNCHRONOUS,
2483 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072484 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592485 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072486
2487 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2488
rtennetib8e80fb2016-05-16 00:12:092489 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322490 CreateSession();
bnc8be55ebb2015-10-30 14:12:072491
2492 SendRequestAndExpectHttpResponse("hello world");
2493 SendRequestAndExpectQuicResponse("hello!");
2494}
2495
zhongyi6b5a3892016-03-12 04:46:202496TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562497 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangba21e032019-09-27 21:52:282498 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092499 return;
2500 }
Ryan Hamiltonabad59e2019-06-06 04:02:592501 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232502 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252503 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232504 mock_quic_data.AddWrite(SYNCHRONOUS,
2505 ConstructInitialSettingsPacket(packet_num++));
2506 }
rch5cb522462017-04-25 20:18:362507 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232508 SYNCHRONOUS,
2509 ConstructClientRequestHeadersPacket(
2510 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2511 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332512 mock_quic_data.AddRead(
2513 ASYNC, ConstructServerResponseHeadersPacket(
2514 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2515 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202516 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522517 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432518 mock_quic_data.AddRead(SYNCHRONOUS,
2519 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522520 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432521 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232522 mock_quic_data.AddWrite(SYNCHRONOUS,
2523 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432524 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332525 mock_quic_data.AddRead(
2526 SYNCHRONOUS, ConstructServerDataPacket(
2527 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172528 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232529 mock_quic_data.AddWrite(
2530 SYNCHRONOUS,
2531 ConstructClientAckAndRstPacket(
2532 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2533 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202534 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2535 mock_quic_data.AddRead(ASYNC, 0); // EOF
2536
2537 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2538
2539 // The non-alternate protocol job needs to hang in order to guarantee that
2540 // the alternate-protocol job will "win".
2541 AddHangingNonAlternateProtocolSocketData();
2542
2543 // In order for a new QUIC session to be established via alternate-protocol
2544 // without racing an HTTP connection, we need the host resolution to happen
2545 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2546 // connection to the the server, in this test we require confirmation
2547 // before encrypting so the HTTP job will still start.
2548 host_resolver_.set_synchronous_mode(true);
2549 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2550 "");
zhongyi6b5a3892016-03-12 04:46:202551
2552 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432553 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2554 false);
Ryan Hamilton9835e662018-08-02 05:36:272555 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202556
bnc691fda62016-08-12 00:43:162557 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202558 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362559 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202561
2562 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522563 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012564 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202565
2566 // Check whether this transaction is correctly marked as received a go-away
2567 // because of migrating port.
2568 NetErrorDetails details;
2569 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162570 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202571 EXPECT_TRUE(details.quic_port_migration_detected);
2572}
2573
Zhongyi Shia6b68d112018-09-24 07:49:032574// This test verifies that a new QUIC connection will be attempted on the
2575// alternate network if the original QUIC connection fails with idle timeout
2576// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2577// alternate network as well, QUIC is marked as broken and the brokenness will
2578// not expire when default network changes.
2579TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432580 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2581 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2582 return;
2583 }
Zhongyi Shia6b68d112018-09-24 07:49:032584 SetUpTestForRetryConnectionOnAlternateNetwork();
2585
Michael Warres167db3e2019-03-01 21:38:032586 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032587
2588 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592589 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032590 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2591 int packet_num = 1;
2592 quic_data.AddWrite(SYNCHRONOUS,
2593 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2594 // Retranmit the handshake messages.
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 quic_data.AddWrite(SYNCHRONOUS,
2602 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032603 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2604 quic_data.AddWrite(SYNCHRONOUS,
2605 client_maker_.MakeConnectionClosePacket(
2606 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2607 "No recent network activity."));
2608 quic_data.AddSocketDataToFactory(&socket_factory_);
2609
2610 // Add successful TCP data so that TCP job will succeed.
2611 MockWrite http_writes[] = {
2612 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2613 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2614 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2615
2616 MockRead http_reads[] = {
2617 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2618 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2619 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2620 SequencedSocketData http_data(http_reads, http_writes);
2621 socket_factory_.AddSocketDataProvider(&http_data);
2622 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2623
2624 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592625 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032626 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2627 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2628 quic_data2.AddSocketDataToFactory(&socket_factory_);
2629
2630 // Resolve the host resolution synchronously.
2631 host_resolver_.set_synchronous_mode(true);
2632 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2633 "");
Zhongyi Shia6b68d112018-09-24 07:49:032634
2635 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432636 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2637 false);
Zhongyi Shia6b68d112018-09-24 07:49:032638 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032639 QuicStreamFactoryPeer::SetAlarmFactory(
2640 session_->quic_stream_factory(),
2641 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222642 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032643 // Add alternate protocol mapping to race QUIC and TCP.
2644 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2645 // peer.
2646 AddQuicAlternateProtocolMapping(
2647 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2648
2649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2650 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362651 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2653
2654 // Pump the message loop to get the request started.
2655 // Request will be served with TCP job.
2656 base::RunLoop().RunUntilIdle();
2657 EXPECT_THAT(callback.WaitForResult(), IsOk());
2658 CheckResponseData(&trans, "TCP succeeds");
2659
Zhongyi Shia6b68d112018-09-24 07:49:032660 // Fast forward to idle timeout the original connection. A new connection will
2661 // be kicked off on the alternate network.
2662 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2663 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2664 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2665
2666 // Run the message loop to execute posted tasks, which will report job status.
2667 base::RunLoop().RunUntilIdle();
2668
2669 // Verify that QUIC is marked as broken.
2670 ExpectBrokenAlternateProtocolMapping();
2671
2672 // Deliver a message to notify the new network becomes default, the brokenness
2673 // will not expire as QUIC is broken on both networks.
2674 scoped_mock_change_notifier_->mock_network_change_notifier()
2675 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2676 ExpectBrokenAlternateProtocolMapping();
2677
2678 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2679 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2680}
2681
2682// This test verifies that a new QUIC connection will be attempted on the
2683// alternate network if the original QUIC connection fails with idle timeout
2684// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2685// alternate network, QUIC is marked as broken. The brokenness will expire when
2686// the default network changes.
2687TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432688 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2689 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2690 return;
2691 }
2692
Zhongyi Shia6b68d112018-09-24 07:49:032693 SetUpTestForRetryConnectionOnAlternateNetwork();
2694
Michael Warres167db3e2019-03-01 21:38:032695 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032696
2697 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592698 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032699 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2700 int packet_num = 1;
2701 quic_data.AddWrite(SYNCHRONOUS,
2702 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2703 // Retranmit the handshake messages.
2704 quic_data.AddWrite(SYNCHRONOUS,
2705 client_maker_.MakeDummyCHLOPacket(packet_num++));
2706 quic_data.AddWrite(SYNCHRONOUS,
2707 client_maker_.MakeDummyCHLOPacket(packet_num++));
2708 quic_data.AddWrite(SYNCHRONOUS,
2709 client_maker_.MakeDummyCHLOPacket(packet_num++));
2710 quic_data.AddWrite(SYNCHRONOUS,
2711 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032712 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2713 quic_data.AddWrite(SYNCHRONOUS,
2714 client_maker_.MakeConnectionClosePacket(
2715 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2716 "No recent network activity."));
2717 quic_data.AddSocketDataToFactory(&socket_factory_);
2718
2719 // Add successful TCP data so that TCP job will succeed.
2720 MockWrite http_writes[] = {
2721 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2722 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2723 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2724
2725 MockRead http_reads[] = {
2726 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2727 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2728 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2729 SequencedSocketData http_data(http_reads, http_writes);
2730 socket_factory_.AddSocketDataProvider(&http_data);
2731 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2732
2733 // Quic connection will be retried on the alternate network after the initial
2734 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592735 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032736 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2737 quic_data2.AddWrite(SYNCHRONOUS,
2738 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2739
2740 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252741 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232742 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032743 quic_data2.AddSocketDataToFactory(&socket_factory_);
2744
2745 // Resolve the host resolution synchronously.
2746 host_resolver_.set_synchronous_mode(true);
2747 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2748 "");
Zhongyi Shia6b68d112018-09-24 07:49:032749
2750 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432751 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2752 false);
Zhongyi Shia6b68d112018-09-24 07:49:032753 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032754 QuicStreamFactoryPeer::SetAlarmFactory(
2755 session_->quic_stream_factory(),
2756 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222757 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032758 // Add alternate protocol mapping to race QUIC and TCP.
2759 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2760 // peer.
2761 AddQuicAlternateProtocolMapping(
2762 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2763
2764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2765 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362766 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2768
2769 // Pump the message loop to get the request started.
2770 // Request will be served with TCP job.
2771 base::RunLoop().RunUntilIdle();
2772 EXPECT_THAT(callback.WaitForResult(), IsOk());
2773 CheckResponseData(&trans, "TCP succeeds");
2774
Zhongyi Shia6b68d112018-09-24 07:49:032775 // Fast forward to idle timeout the original connection. A new connection will
2776 // be kicked off on the alternate network.
2777 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2778 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2779 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2780
2781 // The second connection hasn't finish handshake, verify that QUIC is not
2782 // marked as broken.
2783 ExpectQuicAlternateProtocolMapping();
2784 // Explicitly confirm the handshake on the second connection.
2785 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2786 quic::QuicSession::HANDSHAKE_CONFIRMED);
2787 // Run message loop to execute posted tasks, which will notify JoController
2788 // about the orphaned job status.
2789 base::RunLoop().RunUntilIdle();
2790
2791 // Verify that QUIC is marked as broken.
2792 ExpectBrokenAlternateProtocolMapping();
2793
2794 // Deliver a message to notify the new network becomes default, the previous
2795 // brokenness will be clear as the brokenness is bond with old default
2796 // network.
2797 scoped_mock_change_notifier_->mock_network_change_notifier()
2798 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2799 ExpectQuicAlternateProtocolMapping();
2800
2801 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2802 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2803}
2804
Matt Menkeb32ba5122019-09-10 19:17:052805// Much like above test, but verifies NetworkIsolationKeys are respected.
2806TEST_P(QuicNetworkTransactionTest,
2807 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432808 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2809 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2810 return;
2811 }
2812
Matt Menkeb32ba5122019-09-10 19:17:052813 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2814 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2815 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2816 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2817
2818 base::test::ScopedFeatureList feature_list;
2819 feature_list.InitWithFeatures(
2820 // enabled_features
2821 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2822 // Need to partition connections by NetworkIsolationKey for
2823 // QuicSessionAliasKey to include NetworkIsolationKeys.
2824 features::kPartitionConnectionsByNetworkIsolationKey},
2825 // disabled_features
2826 {});
2827 // Since HttpServerProperties caches the feature value, have to create a new
2828 // one.
2829 http_server_properties_ = std::make_unique<HttpServerProperties>();
2830
2831 SetUpTestForRetryConnectionOnAlternateNetwork();
2832
2833 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2834
2835 // The request will initially go out over QUIC.
2836 MockQuicData quic_data(version_);
2837 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2838 int packet_num = 1;
2839 quic_data.AddWrite(SYNCHRONOUS,
2840 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2841 // Retranmit the handshake messages.
2842 quic_data.AddWrite(SYNCHRONOUS,
2843 client_maker_.MakeDummyCHLOPacket(packet_num++));
2844 quic_data.AddWrite(SYNCHRONOUS,
2845 client_maker_.MakeDummyCHLOPacket(packet_num++));
2846 quic_data.AddWrite(SYNCHRONOUS,
2847 client_maker_.MakeDummyCHLOPacket(packet_num++));
2848 quic_data.AddWrite(SYNCHRONOUS,
2849 client_maker_.MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052850 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2851 quic_data.AddWrite(SYNCHRONOUS,
2852 client_maker_.MakeConnectionClosePacket(
2853 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2854 "No recent network activity."));
2855 quic_data.AddSocketDataToFactory(&socket_factory_);
2856
2857 // Add successful TCP data so that TCP job will succeed.
2858 MockWrite http_writes[] = {
2859 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2860 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2861 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2862
2863 MockRead http_reads[] = {
2864 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2865 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2866 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2867 SequencedSocketData http_data(http_reads, http_writes);
2868 socket_factory_.AddSocketDataProvider(&http_data);
2869 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2870
2871 // Quic connection will be retried on the alternate network after the initial
2872 // one fails on the default network.
2873 MockQuicData quic_data2(version_);
2874 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2875 quic_data2.AddWrite(SYNCHRONOUS,
2876 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2877
2878 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252879 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:052880 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2881 quic_data2.AddSocketDataToFactory(&socket_factory_);
2882
2883 // Resolve the host resolution synchronously.
2884 host_resolver_.set_synchronous_mode(true);
2885 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2886 "");
2887
2888 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432889 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2890 false);
Matt Menkeb32ba5122019-09-10 19:17:052891 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2892 QuicStreamFactoryPeer::SetAlarmFactory(
2893 session_->quic_stream_factory(),
2894 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222895 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:052896 // Add alternate protocol mapping to race QUIC and TCP.
2897 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2898 // peer.
2899 AddQuicAlternateProtocolMapping(
2900 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2901 AddQuicAlternateProtocolMapping(
2902 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2903
2904 request_.network_isolation_key = kNetworkIsolationKey1;
2905 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2906 TestCompletionCallback callback;
2907 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2909
2910 // Pump the message loop to get the request started.
2911 // Request will be served with TCP job.
2912 base::RunLoop().RunUntilIdle();
2913 EXPECT_THAT(callback.WaitForResult(), IsOk());
2914 CheckResponseData(&trans, "TCP succeeds");
2915
2916 // Fast forward to idle timeout the original connection. A new connection will
2917 // be kicked off on the alternate network.
2918 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2919 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2920 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2921
2922 // The second connection hasn't finish handshake, verify that QUIC is not
2923 // marked as broken.
2924 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2925 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2926 // Explicitly confirm the handshake on the second connection.
2927 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2928 quic::QuicSession::HANDSHAKE_CONFIRMED);
2929 // Run message loop to execute posted tasks, which will notify JoController
2930 // about the orphaned job status.
2931 base::RunLoop().RunUntilIdle();
2932
2933 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2934 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2935 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2936
2937 // Deliver a message to notify the new network becomes default, the previous
2938 // brokenness will be clear as the brokenness is bond with old default
2939 // network.
2940 scoped_mock_change_notifier_->mock_network_change_notifier()
2941 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2942 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2943 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2944
2945 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2946 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2947}
2948
Zhongyi Shia6b68d112018-09-24 07:49:032949// This test verifies that a new QUIC connection will be attempted on the
2950// alternate network if the original QUIC connection fails with idle timeout
2951// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2952// alternative network succeeds, QUIC is not marked as broken.
2953TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432954 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2955 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2956 return;
2957 }
2958
Zhongyi Shia6b68d112018-09-24 07:49:032959 SetUpTestForRetryConnectionOnAlternateNetwork();
2960
Michael Warres167db3e2019-03-01 21:38:032961 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032962
2963 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592964 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032965 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2966 int packet_num = 1;
2967 quic_data.AddWrite(SYNCHRONOUS,
2968 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2969 // Retranmit the handshake messages.
2970 quic_data.AddWrite(SYNCHRONOUS,
2971 client_maker_.MakeDummyCHLOPacket(packet_num++));
2972 quic_data.AddWrite(SYNCHRONOUS,
2973 client_maker_.MakeDummyCHLOPacket(packet_num++));
2974 quic_data.AddWrite(SYNCHRONOUS,
2975 client_maker_.MakeDummyCHLOPacket(packet_num++));
2976 quic_data.AddWrite(SYNCHRONOUS,
2977 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032978 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2979 quic_data.AddWrite(SYNCHRONOUS,
2980 client_maker_.MakeConnectionClosePacket(
2981 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2982 "No recent network activity."));
2983 quic_data.AddSocketDataToFactory(&socket_factory_);
2984
2985 // Add hanging TCP data so that TCP job will never succeeded.
2986 AddHangingNonAlternateProtocolSocketData();
2987
2988 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:592989 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:232990 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:032991 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:232992 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:032993
Victor Vasiliev076657c2019-03-12 02:46:432994 const std::string body = "hello!";
2995 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412996
Zhongyi Shia6b68d112018-09-24 07:49:032997 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252998 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232999 quic_data2.AddWrite(SYNCHRONOUS,
3000 ConstructInitialSettingsPacket(packet_num++));
3001 }
Zhongyi Shia6b68d112018-09-24 07:49:033002 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233003 SYNCHRONOUS,
3004 ConstructClientRequestHeadersPacket(
3005 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3006 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033007 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333008 ASYNC, ConstructServerResponseHeadersPacket(
3009 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3010 GetResponseHeaders("200 OK")));
3011 quic_data2.AddRead(
3012 ASYNC, ConstructServerDataPacket(
3013 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173014 header + body));
Renjie Tangaadb84b2019-08-31 01:00:233015 quic_data2.AddWrite(SYNCHRONOUS,
3016 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033017 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3018 quic_data2.AddSocketDataToFactory(&socket_factory_);
3019
3020 // Resolve the host resolution synchronously.
3021 host_resolver_.set_synchronous_mode(true);
3022 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3023 "");
Zhongyi Shia6b68d112018-09-24 07:49:033024
3025 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433026 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3027 false);
Zhongyi Shia6b68d112018-09-24 07:49:033028 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033029 QuicStreamFactoryPeer::SetAlarmFactory(
3030 session_->quic_stream_factory(),
3031 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223032 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033033 // Add alternate protocol mapping to race QUIC and TCP.
3034 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3035 // peer.
3036 AddQuicAlternateProtocolMapping(
3037 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3038
3039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3040 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363041 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3043
3044 // Pump the message loop to get the request started.
3045 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033046
3047 // Fast forward to idle timeout the original connection. A new connection will
3048 // be kicked off on the alternate network.
3049 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3050 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3051 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3052
3053 // Verify that QUIC is not marked as broken.
3054 ExpectQuicAlternateProtocolMapping();
3055 // Explicitly confirm the handshake on the second connection.
3056 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3057 quic::QuicSession::HANDSHAKE_CONFIRMED);
3058
3059 // Read the response.
3060 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413061 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033062 // Verify that QUIC is not marked as broken.
3063 ExpectQuicAlternateProtocolMapping();
3064
3065 // Deliver a message to notify the new network becomes default.
3066 scoped_mock_change_notifier_->mock_network_change_notifier()
3067 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3068 ExpectQuicAlternateProtocolMapping();
3069 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3070 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3071}
3072
rch9ecde09b2017-04-08 00:18:233073// Verify that if a QUIC connection times out, the QuicHttpStream will
3074// return QUIC_PROTOCOL_ERROR.
3075TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433076 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3077 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3078 return;
3079 }
3080
Victor Vasilieva1e66d72019-12-05 17:55:383081 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3082 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233083
3084 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593085 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133086 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233087 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3088
Ryan Hamiltone940bd12019-06-30 02:46:453089 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033090 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493091 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253092 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493093 quic_data.AddWrite(SYNCHRONOUS,
3094 ConstructInitialSettingsPacket(packet_num++));
3095 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023096 quic_data.AddWrite(
3097 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453098 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493099 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3100 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453101
3102 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233103
Victor Vasiliev7da08172019-10-14 06:04:253104 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493105 // TLP 1
3106 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3107 1, packet_num++, true));
3108 // TLP 2
3109 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3110 2, packet_num++, true));
3111 // RTO 1
3112 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3113 1, packet_num++, true));
3114 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3115 2, packet_num++, true));
3116 // RTO 2
3117 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3118 1, packet_num++, true));
3119 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3120 2, packet_num++, true));
3121 // RTO 3
3122 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3123 1, packet_num++, true));
3124 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3125 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013126
Findit2403b85d2019-11-19 05:06:373127 quic_data.AddWrite(SYNCHRONOUS,
3128 client_maker_.MakeConnectionClosePacket(
3129 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3130 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493131 } else {
3132 // Settings were sent in the request packet so there is only 1 packet to
3133 // retransmit.
3134 // TLP 1
3135 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3136 1, packet_num++, true));
3137 // TLP 2
3138 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3139 1, packet_num++, true));
3140 // RTO 1
3141 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3142 1, packet_num++, true));
3143 // RTO 2
3144 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3145 1, packet_num++, true));
3146 // RTO 3
3147 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3148 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373149
Nick Harper057264a82019-09-12 23:33:493150 quic_data.AddWrite(SYNCHRONOUS,
3151 client_maker_.MakeConnectionClosePacket(
3152 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3153 "No recent network activity."));
3154 }
Fan Yang928f1632017-12-14 18:55:223155
rch9ecde09b2017-04-08 00:18:233156 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3157 quic_data.AddRead(ASYNC, OK);
3158 quic_data.AddSocketDataToFactory(&socket_factory_);
3159
3160 // In order for a new QUIC session to be established via alternate-protocol
3161 // without racing an HTTP connection, we need the host resolution to happen
3162 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3163 // connection to the the server, in this test we require confirmation
3164 // before encrypting so the HTTP job will still start.
3165 host_resolver_.set_synchronous_mode(true);
3166 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3167 "");
rch9ecde09b2017-04-08 00:18:233168
3169 CreateSession();
3170 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233171 QuicStreamFactoryPeer::SetAlarmFactory(
3172 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193173 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223174 context_.clock()));
rch9ecde09b2017-04-08 00:18:233175
Ryan Hamilton9835e662018-08-02 05:36:273176 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233177
3178 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3179 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363180 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3182
3183 // Pump the message loop to get the request started.
3184 base::RunLoop().RunUntilIdle();
3185 // Explicitly confirm the handshake.
3186 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523187 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233188
3189 // Run the QUIC session to completion.
3190 quic_task_runner_->RunUntilIdle();
3191
3192 ExpectQuicAlternateProtocolMapping();
3193 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3194 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3195}
3196
3197// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3198// return QUIC_PROTOCOL_ERROR.
3199TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433200 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3201 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3202 return;
3203 }
3204
Victor Vasilieva1e66d72019-12-05 17:55:383205 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3206 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233207
3208 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593209 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133210 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233211 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3212
Ryan Hamiltone940bd12019-06-30 02:46:453213 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033214 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493215 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253216 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493217 quic_data.AddWrite(
3218 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3219 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023220 quic_data.AddWrite(
3221 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453222 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493223 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3224 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453225
3226 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253227 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493228 // TLP 1
3229 quic_data.AddWrite(SYNCHRONOUS,
3230 client_maker_.MakeRetransmissionPacket(1, 3, true));
3231 // TLP 2
3232 quic_data.AddWrite(SYNCHRONOUS,
3233 client_maker_.MakeRetransmissionPacket(2, 4, true));
3234 // RTO 1
3235 quic_data.AddWrite(SYNCHRONOUS,
3236 client_maker_.MakeRetransmissionPacket(1, 5, true));
3237 quic_data.AddWrite(SYNCHRONOUS,
3238 client_maker_.MakeRetransmissionPacket(2, 6, true));
3239 // RTO 2
3240 quic_data.AddWrite(SYNCHRONOUS,
3241 client_maker_.MakeRetransmissionPacket(1, 7, true));
3242 quic_data.AddWrite(SYNCHRONOUS,
3243 client_maker_.MakeRetransmissionPacket(2, 8, true));
3244 // RTO 3
3245 quic_data.AddWrite(SYNCHRONOUS,
3246 client_maker_.MakeRetransmissionPacket(1, 9, true));
3247 quic_data.AddWrite(SYNCHRONOUS,
3248 client_maker_.MakeRetransmissionPacket(2, 10, true));
3249 // RTO 4
3250 quic_data.AddWrite(SYNCHRONOUS,
3251 client_maker_.MakeRetransmissionPacket(1, 11, true));
3252 quic_data.AddWrite(SYNCHRONOUS,
3253 client_maker_.MakeRetransmissionPacket(2, 12, true));
3254 // RTO 5
3255 quic_data.AddWrite(SYNCHRONOUS,
3256 client_maker_.MakeConnectionClosePacket(
3257 13, true, quic::QUIC_TOO_MANY_RTOS,
3258 "5 consecutive retransmission timeouts"));
3259 } else {
3260 // TLP 1
3261 quic_data.AddWrite(SYNCHRONOUS,
3262 client_maker_.MakeRetransmissionPacket(1, 2, true));
3263 // TLP 2
3264 quic_data.AddWrite(SYNCHRONOUS,
3265 client_maker_.MakeRetransmissionPacket(1, 3, true));
3266 // RTO 1
3267 quic_data.AddWrite(SYNCHRONOUS,
3268 client_maker_.MakeRetransmissionPacket(1, 4, true));
3269 // RTO 2
3270 quic_data.AddWrite(SYNCHRONOUS,
3271 client_maker_.MakeRetransmissionPacket(1, 5, true));
3272 // RTO 3
3273 quic_data.AddWrite(SYNCHRONOUS,
3274 client_maker_.MakeRetransmissionPacket(1, 6, true));
3275 // RTO 4
3276 quic_data.AddWrite(SYNCHRONOUS,
3277 client_maker_.MakeRetransmissionPacket(1, 7, true));
3278 // RTO 5
3279 quic_data.AddWrite(SYNCHRONOUS,
3280 client_maker_.MakeConnectionClosePacket(
3281 8, true, quic::QUIC_TOO_MANY_RTOS,
3282 "5 consecutive retransmission timeouts"));
3283 }
rch9ecde09b2017-04-08 00:18:233284
3285 quic_data.AddRead(ASYNC, OK);
3286 quic_data.AddSocketDataToFactory(&socket_factory_);
3287
3288 // In order for a new QUIC session to be established via alternate-protocol
3289 // without racing an HTTP connection, we need the host resolution to happen
3290 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3291 // connection to the the server, in this test we require confirmation
3292 // before encrypting so the HTTP job will still start.
3293 host_resolver_.set_synchronous_mode(true);
3294 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3295 "");
rch9ecde09b2017-04-08 00:18:233296
3297 CreateSession();
3298 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233299 QuicStreamFactoryPeer::SetAlarmFactory(
3300 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193301 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223302 context_.clock()));
rch9ecde09b2017-04-08 00:18:233303
Ryan Hamilton9835e662018-08-02 05:36:273304 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233305
3306 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3307 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363308 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233309 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3310
3311 // Pump the message loop to get the request started.
3312 base::RunLoop().RunUntilIdle();
3313 // Explicitly confirm the handshake.
3314 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523315 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233316
3317 // Run the QUIC session to completion.
3318 quic_task_runner_->RunUntilIdle();
3319
3320 ExpectQuicAlternateProtocolMapping();
3321 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3322 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3323}
3324
3325// Verify that if a QUIC connection RTOs, while there are no active streams
3326// QUIC will not be marked as broken.
3327TEST_P(QuicNetworkTransactionTest,
3328 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433329 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3330 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3331 return;
3332 }
3333
Victor Vasilieva1e66d72019-12-05 17:55:383334 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233335
3336 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593337 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133338 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233339 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3340
Ryan Hamiltone940bd12019-06-30 02:46:453341 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033342 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493343 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253344 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493345 quic_data.AddWrite(
3346 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3347 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023348 quic_data.AddWrite(
3349 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453350 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493351 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3352 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453353
3354 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233355
Victor Vasiliev7da08172019-10-14 06:04:253356 if (!VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493357 quic_data.AddWrite(SYNCHRONOUS,
3358 client_maker_.MakeRstPacket(
3359 packet_number++, true,
3360 GetNthClientInitiatedBidirectionalStreamId(0),
3361 quic::QUIC_STREAM_CANCELLED));
3362 // TLP 1
3363 quic_data.AddWrite(SYNCHRONOUS,
3364 client_maker_.MakeRetransmissionPacket(1, 3, true));
3365 // TLP 2
3366 quic_data.AddWrite(SYNCHRONOUS,
3367 client_maker_.MakeRetransmissionPacket(2, 4, true));
3368 // RTO 1
3369 quic_data.AddWrite(SYNCHRONOUS,
3370 client_maker_.MakeRetransmissionPacket(1, 5, true));
3371 quic_data.AddWrite(SYNCHRONOUS,
3372 client_maker_.MakeRetransmissionPacket(2, 6, true));
3373 // RTO 2
3374 quic_data.AddWrite(SYNCHRONOUS,
3375 client_maker_.MakeRetransmissionPacket(1, 7, true));
3376 quic_data.AddWrite(SYNCHRONOUS,
3377 client_maker_.MakeRetransmissionPacket(2, 8, true));
3378 // RTO 3
3379 quic_data.AddWrite(SYNCHRONOUS,
3380 client_maker_.MakeRetransmissionPacket(1, 9, true));
3381 quic_data.AddWrite(SYNCHRONOUS,
3382 client_maker_.MakeRetransmissionPacket(2, 10, true));
3383 // RTO 4
3384 quic_data.AddWrite(SYNCHRONOUS,
3385 client_maker_.MakeRetransmissionPacket(1, 11, true));
3386 quic_data.AddWrite(SYNCHRONOUS,
3387 client_maker_.MakeRetransmissionPacket(2, 12, true));
3388 // RTO 5
3389 quic_data.AddWrite(SYNCHRONOUS,
3390 client_maker_.MakeConnectionClosePacket(
3391 13, true, quic::QUIC_TOO_MANY_RTOS,
3392 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423393 } else if (FLAGS_quic_allow_http3_priority) {
Nick Harper057264a82019-09-12 23:33:493394 quic_data.AddWrite(
3395 SYNCHRONOUS, client_maker_.MakeRstPacket(
3396 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb01f886f2019-07-10 02:25:553397 quic::QUIC_STREAM_CANCELLED));
Nick Harper057264a82019-09-12 23:33:493398 client_maker_.RemoveSavedStreamFrames(
3399 GetNthClientInitiatedBidirectionalStreamId(0));
3400 // TLP 1
3401 quic_data.AddWrite(SYNCHRONOUS,
3402 client_maker_.MakeRetransmissionPacket(1, 4, true));
3403 // TLP 2
3404 quic_data.AddWrite(SYNCHRONOUS,
3405 client_maker_.MakeRetransmissionPacket(2, 5, true));
3406 // RTO 1
3407 quic_data.AddWrite(SYNCHRONOUS,
3408 client_maker_.MakeRetransmissionPacket(3, 6, true));
3409 quic_data.AddWrite(SYNCHRONOUS,
3410 client_maker_.MakeRetransmissionPacket(1, 7, true));
3411 // RTO 2
3412 quic_data.AddWrite(SYNCHRONOUS,
3413 client_maker_.MakeRetransmissionPacket(2, 8, true));
3414 quic_data.AddWrite(SYNCHRONOUS,
3415 client_maker_.MakeRetransmissionPacket(3, 9, true));
3416 // RTO 3
3417 quic_data.AddWrite(SYNCHRONOUS,
3418 client_maker_.MakeRetransmissionPacket(1, 10, true));
3419 quic_data.AddWrite(SYNCHRONOUS,
3420 client_maker_.MakeRetransmissionPacket(2, 11, true));
3421 // RTO 4
3422 quic_data.AddWrite(SYNCHRONOUS,
3423 client_maker_.MakeRetransmissionPacket(3, 12, true));
3424 quic_data.AddWrite(SYNCHRONOUS,
3425 client_maker_.MakeRetransmissionPacket(1, 13, true));
3426 // RTO 5
3427 quic_data.AddWrite(SYNCHRONOUS,
3428 client_maker_.MakeConnectionClosePacket(
3429 14, true, quic::QUIC_TOO_MANY_RTOS,
3430 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423431 } else {
3432 quic_data.AddWrite(
3433 SYNCHRONOUS, client_maker_.MakeRstPacket(
3434 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3435 quic::QUIC_STREAM_CANCELLED));
3436 client_maker_.RemoveSavedStreamFrames(
3437 GetNthClientInitiatedBidirectionalStreamId(0));
3438 // When PRIORITY is disabled, packet 2 only contains request headers. And
3439 // since the request stream is reset, packet 2 will not be retransmitted.
3440 // TLP 1
3441 quic_data.AddWrite(SYNCHRONOUS,
3442 client_maker_.MakeRetransmissionPacket(1, 4, true));
3443 // TLP 2
3444 quic_data.AddWrite(SYNCHRONOUS,
3445 client_maker_.MakeRetransmissionPacket(3, 5, true));
3446 // RTO 1
3447 quic_data.AddWrite(SYNCHRONOUS,
3448 client_maker_.MakeRetransmissionPacket(1, 6, true));
3449 quic_data.AddWrite(SYNCHRONOUS,
3450 client_maker_.MakeRetransmissionPacket(3, 7, true));
3451 // RTO 2
3452 quic_data.AddWrite(SYNCHRONOUS,
3453 client_maker_.MakeRetransmissionPacket(1, 8, true));
3454 quic_data.AddWrite(SYNCHRONOUS,
3455 client_maker_.MakeRetransmissionPacket(3, 9, true));
3456 // RTO 3
3457 quic_data.AddWrite(SYNCHRONOUS,
3458 client_maker_.MakeRetransmissionPacket(1, 10, true));
3459 quic_data.AddWrite(SYNCHRONOUS,
3460 client_maker_.MakeRetransmissionPacket(3, 11, true));
3461 // RTO 4
3462 quic_data.AddWrite(SYNCHRONOUS,
3463 client_maker_.MakeRetransmissionPacket(1, 12, true));
3464 quic_data.AddWrite(SYNCHRONOUS,
3465 client_maker_.MakeRetransmissionPacket(3, 13, true));
3466 // RTO 5
3467 quic_data.AddWrite(SYNCHRONOUS,
3468 client_maker_.MakeConnectionClosePacket(
3469 14, true, quic::QUIC_TOO_MANY_RTOS,
3470 "5 consecutive retransmission timeouts"));
Nick Harper057264a82019-09-12 23:33:493471 }
rch9ecde09b2017-04-08 00:18:233472
3473 quic_data.AddRead(ASYNC, OK);
3474 quic_data.AddSocketDataToFactory(&socket_factory_);
3475
3476 // In order for a new QUIC session to be established via alternate-protocol
3477 // without racing an HTTP connection, we need the host resolution to happen
3478 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3479 // connection to the the server, in this test we require confirmation
3480 // before encrypting so the HTTP job will still start.
3481 host_resolver_.set_synchronous_mode(true);
3482 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3483 "");
rch9ecde09b2017-04-08 00:18:233484
3485 CreateSession();
3486 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233487 QuicStreamFactoryPeer::SetAlarmFactory(
3488 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193489 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223490 context_.clock()));
rch9ecde09b2017-04-08 00:18:233491
Ryan Hamilton9835e662018-08-02 05:36:273492 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233493
Jeremy Roman0579ed62017-08-29 15:56:193494 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233495 session_.get());
3496 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363497 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233498 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3499
3500 // Pump the message loop to get the request started.
3501 base::RunLoop().RunUntilIdle();
3502 // Explicitly confirm the handshake.
3503 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523504 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233505
3506 // Now cancel the request.
3507 trans.reset();
3508
3509 // Run the QUIC session to completion.
3510 quic_task_runner_->RunUntilIdle();
3511
3512 ExpectQuicAlternateProtocolMapping();
3513
3514 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3515}
3516
rch2f2991c2017-04-13 19:28:173517// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3518// the request fails with QUIC_PROTOCOL_ERROR.
3519TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433520 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3521 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3522 return;
3523 }
3524
Victor Vasilieva1e66d72019-12-05 17:55:383525 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173526 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593527 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033528 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493529 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253530 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493531 quic_data.AddWrite(SYNCHRONOUS,
3532 ConstructInitialSettingsPacket(packet_num++));
3533 }
3534 quic_data.AddWrite(
3535 SYNCHRONOUS,
3536 ConstructClientRequestHeadersPacket(
3537 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3538 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023539 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553540 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173541 // Peer sending data from an non-existing stream causes this end to raise
3542 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333543 quic_data.AddRead(
3544 ASYNC, ConstructServerRstPacket(
3545 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3546 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173547 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373548 quic_data.AddWrite(SYNCHRONOUS,
3549 ConstructClientAckAndConnectionClosePacket(
3550 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3551 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3552 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173553 quic_data.AddSocketDataToFactory(&socket_factory_);
3554
3555 // In order for a new QUIC session to be established via alternate-protocol
3556 // without racing an HTTP connection, we need the host resolution to happen
3557 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3558 // connection to the the server, in this test we require confirmation
3559 // before encrypting so the HTTP job will still start.
3560 host_resolver_.set_synchronous_mode(true);
3561 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3562 "");
rch2f2991c2017-04-13 19:28:173563
3564 CreateSession();
3565
Ryan Hamilton9835e662018-08-02 05:36:273566 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173567
3568 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3569 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363570 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3572
3573 // Pump the message loop to get the request started.
3574 base::RunLoop().RunUntilIdle();
3575 // Explicitly confirm the handshake.
3576 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523577 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173578
3579 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553580 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173581
3582 // Run the QUIC session to completion.
3583 base::RunLoop().RunUntilIdle();
3584 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3585 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3586
3587 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3588 ExpectQuicAlternateProtocolMapping();
3589 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3590}
3591
rch2f2991c2017-04-13 19:28:173592// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3593// connection times out, then QUIC will be marked as broken and the request
3594// retried over TCP.
3595TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433596 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3597 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3598 return;
3599 }
3600
Victor Vasilieva1e66d72019-12-05 17:55:383601 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173602
3603 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593604 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133605 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173606 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3607
Ryan Hamiltone940bd12019-06-30 02:46:453608 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033609 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493610 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253611 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493612 quic_data.AddWrite(SYNCHRONOUS,
3613 client_maker_.MakeInitialSettingsPacket(packet_num++));
3614 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023615 quic_data.AddWrite(
3616 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453617 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493618 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3619 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453620
3621 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253622 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493623 // TLP 1
3624 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3625 1, packet_num++, true));
3626 // TLP 2
3627 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3628 2, packet_num++, true));
3629 // RTO 1
3630 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3631 1, packet_num++, true));
3632 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3633 2, packet_num++, true));
3634 // RTO 2
3635 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3636 1, packet_num++, true));
3637 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3638 2, packet_num++, true));
3639 // RTO 3
3640 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3641 1, packet_num++, true));
3642 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3643 2, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373644
3645 quic_data.AddWrite(SYNCHRONOUS,
3646 client_maker_.MakeConnectionClosePacket(
3647 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3648 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493649 } else {
3650 // TLP 1
3651 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3652 1, packet_num++, true));
3653 // TLP 2
3654 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3655 1, packet_num++, true));
3656 // RTO 1
3657 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3658 1, packet_num++, true));
3659 // RTO 2
3660 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3661 1, packet_num++, true));
3662 // RTO 3
3663 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3664 1, packet_num++, true));
3665
3666 quic_data.AddWrite(SYNCHRONOUS,
3667 client_maker_.MakeConnectionClosePacket(
3668 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3669 "No recent network activity."));
3670 }
Fan Yang928f1632017-12-14 18:55:223671
rch2f2991c2017-04-13 19:28:173672 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3673 quic_data.AddRead(ASYNC, OK);
3674 quic_data.AddSocketDataToFactory(&socket_factory_);
3675
3676 // After that fails, it will be resent via TCP.
3677 MockWrite http_writes[] = {
3678 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3679 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3680 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3681
3682 MockRead http_reads[] = {
3683 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3684 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3685 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013686 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173687 socket_factory_.AddSocketDataProvider(&http_data);
3688 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3689
3690 // In order for a new QUIC session to be established via alternate-protocol
3691 // without racing an HTTP connection, we need the host resolution to happen
3692 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3693 // connection to the the server, in this test we require confirmation
3694 // before encrypting so the HTTP job will still start.
3695 host_resolver_.set_synchronous_mode(true);
3696 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3697 "");
rch2f2991c2017-04-13 19:28:173698
3699 CreateSession();
3700 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173701 QuicStreamFactoryPeer::SetAlarmFactory(
3702 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193703 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223704 context_.clock()));
rch2f2991c2017-04-13 19:28:173705
Ryan Hamilton9835e662018-08-02 05:36:273706 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173707
3708 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3709 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363710 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173711 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3712
3713 // Pump the message loop to get the request started.
3714 base::RunLoop().RunUntilIdle();
3715 // Explicitly confirm the handshake.
3716 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523717 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173718
3719 // Run the QUIC session to completion.
3720 quic_task_runner_->RunUntilIdle();
3721 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3722
3723 ExpectQuicAlternateProtocolMapping();
3724
3725 // Let the transaction proceed which will result in QUIC being marked
3726 // as broken and the request falling back to TCP.
3727 EXPECT_THAT(callback.WaitForResult(), IsOk());
3728
3729 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3730 ASSERT_FALSE(http_data.AllReadDataConsumed());
3731
3732 // Read the response body over TCP.
3733 CheckResponseData(&trans, "hello world");
3734 ExpectBrokenAlternateProtocolMapping();
3735 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3736 ASSERT_TRUE(http_data.AllReadDataConsumed());
3737}
3738
rch2f2991c2017-04-13 19:28:173739// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3740// protocol error occurs after the handshake is confirmed, the request
3741// retried over TCP and the QUIC will be marked as broken.
3742TEST_P(QuicNetworkTransactionTest,
3743 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433744 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3745 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3746 return;
3747 }
3748
Victor Vasilieva1e66d72019-12-05 17:55:383749 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173750
3751 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593752 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033753 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493754 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253755 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493756 quic_data.AddWrite(SYNCHRONOUS,
3757 ConstructInitialSettingsPacket(packet_num++));
3758 }
3759 quic_data.AddWrite(
3760 SYNCHRONOUS,
3761 ConstructClientRequestHeadersPacket(
3762 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3763 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023764 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553765 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3766
rch2f2991c2017-04-13 19:28:173767 // Peer sending data from an non-existing stream causes this end to raise
3768 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333769 quic_data.AddRead(
3770 ASYNC, ConstructServerRstPacket(
3771 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3772 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173773 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373774 quic_data.AddWrite(SYNCHRONOUS,
3775 ConstructClientAckAndConnectionClosePacket(
3776 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3777 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3778 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173779 quic_data.AddSocketDataToFactory(&socket_factory_);
3780
3781 // After that fails, it will be resent via TCP.
3782 MockWrite http_writes[] = {
3783 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3784 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3785 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3786
3787 MockRead http_reads[] = {
3788 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3789 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3790 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013791 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173792 socket_factory_.AddSocketDataProvider(&http_data);
3793 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3794
3795 // In order for a new QUIC session to be established via alternate-protocol
3796 // without racing an HTTP connection, we need the host resolution to happen
3797 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3798 // connection to the the server, in this test we require confirmation
3799 // before encrypting so the HTTP job will still start.
3800 host_resolver_.set_synchronous_mode(true);
3801 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3802 "");
rch2f2991c2017-04-13 19:28:173803
3804 CreateSession();
3805
Ryan Hamilton9835e662018-08-02 05:36:273806 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173807
3808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3809 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363810 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3812
3813 // Pump the message loop to get the request started.
3814 base::RunLoop().RunUntilIdle();
3815 // Explicitly confirm the handshake.
3816 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523817 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553818 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173819
3820 // Run the QUIC session to completion.
3821 base::RunLoop().RunUntilIdle();
3822 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3823
3824 ExpectQuicAlternateProtocolMapping();
3825
3826 // Let the transaction proceed which will result in QUIC being marked
3827 // as broken and the request falling back to TCP.
3828 EXPECT_THAT(callback.WaitForResult(), IsOk());
3829
3830 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3831 ASSERT_FALSE(http_data.AllReadDataConsumed());
3832
3833 // Read the response body over TCP.
3834 CheckResponseData(&trans, "hello world");
3835 ExpectBrokenAlternateProtocolMapping();
3836 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3837 ASSERT_TRUE(http_data.AllReadDataConsumed());
3838}
3839
Matt Menkeb32ba5122019-09-10 19:17:053840// Much like above test, but verifies that NetworkIsolationKey is respected.
3841TEST_P(QuicNetworkTransactionTest,
3842 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433843 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3844 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3845 return;
3846 }
3847
Matt Menkeb32ba5122019-09-10 19:17:053848 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3849 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3850 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3851 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3852
3853 base::test::ScopedFeatureList feature_list;
3854 feature_list.InitWithFeatures(
3855 // enabled_features
3856 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3857 features::kPartitionConnectionsByNetworkIsolationKey},
3858 // disabled_features
3859 {});
3860 // Since HttpServerProperties caches the feature value, have to create a new
3861 // one.
3862 http_server_properties_ = std::make_unique<HttpServerProperties>();
3863
Victor Vasilieva1e66d72019-12-05 17:55:383864 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053865
3866 // The request will initially go out over QUIC.
3867 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563868 uint64_t packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:053869 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253870 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563871 quic_data.AddWrite(SYNCHRONOUS,
3872 ConstructInitialSettingsPacket(packet_number++));
3873 }
3874 quic_data.AddWrite(
3875 SYNCHRONOUS,
3876 ConstructClientRequestHeadersPacket(
3877 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3878 true, GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053879 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053880 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3881
3882 // Peer sending data from an non-existing stream causes this end to raise
3883 // error and close connection.
3884 quic_data.AddRead(
3885 ASYNC, ConstructServerRstPacket(
3886 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3887 quic::QUIC_STREAM_LAST_ERROR));
3888 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373889 quic_data.AddWrite(
3890 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3891 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3892 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3893 quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053894 quic_data.AddSocketDataToFactory(&socket_factory_);
3895
3896 // After that fails, it will be resent via TCP.
3897 MockWrite http_writes[] = {
3898 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3899 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3900 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3901
3902 MockRead http_reads[] = {
3903 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3904 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3905 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3906 SequencedSocketData http_data(http_reads, http_writes);
3907 socket_factory_.AddSocketDataProvider(&http_data);
3908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3909
3910 // In order for a new QUIC session to be established via alternate-protocol
3911 // without racing an HTTP connection, we need the host resolution to happen
3912 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3913 // connection to the the server, in this test we require confirmation
3914 // before encrypting so the HTTP job will still start.
3915 host_resolver_.set_synchronous_mode(true);
3916 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3917 "");
3918
3919 CreateSession();
3920
3921 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3922 kNetworkIsolationKey1);
3923 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3924 kNetworkIsolationKey2);
3925
3926 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3927 TestCompletionCallback callback;
3928 request_.network_isolation_key = kNetworkIsolationKey1;
3929 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3931
3932 // Pump the message loop to get the request started.
3933 base::RunLoop().RunUntilIdle();
3934 // Explicitly confirm the handshake.
3935 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3936 quic::QuicSession::HANDSHAKE_CONFIRMED);
3937 quic_data.Resume();
3938
3939 // Run the QUIC session to completion.
3940 base::RunLoop().RunUntilIdle();
3941 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3942
3943 // Let the transaction proceed which will result in QUIC being marked
3944 // as broken and the request falling back to TCP.
3945 EXPECT_THAT(callback.WaitForResult(), IsOk());
3946 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3947 ASSERT_FALSE(http_data.AllReadDataConsumed());
3948
3949 // Read the response body over TCP.
3950 CheckResponseData(&trans, "hello world");
3951 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3952 ASSERT_TRUE(http_data.AllReadDataConsumed());
3953
3954 // The alternative service shouldhave been marked as broken under
3955 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3956 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3957 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3958
3959 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3960 AddHttpDataAndRunRequest();
3961 // Requests using other NetworkIsolationKeys can still use QUIC.
3962 request_.network_isolation_key = kNetworkIsolationKey2;
3963 AddQuicDataAndRunRequest();
3964
3965 // The last two requests should not have changed the alternative service
3966 // mappings.
3967 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3968 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3969}
3970
rch30943ee2017-06-12 21:28:443971// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3972// request is reset from, then QUIC will be marked as broken and the request
3973// retried over TCP.
3974TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433975 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3976 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3977 return;
3978 }
3979
rch30943ee2017-06-12 21:28:443980 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593981 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133982 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443983 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3984
Michael Warres167db3e2019-03-01 21:38:033985 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493986 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253987 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493988 quic_data.AddWrite(SYNCHRONOUS,
3989 ConstructInitialSettingsPacket(packet_num++));
3990 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023991 quic_data.AddWrite(
3992 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453993 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493994 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3995 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453996
3997 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553998 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:443999
Fan Yang32c5a112018-12-10 20:06:334000 quic_data.AddRead(ASYNC,
4001 ConstructServerRstPacket(
4002 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
4003 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444004
4005 quic_data.AddRead(ASYNC, OK);
4006 quic_data.AddSocketDataToFactory(&socket_factory_);
4007
4008 // After that fails, it will be resent via TCP.
4009 MockWrite http_writes[] = {
4010 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4011 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
4012 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4013
4014 MockRead http_reads[] = {
4015 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4016 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4017 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014018 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444019 socket_factory_.AddSocketDataProvider(&http_data);
4020 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4021
4022 // In order for a new QUIC session to be established via alternate-protocol
4023 // without racing an HTTP connection, we need the host resolution to happen
4024 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4025 // connection to the the server, in this test we require confirmation
4026 // before encrypting so the HTTP job will still start.
4027 host_resolver_.set_synchronous_mode(true);
4028 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4029 "");
rch30943ee2017-06-12 21:28:444030
4031 CreateSession();
4032
Ryan Hamilton9835e662018-08-02 05:36:274033 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:444034
4035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4036 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364037 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:444038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4039
4040 // Pump the message loop to get the request started.
4041 base::RunLoop().RunUntilIdle();
4042 // Explicitly confirm the handshake.
4043 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524044 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:554045 quic_data.Resume();
rch30943ee2017-06-12 21:28:444046
4047 // Run the QUIC session to completion.
4048 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4049
4050 ExpectQuicAlternateProtocolMapping();
4051
4052 // Let the transaction proceed which will result in QUIC being marked
4053 // as broken and the request falling back to TCP.
4054 EXPECT_THAT(callback.WaitForResult(), IsOk());
4055
4056 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4057 ASSERT_FALSE(http_data.AllReadDataConsumed());
4058
4059 // Read the response body over TCP.
4060 CheckResponseData(&trans, "hello world");
4061 ExpectBrokenAlternateProtocolMapping();
4062 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4063 ASSERT_TRUE(http_data.AllReadDataConsumed());
4064}
4065
Ryan Hamilton6c2a2a82017-12-15 02:06:284066// Verify that when an origin has two alt-svc advertisements, one local and one
4067// remote, that when the local is broken the request will go over QUIC via
4068// the remote Alt-Svc.
4069// This is a regression test for crbug/825646.
4070TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384071 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:284072
4073 GURL origin1 = request_.url; // mail.example.org
4074 GURL origin2("https://www.example.org/");
4075 ASSERT_NE(origin1.host(), origin2.host());
4076
4077 scoped_refptr<X509Certificate> cert(
4078 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244079 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4080 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284081
4082 ProofVerifyDetailsChromium verify_details;
4083 verify_details.cert_verify_result.verified_cert = cert;
4084 verify_details.cert_verify_result.is_issued_by_known_root = true;
4085 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4086
Ryan Hamiltonabad59e2019-06-06 04:02:594087 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234088 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254089 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234090 mock_quic_data.AddWrite(SYNCHRONOUS,
4091 ConstructInitialSettingsPacket(packet_num++));
4092 }
Ryan Hamilton6c2a2a82017-12-15 02:06:284093 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234094 SYNCHRONOUS,
4095 ConstructClientRequestHeadersPacket(
4096 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4097 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434098 mock_quic_data.AddRead(
4099 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334100 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024101 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434102 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434103 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334104 ASYNC, ConstructServerDataPacket(
4105 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174106 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234107 mock_quic_data.AddWrite(SYNCHRONOUS,
4108 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284109 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4110 mock_quic_data.AddRead(ASYNC, 0); // EOF
4111
4112 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594113 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284114 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4115 AddHangingNonAlternateProtocolSocketData();
4116
4117 CreateSession();
4118
4119 // Set up alternative service for |origin1|.
4120 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4121 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4122 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4123 AlternativeServiceInfoVector alternative_services;
4124 alternative_services.push_back(
4125 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4126 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384127 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284128 alternative_services.push_back(
4129 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4130 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384131 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494132 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4133 NetworkIsolationKey(),
4134 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284135
Matt Menkeb32ba5122019-09-10 19:17:054136 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4137 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284138
4139 SendRequestAndExpectQuicResponse("hello!");
4140}
4141
Ryan Hamilton899c2e02019-11-14 01:22:024142// Verify that when multiple alternatives are broken,
4143// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
4144// This is a regression test for crbug/1024613.
4145TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
4146 base::HistogramTester histogram_tester;
4147
4148 MockRead http_reads[] = {
4149 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4150 MockRead("hello world"),
4151 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4152 MockRead(ASYNC, OK)};
4153
4154 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4155 socket_factory_.AddSocketDataProvider(&http_data);
4156 AddCertificate(&ssl_data_);
4157 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4158
4159 GURL origin1 = request_.url; // mail.example.org
4160
4161 scoped_refptr<X509Certificate> cert(
4162 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4163 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4164
4165 ProofVerifyDetailsChromium verify_details;
4166 verify_details.cert_verify_result.verified_cert = cert;
4167 verify_details.cert_verify_result.is_issued_by_known_root = true;
4168 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4169
4170 CreateSession();
4171
4172 // Set up alternative service for |origin1|.
4173 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4174 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4175 AlternativeServiceInfoVector alternative_services;
4176 alternative_services.push_back(
4177 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4178 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384179 context_.params()->supported_versions));
Ryan Hamilton899c2e02019-11-14 01:22:024180 alternative_services.push_back(
4181 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4182 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384183 context_.params()->supported_versions));
Ryan Hamilton899c2e02019-11-14 01:22:024184 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4185 NetworkIsolationKey(),
4186 alternative_services);
4187
4188 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4189 NetworkIsolationKey());
4190
4191 SendRequestAndExpectHttpResponse("hello world");
4192
4193 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4194 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4195}
4196
rch30943ee2017-06-12 21:28:444197// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4198// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054199// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444200// connection instead of going back to the broken QUIC connection.
4201// This is a regression tests for crbug/731303.
4202TEST_P(QuicNetworkTransactionTest,
4203 ResetPooledAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384204 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444205
4206 GURL origin1 = request_.url;
4207 GURL origin2("https://www.example.org/");
4208 ASSERT_NE(origin1.host(), origin2.host());
4209
Ryan Hamiltonabad59e2019-06-06 04:02:594210 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444211
4212 scoped_refptr<X509Certificate> cert(
4213 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244214 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4215 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444216
4217 ProofVerifyDetailsChromium verify_details;
4218 verify_details.cert_verify_result.verified_cert = cert;
4219 verify_details.cert_verify_result.is_issued_by_known_root = true;
4220 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4221
Renjie Tangaadb84b2019-08-31 01:00:234222 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254223 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234224 mock_quic_data.AddWrite(SYNCHRONOUS,
4225 ConstructInitialSettingsPacket(packet_num++));
4226 }
rch30943ee2017-06-12 21:28:444227 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434228 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234229 SYNCHRONOUS,
4230 ConstructClientRequestHeadersPacket(
4231 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4232 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434233 mock_quic_data.AddRead(
4234 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334235 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024236 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434237 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434238 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334239 ASYNC, ConstructServerDataPacket(
4240 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174241 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234242 mock_quic_data.AddWrite(SYNCHRONOUS,
4243 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444244
4245 // Second request will go over the pooled QUIC connection, but will be
4246 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054247 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224248 version_,
4249 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4250 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054251 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174252 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224253 version_,
4254 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4255 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434256 mock_quic_data.AddWrite(
4257 SYNCHRONOUS,
4258 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234259 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4260 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024261 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334262 mock_quic_data.AddRead(
4263 ASYNC, ConstructServerRstPacket(
4264 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4265 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444266 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4267 mock_quic_data.AddRead(ASYNC, 0); // EOF
4268
4269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4270
4271 // After that fails, it will be resent via TCP.
4272 MockWrite http_writes[] = {
4273 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4274 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4275 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4276
4277 MockRead http_reads[] = {
4278 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4279 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4280 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014281 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444282 socket_factory_.AddSocketDataProvider(&http_data);
4283 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4284
Ryan Hamilton6c2a2a82017-12-15 02:06:284285 // Then the next request to the second origin will be sent over TCP.
4286 socket_factory_.AddSocketDataProvider(&http_data);
4287 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444288
4289 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564290 QuicStreamFactoryPeer::SetAlarmFactory(
4291 session_->quic_stream_factory(),
4292 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224293 context_.clock()));
rch30943ee2017-06-12 21:28:444294
4295 // Set up alternative service for |origin1|.
4296 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244297 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494298 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074299 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4300 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444301
4302 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244303 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494304 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074305 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4306 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344307
rch30943ee2017-06-12 21:28:444308 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524309 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444310 SendRequestAndExpectQuicResponse("hello!");
4311
4312 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524313 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054314 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444315 request_.url = origin2;
4316 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054317 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4318 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244319 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054320 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4321 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244322 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444323
Matt Menkeb32ba5122019-09-10 19:17:054324 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444325 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284326 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444327}
4328
bnc8be55ebb2015-10-30 14:12:074329TEST_P(QuicNetworkTransactionTest,
4330 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564331 std::string altsvc_header =
4332 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4333 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074334 MockRead http_reads[] = {
4335 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4336 MockRead("hello world"),
4337 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4338 MockRead(ASYNC, OK)};
4339
Ryan Sleevib8d7ea02018-05-07 20:01:014340 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074341 socket_factory_.AddSocketDataProvider(&http_data);
4342 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4343 socket_factory_.AddSocketDataProvider(&http_data);
4344 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4345
rch3f4b8452016-02-23 16:59:324346 CreateSession();
bnc8be55ebb2015-10-30 14:12:074347
4348 SendRequestAndExpectHttpResponse("hello world");
4349 SendRequestAndExpectHttpResponse("hello world");
4350}
4351
Xida Chen9bfe0b62018-04-24 19:52:214352// When multiple alternative services are advertised, HttpStreamFactory should
4353// select the alternative service which uses existing QUIC session if available.
4354// If no existing QUIC session can be used, use the first alternative service
4355// from the list.
zhongyi32569c62016-01-08 02:54:304356TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:384357 context_.params()->allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524358 MockRead http_reads[] = {
4359 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294360 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524361 MockRead("hello world"),
4362 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4363 MockRead(ASYNC, OK)};
4364
Ryan Sleevib8d7ea02018-05-07 20:01:014365 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524366 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084367 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564368 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524369
zhongyi32569c62016-01-08 02:54:304370 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294371 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304372 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594373 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234374 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254375 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234376 mock_quic_data.AddWrite(SYNCHRONOUS,
4377 ConstructInitialSettingsPacket(packet_num++));
4378 }
rch5cb522462017-04-25 20:18:364379 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234380 SYNCHRONOUS,
4381 ConstructClientRequestHeadersPacket(
4382 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4383 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304384
4385 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294386 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4387 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434388 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024389 ASYNC, ConstructServerResponseHeadersPacket(
4390 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4391 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434392 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434393 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334394 ASYNC, ConstructServerDataPacket(
4395 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174396 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234397 mock_quic_data.AddWrite(SYNCHRONOUS,
4398 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304399
4400 // Second QUIC request data.
4401 // Connection pooling, using existing session, no need to include version
4402 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584403 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234404 SYNCHRONOUS,
4405 ConstructClientRequestHeadersPacket(
4406 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4407 true, GetRequestHeaders("GET", "https", "/"),
4408 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434409 mock_quic_data.AddRead(
4410 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334411 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024412 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434413 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334414 ASYNC, ConstructServerDataPacket(
4415 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174416 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434417 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234418 SYNCHRONOUS,
4419 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524420 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594421 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524422
4423 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4424
rtennetib8e80fb2016-05-16 00:12:094425 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324426 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564427 QuicStreamFactoryPeer::SetAlarmFactory(
4428 session_->quic_stream_factory(),
4429 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224430 context_.clock()));
bncc958faa2015-07-31 18:14:524431
4432 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304433
bnc359ed2a2016-04-29 20:43:454434 SendRequestAndExpectQuicResponse("hello!");
4435 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304436}
4437
tbansal6490783c2016-09-20 17:55:274438// Check that an existing QUIC connection to an alternative proxy server is
4439// used.
4440TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4441 base::HistogramTester histogram_tester;
4442
tbansal6490783c2016-09-20 17:55:274443 // First QUIC request data.
4444 // Open a session to foo.example.org:443 using the first entry of the
4445 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594446 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234447 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254448 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234449 mock_quic_data.AddWrite(SYNCHRONOUS,
4450 ConstructInitialSettingsPacket(packet_num++));
4451 }
rch5cb522462017-04-25 20:18:364452 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234453 SYNCHRONOUS,
4454 ConstructClientRequestHeadersPacket(
4455 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4456 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274457
4458 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434459 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024460 ASYNC, ConstructServerResponseHeadersPacket(
4461 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4462 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434463 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434464 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334465 ASYNC, ConstructServerDataPacket(
4466 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174467 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234468 mock_quic_data.AddWrite(SYNCHRONOUS,
4469 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274470
4471 // Second QUIC request data.
4472 // Connection pooling, using existing session, no need to include version
4473 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274474 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234475 SYNCHRONOUS,
4476 ConstructClientRequestHeadersPacket(
4477 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4478 true, GetRequestHeaders("GET", "http", "/"),
4479 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434480 mock_quic_data.AddRead(
4481 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334482 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024483 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434484 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334485 ASYNC, ConstructServerDataPacket(
4486 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174487 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434488 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234489 SYNCHRONOUS,
4490 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274491 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4492 mock_quic_data.AddRead(ASYNC, 0); // EOF
4493
4494 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4495
4496 AddHangingNonAlternateProtocolSocketData();
4497
4498 TestProxyDelegate test_proxy_delegate;
4499
Lily Houghton8c2f97d2018-01-22 05:06:594500 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494501 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274502
4503 test_proxy_delegate.set_alternative_proxy_server(
4504 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524505 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274506
4507 request_.url = GURL("http://mail.example.org/");
4508
4509 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564510 QuicStreamFactoryPeer::SetAlarmFactory(
4511 session_->quic_stream_factory(),
4512 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224513 context_.clock()));
tbansal6490783c2016-09-20 17:55:274514
4515 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4516 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4517 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4518 1);
4519
4520 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4521 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4522 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4523 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4524 1);
4525}
4526
Ryan Hamilton8d9ee76e2018-05-29 23:52:524527// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454528// even if alternative service destination is different.
4529TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384530 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594531 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454532
Renjie Tangaadb84b2019-08-31 01:00:234533 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254534 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234535 mock_quic_data.AddWrite(SYNCHRONOUS,
4536 ConstructInitialSettingsPacket(packet_num++));
4537 }
bnc359ed2a2016-04-29 20:43:454538 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434539 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234540 SYNCHRONOUS,
4541 ConstructClientRequestHeadersPacket(
4542 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4543 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434544 mock_quic_data.AddRead(
4545 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334546 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024547 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434548 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434549 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334550 ASYNC, ConstructServerDataPacket(
4551 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174552 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234553 mock_quic_data.AddWrite(SYNCHRONOUS,
4554 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304555
bnc359ed2a2016-04-29 20:43:454556 // Second request.
alyssar2adf3ac2016-05-03 17:12:584557 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234558 SYNCHRONOUS,
4559 ConstructClientRequestHeadersPacket(
4560 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4561 true, GetRequestHeaders("GET", "https", "/"),
4562 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434563 mock_quic_data.AddRead(
4564 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334565 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024566 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434567 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334568 ASYNC, ConstructServerDataPacket(
4569 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174570 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434571 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234572 SYNCHRONOUS,
4573 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304574 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4575 mock_quic_data.AddRead(ASYNC, 0); // EOF
4576
4577 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454578
4579 AddHangingNonAlternateProtocolSocketData();
4580 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304581
rch3f4b8452016-02-23 16:59:324582 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564583 QuicStreamFactoryPeer::SetAlarmFactory(
4584 session_->quic_stream_factory(),
4585 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224586 context_.clock()));
zhongyi32569c62016-01-08 02:54:304587
bnc359ed2a2016-04-29 20:43:454588 const char destination1[] = "first.example.com";
4589 const char destination2[] = "second.example.com";
4590
4591 // Set up alternative service entry to destination1.
4592 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214593 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454594 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494595 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074596 server, NetworkIsolationKey(), alternative_service, expiration,
4597 supported_versions_);
bnc359ed2a2016-04-29 20:43:454598 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524599 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454600 SendRequestAndExpectQuicResponse("hello!");
4601
4602 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214603 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494604 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074605 server, NetworkIsolationKey(), alternative_service, expiration,
4606 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524607 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454608 // even though alternative service destination is different.
4609 SendRequestAndExpectQuicResponse("hello!");
4610}
4611
4612// Pool to existing session with matching destination and matching certificate
4613// even if origin is different, and even if the alternative service with
4614// matching destination is not the first one on the list.
4615TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384616 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454617 GURL origin1 = request_.url;
4618 GURL origin2("https://www.example.org/");
4619 ASSERT_NE(origin1.host(), origin2.host());
4620
Ryan Hamiltonabad59e2019-06-06 04:02:594621 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454622
Renjie Tangaadb84b2019-08-31 01:00:234623 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254624 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234625 mock_quic_data.AddWrite(SYNCHRONOUS,
4626 ConstructInitialSettingsPacket(packet_num++));
4627 }
bnc359ed2a2016-04-29 20:43:454628 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434629 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234630 SYNCHRONOUS,
4631 ConstructClientRequestHeadersPacket(
4632 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4633 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434634 mock_quic_data.AddRead(
4635 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334636 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024637 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434638 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434639 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334640 ASYNC, ConstructServerDataPacket(
4641 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174642 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234643 mock_quic_data.AddWrite(SYNCHRONOUS,
4644 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454645
4646 // Second request.
Yixin Wang079ad542018-01-11 04:06:054647 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224648 version_,
4649 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4650 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054651 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174652 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224653 version_,
4654 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4655 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584656 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434657 SYNCHRONOUS,
4658 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234659 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4660 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024661 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434662 mock_quic_data.AddRead(
4663 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334664 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024665 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434666 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334667 ASYNC, ConstructServerDataPacket(
4668 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174669 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434670 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234671 SYNCHRONOUS,
4672 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454673 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4674 mock_quic_data.AddRead(ASYNC, 0); // EOF
4675
4676 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4677
4678 AddHangingNonAlternateProtocolSocketData();
4679 AddHangingNonAlternateProtocolSocketData();
4680
4681 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564682 QuicStreamFactoryPeer::SetAlarmFactory(
4683 session_->quic_stream_factory(),
4684 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224685 context_.clock()));
bnc359ed2a2016-04-29 20:43:454686
4687 const char destination1[] = "first.example.com";
4688 const char destination2[] = "second.example.com";
4689
4690 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214691 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454692 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494693 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074694 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4695 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454696
4697 // Set up multiple alternative service entries for |origin2|,
4698 // the first one with a different destination as for |origin1|,
4699 // the second one with the same. The second one should be used,
4700 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214701 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454702 AlternativeServiceInfoVector alternative_services;
4703 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214704 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4705 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384706 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454707 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214708 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4709 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384710 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494711 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4712 NetworkIsolationKey(),
4713 alternative_services);
bnc359ed2a2016-04-29 20:43:454714 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524715 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454716 SendRequestAndExpectQuicResponse("hello!");
4717
4718 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524719 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454720 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584721
bnc359ed2a2016-04-29 20:43:454722 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304723}
4724
4725// Multiple origins have listed the same alternative services. When there's a
4726// existing QUIC session opened by a request to other origin,
4727// if the cert is valid, should select this QUIC session to make the request
4728// if this is also the first existing QUIC session.
4729TEST_P(QuicNetworkTransactionTest,
4730 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Victor Vasilieva1e66d72019-12-05 17:55:384731 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294732 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304733
rch9ae5b3b2016-02-11 00:36:294734 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304735 MockRead http_reads[] = {
4736 MockRead("HTTP/1.1 200 OK\r\n"),
4737 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294738 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304739 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4740 MockRead(ASYNC, OK)};
4741
Ryan Sleevib8d7ea02018-05-07 20:01:014742 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304743 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084744 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304745 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4746
4747 // HTTP data for request to mail.example.org.
4748 MockRead http_reads2[] = {
4749 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294750 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304751 MockRead("hello world from mail.example.org"),
4752 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4753 MockRead(ASYNC, OK)};
4754
Ryan Sleevib8d7ea02018-05-07 20:01:014755 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304756 socket_factory_.AddSocketDataProvider(&http_data2);
4757 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4758
Yixin Wang079ad542018-01-11 04:06:054759 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224760 version_,
4761 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4762 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054763 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584764 server_maker_.set_hostname("www.example.org");
4765 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594766 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234767 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254768 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234769 mock_quic_data.AddWrite(SYNCHRONOUS,
4770 ConstructInitialSettingsPacket(packet_num++));
4771 }
zhongyi32569c62016-01-08 02:54:304772 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584773 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234774 SYNCHRONOUS,
4775 ConstructClientRequestHeadersPacket(
4776 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4777 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434778
4779 mock_quic_data.AddRead(
4780 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334781 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024782 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434783 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334784 mock_quic_data.AddRead(
4785 ASYNC, ConstructServerDataPacket(
4786 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174787 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234788 mock_quic_data.AddWrite(SYNCHRONOUS,
4789 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434790 // Second QUIC request data.
4791 mock_quic_data.AddWrite(
4792 SYNCHRONOUS,
4793 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234794 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4795 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024796 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434797 mock_quic_data.AddRead(
4798 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334799 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024800 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334801 mock_quic_data.AddRead(
4802 ASYNC, ConstructServerDataPacket(
4803 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174804 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434805 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234806 SYNCHRONOUS,
4807 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304808 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4809 mock_quic_data.AddRead(ASYNC, 0); // EOF
4810
4811 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304812
rtennetib8e80fb2016-05-16 00:12:094813 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324814 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564815 QuicStreamFactoryPeer::SetAlarmFactory(
4816 session_->quic_stream_factory(),
4817 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224818 context_.clock()));
zhongyi32569c62016-01-08 02:54:304819
4820 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294821 request_.url = GURL("https://www.example.org/");
4822 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304823 request_.url = GURL("https://mail.example.org/");
4824 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4825
rch9ae5b3b2016-02-11 00:36:294826 // Open a QUIC session to mail.example.org:443 when making request
4827 // to mail.example.org.
4828 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454829 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304830
rch9ae5b3b2016-02-11 00:36:294831 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304832 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454833 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524834}
4835
4836TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524837 MockRead http_reads[] = {
4838 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564839 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524840 MockRead("hello world"),
4841 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4842 MockRead(ASYNC, OK)};
4843
Ryan Sleevib8d7ea02018-05-07 20:01:014844 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524845 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084846 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564847 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524848
rtennetib8e80fb2016-05-16 00:12:094849 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324850 CreateSession();
bncc958faa2015-07-31 18:14:524851
4852 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454853
4854 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344855 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494856 http_server_properties_->GetAlternativeServiceInfos(
4857 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344858 ASSERT_EQ(1u, alternative_service_info_vector.size());
4859 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544860 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344861 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4862 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4863 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524864}
4865
4866TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524867 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564868 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4869 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524870 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4871 MockRead(ASYNC, OK)};
4872
Ryan Sleevib8d7ea02018-05-07 20:01:014873 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524874 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084875 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564876 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524877
Ryan Hamiltonabad59e2019-06-06 04:02:594878 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234879 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254880 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234881 mock_quic_data.AddWrite(SYNCHRONOUS,
4882 ConstructInitialSettingsPacket(packet_num++));
4883 }
rch5cb522462017-04-25 20:18:364884 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234885 SYNCHRONOUS,
4886 ConstructClientRequestHeadersPacket(
4887 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4888 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434889 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334890 ASYNC, ConstructServerResponseHeadersPacket(
4891 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4892 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434893 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334894 mock_quic_data.AddRead(
4895 ASYNC, ConstructServerDataPacket(
4896 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174897 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234898 mock_quic_data.AddWrite(SYNCHRONOUS,
4899 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524900 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4901 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524902
4903 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4904
rtennetib8e80fb2016-05-16 00:12:094905 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324906 CreateSession();
bncc958faa2015-07-31 18:14:524907
bnc3472afd2016-11-17 15:27:214908 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524909 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494910 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054911 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494912 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054913 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524914
4915 SendRequestAndExpectHttpResponse("hello world");
4916 SendRequestAndExpectQuicResponse("hello!");
4917
mmenkee24011922015-12-17 22:12:594918 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524919
Matt Menke3233d8f22019-08-20 21:01:494920 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054921 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444922 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4923 url::SchemeHostPort("https", request_.url.host(), 443),
4924 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524925}
4926
Matt Menkeb32ba5122019-09-10 19:17:054927TEST_P(QuicNetworkTransactionTest,
4928 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4929 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4930 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4931 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4932 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4933
4934 base::test::ScopedFeatureList feature_list;
4935 feature_list.InitWithFeatures(
4936 // enabled_features
4937 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4938 features::kPartitionConnectionsByNetworkIsolationKey},
4939 // disabled_features
4940 {});
4941 // Since HttpServerProperties caches the feature value, have to create a new
4942 // one.
4943 http_server_properties_ = std::make_unique<HttpServerProperties>();
4944
4945 MockRead http_reads[] = {
4946 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4947 MockRead("hello world"),
4948 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4949 MockRead(ASYNC, OK)};
4950
4951 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4952 socket_factory_.AddSocketDataProvider(&http_data);
4953 AddCertificate(&ssl_data_);
4954 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4955
4956 MockQuicData mock_quic_data(version_);
4957 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254958 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054959 mock_quic_data.AddWrite(SYNCHRONOUS,
4960 ConstructInitialSettingsPacket(packet_num++));
4961 }
4962 mock_quic_data.AddWrite(
4963 SYNCHRONOUS,
4964 ConstructClientRequestHeadersPacket(
4965 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4966 true, GetRequestHeaders("GET", "https", "/")));
4967 mock_quic_data.AddRead(
4968 ASYNC, ConstructServerResponseHeadersPacket(
4969 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4970 GetResponseHeaders("200 OK")));
4971 std::string header = ConstructDataHeader(6);
4972 mock_quic_data.AddRead(
4973 ASYNC, ConstructServerDataPacket(
4974 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4975 header + "hello!"));
4976 mock_quic_data.AddWrite(SYNCHRONOUS,
4977 ConstructClientAckPacket(packet_num++, 2, 1, 1));
4978 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4979 mock_quic_data.AddRead(ASYNC, 0); // EOF
4980
4981 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4982
4983 CreateSession();
4984
4985 AlternativeService alternative_service(kProtoQUIC,
4986 HostPortPair::FromURL(request_.url));
4987 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4988 alternative_service, kNetworkIsolationKey1);
4989 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
4990 alternative_service, kNetworkIsolationKey2);
4991 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4992 alternative_service, kNetworkIsolationKey1));
4993 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
4994 alternative_service, kNetworkIsolationKey2));
4995
4996 request_.network_isolation_key = kNetworkIsolationKey1;
4997 SendRequestAndExpectHttpResponse("hello world");
4998 SendRequestAndExpectQuicResponse("hello!");
4999
5000 mock_quic_data.Resume();
5001
5002 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5003 alternative_service, kNetworkIsolationKey1));
5004 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
5005 url::SchemeHostPort("https", request_.url.host(), 443),
5006 kNetworkIsolationKey1));
5007 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5008 alternative_service, kNetworkIsolationKey2));
5009 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5010 url::SchemeHostPort("https", request_.url.host(), 443),
5011 kNetworkIsolationKey2));
5012}
5013
bncc958faa2015-07-31 18:14:525014TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:525015 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565016 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5017 MockRead("hello world"),
bncc958faa2015-07-31 18:14:525018 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5019 MockRead(ASYNC, OK)};
5020
Ryan Sleevib8d7ea02018-05-07 20:01:015021 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:525022 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565023 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:525024
Ryan Hamiltonabad59e2019-06-06 04:02:595025 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235026 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255027 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235028 mock_quic_data.AddWrite(SYNCHRONOUS,
5029 ConstructInitialSettingsPacket(packet_num++));
5030 }
rch5cb522462017-04-25 20:18:365031 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235032 SYNCHRONOUS,
5033 ConstructClientRequestHeadersPacket(
5034 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5035 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435036 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335037 ASYNC, ConstructServerResponseHeadersPacket(
5038 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5039 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435040 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335041 mock_quic_data.AddRead(
5042 ASYNC, ConstructServerDataPacket(
5043 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175044 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235045 mock_quic_data.AddWrite(SYNCHRONOUS,
5046 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:525047 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
5048
5049 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5050
5051 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325052 CreateSession();
bncc958faa2015-07-31 18:14:525053
5054 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
5055 SendRequestAndExpectHttpResponse("hello world");
5056}
5057
tbansalc3308d72016-08-27 10:25:045058// Tests that the connection to an HTTPS proxy is raced with an available
5059// alternative proxy server.
5060TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:275061 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595062 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495063 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045064
Ryan Hamiltonabad59e2019-06-06 04:02:595065 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235066 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255067 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235068 mock_quic_data.AddWrite(SYNCHRONOUS,
5069 ConstructInitialSettingsPacket(packet_num++));
5070 }
rch5cb522462017-04-25 20:18:365071 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235072 SYNCHRONOUS,
5073 ConstructClientRequestHeadersPacket(
5074 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5075 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435076 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335077 ASYNC, ConstructServerResponseHeadersPacket(
5078 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5079 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435080 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335081 mock_quic_data.AddRead(
5082 ASYNC, ConstructServerDataPacket(
5083 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175084 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235085 mock_quic_data.AddWrite(SYNCHRONOUS,
5086 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:045087 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5088 mock_quic_data.AddRead(ASYNC, 0); // EOF
5089
5090 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5091
5092 // There is no need to set up main job, because no attempt will be made to
5093 // speak to the proxy over TCP.
5094 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:045095 TestProxyDelegate test_proxy_delegate;
5096 const HostPortPair host_port_pair("mail.example.org", 443);
5097
5098 test_proxy_delegate.set_alternative_proxy_server(
5099 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525100 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045101 CreateSession();
5102 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5103
5104 // The main job needs to hang in order to guarantee that the alternative
5105 // proxy server job will "win".
5106 AddHangingNonAlternateProtocolSocketData();
5107
5108 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
5109
5110 // Verify that the alternative proxy server is not marked as broken.
5111 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5112
5113 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595114 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275115
5116 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5117 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5118 1);
tbansalc3308d72016-08-27 10:25:045119}
5120
bnc1c196c6e2016-05-28 13:51:485121TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:305122 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275123 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:305124
5125 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:565126 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:295127 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565128 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:305129
5130 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565131 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485132 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565133 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:305134
Ryan Sleevib8d7ea02018-05-07 20:01:015135 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505136 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:085137 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:505138 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305139
5140 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:455141 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:305142 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:455143 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:305144 };
Ryan Sleevib8d7ea02018-05-07 20:01:015145 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:505146 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:305147
5148 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:015149 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505150 socket_factory_.AddSocketDataProvider(&http_data2);
5151 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305152
bnc912a04b2016-04-20 14:19:505153 CreateSession();
[email protected]dda75ab2013-06-22 22:43:305154
5155 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:305156 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:175157 ASSERT_TRUE(http_data.AllReadDataConsumed());
5158 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305159
5160 // Now run the second request in which the QUIC socket hangs,
5161 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:305162 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455163 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305164
rch37de576c2015-05-17 20:28:175165 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5166 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455167 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305168}
5169
[email protected]1e960032013-12-20 19:00:205170TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435171 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5172 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5173 return;
5174 }
5175
Ryan Hamiltonabad59e2019-06-06 04:02:595176 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035177 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495178 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255179 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495180 mock_quic_data.AddWrite(SYNCHRONOUS,
5181 ConstructInitialSettingsPacket(packet_num++));
5182 }
Zhongyi Shi32f2fd02018-04-16 18:23:435183 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495184 SYNCHRONOUS,
5185 ConstructClientRequestHeadersPacket(
5186 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5187 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435188 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335189 ASYNC, ConstructServerResponseHeadersPacket(
5190 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5191 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435192 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335193 mock_quic_data.AddRead(
5194 ASYNC, ConstructServerDataPacket(
5195 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175196 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495197 mock_quic_data.AddWrite(SYNCHRONOUS,
5198 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505199 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595200 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485201
rcha5399e02015-04-21 19:32:045202 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485203
rtennetib8e80fb2016-05-16 00:12:095204 // The non-alternate protocol job needs to hang in order to guarantee that
5205 // the alternate-protocol job will "win".
5206 AddHangingNonAlternateProtocolSocketData();
5207
rch3f4b8452016-02-23 16:59:325208 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275209 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195210 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305211
Matt Menke19475f72019-08-21 18:57:445212 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5213 url::SchemeHostPort("https", request_.url.host(), 443),
5214 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485215}
5216
[email protected]1e960032013-12-20 19:00:205217TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435218 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5219 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5220 return;
5221 }
5222
Ryan Hamiltonabad59e2019-06-06 04:02:595223 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035224 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495225 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255226 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495227 mock_quic_data.AddWrite(
5228 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5229 }
Fan Yang32c5a112018-12-10 20:06:335230 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495231 SYNCHRONOUS,
5232 ConstructClientRequestHeadersPacket(
5233 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5234 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435235 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335236 ASYNC, ConstructServerResponseHeadersPacket(
5237 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5238 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435239 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335240 mock_quic_data.AddRead(
5241 ASYNC, ConstructServerDataPacket(
5242 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175243 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495244 mock_quic_data.AddWrite(SYNCHRONOUS,
5245 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505246 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595247 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045248 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275249
5250 // In order for a new QUIC session to be established via alternate-protocol
5251 // without racing an HTTP connection, we need the host resolution to happen
5252 // synchronously.
5253 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295254 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565255 "");
[email protected]3a120a6b2013-06-25 01:08:275256
rtennetib8e80fb2016-05-16 00:12:095257 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325258 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275259 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275260 SendRequestAndExpectQuicResponse("hello!");
5261}
5262
[email protected]0fc924b2014-03-31 04:34:155263TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495264 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5265 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155266
5267 // Since we are using a proxy, the QUIC job will not succeed.
5268 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295269 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5270 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565271 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155272
5273 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565274 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485275 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565276 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155277
Ryan Sleevib8d7ea02018-05-07 20:01:015278 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155279 socket_factory_.AddSocketDataProvider(&http_data);
5280
5281 // In order for a new QUIC session to be established via alternate-protocol
5282 // without racing an HTTP connection, we need the host resolution to happen
5283 // synchronously.
5284 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295285 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565286 "");
[email protected]0fc924b2014-03-31 04:34:155287
rch9ae5b3b2016-02-11 00:36:295288 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325289 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275290 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155291 SendRequestAndExpectHttpResponse("hello world");
5292}
5293
[email protected]1e960032013-12-20 19:00:205294TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435295 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5296 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5297 return;
5298 }
5299
Ryan Hamiltonabad59e2019-06-06 04:02:595300 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235301 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495302 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255303 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235304 mock_quic_data.AddWrite(SYNCHRONOUS,
5305 ConstructInitialSettingsPacket(packet_num++));
5306 }
Nick Harper057264a82019-09-12 23:33:495307 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365308 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235309 SYNCHRONOUS,
5310 ConstructClientRequestHeadersPacket(
5311 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5312 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435313 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335314 ASYNC, ConstructServerResponseHeadersPacket(
5315 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5316 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435317 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335318 mock_quic_data.AddRead(
5319 ASYNC, ConstructServerDataPacket(
5320 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175321 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235322 mock_quic_data.AddWrite(SYNCHRONOUS,
5323 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595324 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045325 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125326
rtennetib8e80fb2016-05-16 00:12:095327 // The non-alternate protocol job needs to hang in order to guarantee that
5328 // the alternate-protocol job will "win".
5329 AddHangingNonAlternateProtocolSocketData();
5330
[email protected]11c05872013-08-20 02:04:125331 // In order for a new QUIC session to be established via alternate-protocol
5332 // without racing an HTTP connection, we need the host resolution to happen
5333 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5334 // connection to the the server, in this test we require confirmation
5335 // before encrypting so the HTTP job will still start.
5336 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295337 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565338 "");
[email protected]11c05872013-08-20 02:04:125339
rch3f4b8452016-02-23 16:59:325340 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435341 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5342 false);
Ryan Hamilton9835e662018-08-02 05:36:275343 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125344
bnc691fda62016-08-12 00:43:165345 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125346 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365347 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125349
5350 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525351 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015352 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505353
bnc691fda62016-08-12 00:43:165354 CheckWasQuicResponse(&trans);
5355 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125356}
5357
Steven Valdez58097ec32018-07-16 18:29:045358TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435359 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5360 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5361 return;
5362 }
5363
Ryan Hamilton3cc2c152019-07-09 19:36:015364 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595365 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035366 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255367 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495368 mock_quic_data.AddWrite(
5369 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5370 }
Steven Valdez58097ec32018-07-16 18:29:045371 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015372 SYNCHRONOUS,
5373 ConstructClientRequestHeadersPacket(
5374 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5375 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335376 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025377 ASYNC, ConstructServerResponseHeadersPacket(
5378 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5379 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015380 mock_quic_data.AddWrite(
5381 SYNCHRONOUS,
5382 ConstructClientAckAndRstPacket(
5383 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5384 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045385
5386 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5387
Steven Valdez58097ec32018-07-16 18:29:045388 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015389 SYNCHRONOUS,
5390 ConstructClientRequestHeadersPacket(
5391 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5392 true, GetRequestHeaders("GET", "https", "/"),
5393 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045394 mock_quic_data.AddRead(
5395 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335396 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025397 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435398 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045399 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335400 ASYNC, ConstructServerDataPacket(
5401 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175402 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045403 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015404 SYNCHRONOUS,
5405 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045406 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5407 mock_quic_data.AddRead(ASYNC, 0); // EOF
5408
5409 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5410
5411 // In order for a new QUIC session to be established via alternate-protocol
5412 // without racing an HTTP connection, we need the host resolution to happen
5413 // synchronously.
5414 host_resolver_.set_synchronous_mode(true);
5415 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5416 "");
Steven Valdez58097ec32018-07-16 18:29:045417
5418 AddHangingNonAlternateProtocolSocketData();
5419 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275420 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565421 QuicStreamFactoryPeer::SetAlarmFactory(
5422 session_->quic_stream_factory(),
5423 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225424 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045425
5426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5427 TestCompletionCallback callback;
5428 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5429 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5430
5431 // Confirm the handshake after the 425 Too Early.
5432 base::RunLoop().RunUntilIdle();
5433
5434 // The handshake hasn't been confirmed yet, so the retry should not have
5435 // succeeded.
5436 EXPECT_FALSE(callback.have_result());
5437
5438 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5439 quic::QuicSession::HANDSHAKE_CONFIRMED);
5440
5441 EXPECT_THAT(callback.WaitForResult(), IsOk());
5442 CheckWasQuicResponse(&trans);
5443 CheckResponseData(&trans, "hello!");
5444}
5445
5446TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435447 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5448 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5449 return;
5450 }
5451
Ryan Hamilton3cc2c152019-07-09 19:36:015452 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595453 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035454 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255455 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495456 mock_quic_data.AddWrite(
5457 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5458 }
Steven Valdez58097ec32018-07-16 18:29:045459 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015460 SYNCHRONOUS,
5461 ConstructClientRequestHeadersPacket(
5462 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5463 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335464 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025465 ASYNC, ConstructServerResponseHeadersPacket(
5466 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5467 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015468 mock_quic_data.AddWrite(
5469 SYNCHRONOUS,
5470 ConstructClientAckAndRstPacket(
5471 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5472 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045473
5474 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5475
Steven Valdez58097ec32018-07-16 18:29:045476 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015477 SYNCHRONOUS,
5478 ConstructClientRequestHeadersPacket(
5479 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5480 true, GetRequestHeaders("GET", "https", "/"),
5481 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335482 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025483 ASYNC, ConstructServerResponseHeadersPacket(
5484 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5485 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015486 mock_quic_data.AddWrite(
5487 SYNCHRONOUS,
5488 ConstructClientAckAndRstPacket(
5489 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5490 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045491 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5492 mock_quic_data.AddRead(ASYNC, 0); // EOF
5493
5494 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5495
5496 // In order for a new QUIC session to be established via alternate-protocol
5497 // without racing an HTTP connection, we need the host resolution to happen
5498 // synchronously.
5499 host_resolver_.set_synchronous_mode(true);
5500 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5501 "");
Steven Valdez58097ec32018-07-16 18:29:045502
5503 AddHangingNonAlternateProtocolSocketData();
5504 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275505 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565506 QuicStreamFactoryPeer::SetAlarmFactory(
5507 session_->quic_stream_factory(),
5508 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225509 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045510
5511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5512 TestCompletionCallback callback;
5513 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5515
5516 // Confirm the handshake after the 425 Too Early.
5517 base::RunLoop().RunUntilIdle();
5518
5519 // The handshake hasn't been confirmed yet, so the retry should not have
5520 // succeeded.
5521 EXPECT_FALSE(callback.have_result());
5522
5523 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5524 quic::QuicSession::HANDSHAKE_CONFIRMED);
5525
5526 EXPECT_THAT(callback.WaitForResult(), IsOk());
5527 const HttpResponseInfo* response = trans.GetResponseInfo();
5528 ASSERT_TRUE(response != nullptr);
5529 ASSERT_TRUE(response->headers.get() != nullptr);
5530 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5531 EXPECT_TRUE(response->was_fetched_via_spdy);
5532 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085533 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5534 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045535}
5536
zhongyica364fbb2015-12-12 03:39:125537TEST_P(QuicNetworkTransactionTest,
5538 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435539 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5540 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5541 return;
5542 }
5543
Victor Vasilieva1e66d72019-12-05 17:55:385544 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595545 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235546 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495547 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255548 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235549 mock_quic_data.AddWrite(SYNCHRONOUS,
5550 ConstructInitialSettingsPacket(packet_num++));
5551 }
Nick Harper057264a82019-09-12 23:33:495552 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365553 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235554 SYNCHRONOUS,
5555 ConstructClientRequestHeadersPacket(
5556 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5557 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125558 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525559 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435560 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125561 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5562
5563 // The non-alternate protocol job needs to hang in order to guarantee that
5564 // the alternate-protocol job will "win".
5565 AddHangingNonAlternateProtocolSocketData();
5566
5567 // In order for a new QUIC session to be established via alternate-protocol
5568 // without racing an HTTP connection, we need the host resolution to happen
5569 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5570 // connection to the the server, in this test we require confirmation
5571 // before encrypting so the HTTP job will still start.
5572 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295573 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125574 "");
zhongyica364fbb2015-12-12 03:39:125575
rch3f4b8452016-02-23 16:59:325576 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435577 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5578 false);
Ryan Hamilton9835e662018-08-02 05:36:275579 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125580
bnc691fda62016-08-12 00:43:165581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125582 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365583 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125585
5586 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525587 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015588 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125589
5590 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525591 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125592
bnc691fda62016-08-12 00:43:165593 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125594 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525595 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5596 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125597}
5598
5599TEST_P(QuicNetworkTransactionTest,
5600 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435601 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5602 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5603 return;
5604 }
5605
Victor Vasilieva1e66d72019-12-05 17:55:385606 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595607 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235608 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495609 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255610 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235611 mock_quic_data.AddWrite(SYNCHRONOUS,
5612 ConstructInitialSettingsPacket(packet_num++));
5613 }
Nick Harper057264a82019-09-12 23:33:495614 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365615 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235616 SYNCHRONOUS,
5617 ConstructClientRequestHeadersPacket(
5618 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5619 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215620 // Peer sending data from an non-existing stream causes this end to raise
5621 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335622 mock_quic_data.AddRead(
5623 ASYNC, ConstructServerRstPacket(
5624 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5625 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215626 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375627 mock_quic_data.AddWrite(
5628 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5629 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5630 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
5631 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125632 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5633
5634 // The non-alternate protocol job needs to hang in order to guarantee that
5635 // the alternate-protocol job will "win".
5636 AddHangingNonAlternateProtocolSocketData();
5637
5638 // In order for a new QUIC session to be established via alternate-protocol
5639 // without racing an HTTP connection, we need the host resolution to happen
5640 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5641 // connection to the the server, in this test we require confirmation
5642 // before encrypting so the HTTP job will still start.
5643 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295644 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125645 "");
zhongyica364fbb2015-12-12 03:39:125646
rch3f4b8452016-02-23 16:59:325647 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435648 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5649 false);
Ryan Hamilton9835e662018-08-02 05:36:275650 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125651
bnc691fda62016-08-12 00:43:165652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125653 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365654 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125656
5657 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525658 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015659 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125660 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525661 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125662
bnc691fda62016-08-12 00:43:165663 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525664 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125665}
5666
Nick Harper057264a82019-09-12 23:33:495667TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435668 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5669 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5670 return;
5671 }
5672
Ryan Hamiltonabad59e2019-06-06 04:02:595673 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235674 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495675 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255676 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235677 mock_quic_data.AddWrite(SYNCHRONOUS,
5678 ConstructInitialSettingsPacket(packet_num++));
5679 }
Nick Harper057264a82019-09-12 23:33:495680 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365681 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235682 SYNCHRONOUS,
5683 ConstructClientRequestHeadersPacket(
5684 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5685 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485686 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335687 mock_quic_data.AddRead(
5688 ASYNC, ConstructServerResponseHeadersPacket(
5689 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5690 GetResponseHeaders("200 OK")));
5691 mock_quic_data.AddRead(
5692 ASYNC, ConstructServerRstPacket(
5693 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5694 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:235695 mock_quic_data.AddWrite(SYNCHRONOUS,
5696 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485697 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5698 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5699
5700 // The non-alternate protocol job needs to hang in order to guarantee that
5701 // the alternate-protocol job will "win".
5702 AddHangingNonAlternateProtocolSocketData();
5703
5704 // In order for a new QUIC session to be established via alternate-protocol
5705 // without racing an HTTP connection, we need the host resolution to happen
5706 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5707 // connection to the the server, in this test we require confirmation
5708 // before encrypting so the HTTP job will still start.
5709 host_resolver_.set_synchronous_mode(true);
5710 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5711 "");
rchcd5f1c62016-06-23 02:43:485712
5713 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435714 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5715 false);
Ryan Hamilton9835e662018-08-02 05:36:275716 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485717
bnc691fda62016-08-12 00:43:165718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485719 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365720 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485722
5723 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525724 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485725 // Read the headers.
robpercival214763f2016-07-01 23:27:015726 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485727
bnc691fda62016-08-12 00:43:165728 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485729 ASSERT_TRUE(response != nullptr);
5730 ASSERT_TRUE(response->headers.get() != nullptr);
5731 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5732 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525733 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085734 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5735 response->connection_info);
rchcd5f1c62016-06-23 02:43:485736
5737 std::string response_data;
bnc691fda62016-08-12 00:43:165738 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485739}
5740
Nick Harper057264a82019-09-12 23:33:495741TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435742 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5743 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5744 return;
5745 }
5746
Victor Vasilieva1e66d72019-12-05 17:55:385747 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595748 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235749 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495750 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255751 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235752 mock_quic_data.AddWrite(SYNCHRONOUS,
5753 ConstructInitialSettingsPacket(packet_num++));
5754 }
Nick Harper057264a82019-09-12 23:33:495755 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365756 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235757 SYNCHRONOUS,
5758 ConstructClientRequestHeadersPacket(
5759 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5760 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335761 mock_quic_data.AddRead(
5762 ASYNC, ConstructServerRstPacket(
5763 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5764 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485765 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5766 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5767
5768 // The non-alternate protocol job needs to hang in order to guarantee that
5769 // the alternate-protocol job will "win".
5770 AddHangingNonAlternateProtocolSocketData();
5771
5772 // In order for a new QUIC session to be established via alternate-protocol
5773 // without racing an HTTP connection, we need the host resolution to happen
5774 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5775 // connection to the the server, in this test we require confirmation
5776 // before encrypting so the HTTP job will still start.
5777 host_resolver_.set_synchronous_mode(true);
5778 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5779 "");
rchcd5f1c62016-06-23 02:43:485780
5781 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435782 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5783 false);
Ryan Hamilton9835e662018-08-02 05:36:275784 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485785
bnc691fda62016-08-12 00:43:165786 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485787 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365788 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015789 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485790
5791 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525792 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485793 // Read the headers.
robpercival214763f2016-07-01 23:27:015794 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485795}
5796
[email protected]1e960032013-12-20 19:00:205797TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305798 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525799 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585800 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305801 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505802 MockRead(ASYNC, close->data(), close->length()),
5803 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5804 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305805 };
Ryan Sleevib8d7ea02018-05-07 20:01:015806 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305807 socket_factory_.AddSocketDataProvider(&quic_data);
5808
5809 // Main job which will succeed even though the alternate job fails.
5810 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025811 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5812 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5813 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305814
Ryan Sleevib8d7ea02018-05-07 20:01:015815 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305816 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565817 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305818
rch3f4b8452016-02-23 16:59:325819 CreateSession();
David Schinazic8281052019-01-24 06:14:175820 AddQuicAlternateProtocolMapping(
5821 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195822 SendRequestAndExpectHttpResponse("hello from http");
5823 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305824}
5825
Matt Menkeb32ba5122019-09-10 19:17:055826TEST_P(QuicNetworkTransactionTest,
5827 BrokenAlternateProtocolWithNetworkIsolationKey) {
5828 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5829 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5830 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5831 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5832
5833 base::test::ScopedFeatureList feature_list;
5834 feature_list.InitWithFeatures(
5835 // enabled_features
5836 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5837 features::kPartitionConnectionsByNetworkIsolationKey},
5838 // disabled_features
5839 {});
5840 // Since HttpServerProperties caches the feature value, have to create a new
5841 // one.
5842 http_server_properties_ = std::make_unique<HttpServerProperties>();
5843
5844 // Alternate-protocol job
5845 std::unique_ptr<quic::QuicEncryptedPacket> close(
5846 ConstructServerConnectionClosePacket(1));
5847 MockRead quic_reads[] = {
5848 MockRead(ASYNC, close->data(), close->length()),
5849 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5850 MockRead(ASYNC, OK), // EOF
5851 };
5852 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5853 socket_factory_.AddSocketDataProvider(&quic_data);
5854
5855 // Main job which will succeed even though the alternate job fails.
5856 MockRead http_reads[] = {
5857 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5858 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5859 MockRead(ASYNC, OK)};
5860
5861 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5862 socket_factory_.AddSocketDataProvider(&http_data);
5863 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5864
5865 CreateSession();
5866 AddQuicAlternateProtocolMapping(
5867 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5868 AddQuicAlternateProtocolMapping(
5869 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5870 request_.network_isolation_key = kNetworkIsolationKey1;
5871 SendRequestAndExpectHttpResponse("hello from http");
5872
5873 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5874 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5875}
5876
[email protected]1e960032013-12-20 19:00:205877TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595878 // Alternate-protocol job
5879 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025880 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595881 };
Ryan Sleevib8d7ea02018-05-07 20:01:015882 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595883 socket_factory_.AddSocketDataProvider(&quic_data);
5884
5885 // Main job which will succeed even though the alternate job fails.
5886 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025887 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5888 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5889 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595890
Ryan Sleevib8d7ea02018-05-07 20:01:015891 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595892 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565893 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595894
rch3f4b8452016-02-23 16:59:325895 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595896
Ryan Hamilton9835e662018-08-02 05:36:275897 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195898 SendRequestAndExpectHttpResponse("hello from http");
5899 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595900}
5901
[email protected]00c159f2014-05-21 22:38:165902TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535903 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165904 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025905 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165906 };
Ryan Sleevib8d7ea02018-05-07 20:01:015907 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165908 socket_factory_.AddSocketDataProvider(&quic_data);
5909
[email protected]eb71ab62014-05-23 07:57:535910 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165911 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025912 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165913 };
5914
Ryan Sleevib8d7ea02018-05-07 20:01:015915 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165916 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5917 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565918 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165919
rtennetib8e80fb2016-05-16 00:12:095920 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325921 CreateSession();
[email protected]00c159f2014-05-21 22:38:165922
Ryan Hamilton9835e662018-08-02 05:36:275923 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165925 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165926 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5928 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165929 ExpectQuicAlternateProtocolMapping();
5930}
5931
Zhongyi Shia0cef1082017-08-25 01:49:505932TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435933 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5934 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5935 return;
5936 }
5937
Zhongyi Shia0cef1082017-08-25 01:49:505938 // Tests that TCP job is delayed and QUIC job does not require confirmation
5939 // if QUIC was recently supported on the same IP on start.
5940
5941 // Set QUIC support on the last IP address, which is same with the local IP
5942 // address. Require confirmation mode will be turned off immediately when
5943 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435944 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5945 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505946
Ryan Hamiltonabad59e2019-06-06 04:02:595947 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035948 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495949 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255950 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495951 mock_quic_data.AddWrite(SYNCHRONOUS,
5952 ConstructInitialSettingsPacket(packet_number++));
5953 }
Zhongyi Shi32f2fd02018-04-16 18:23:435954 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495955 SYNCHRONOUS,
5956 ConstructClientRequestHeadersPacket(
5957 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5958 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435959 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335960 ASYNC, ConstructServerResponseHeadersPacket(
5961 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5962 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435963 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335964 mock_quic_data.AddRead(
5965 ASYNC, ConstructServerDataPacket(
5966 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175967 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495968 mock_quic_data.AddWrite(SYNCHRONOUS,
5969 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505970 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5971 mock_quic_data.AddRead(ASYNC, 0); // EOF
5972
5973 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5974 // No HTTP data is mocked as TCP job never starts in this case.
5975
5976 CreateSession();
5977 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:435978 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5979 false);
Zhongyi Shia0cef1082017-08-25 01:49:505980
Ryan Hamilton9835e662018-08-02 05:36:275981 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505982
5983 // Stall host resolution so that QUIC job will not succeed synchronously.
5984 // Socket will not be configured immediately and QUIC support is not sorted
5985 // out, TCP job will still be delayed as server properties indicates QUIC
5986 // support on last IP address.
5987 host_resolver_.set_synchronous_mode(false);
5988
5989 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5990 TestCompletionCallback callback;
5991 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5992 IsError(ERR_IO_PENDING));
5993 // Complete host resolution in next message loop so that QUIC job could
5994 // proceed.
5995 base::RunLoop().RunUntilIdle();
5996 EXPECT_THAT(callback.WaitForResult(), IsOk());
5997
5998 CheckWasQuicResponse(&trans);
5999 CheckResponseData(&trans, "hello!");
6000}
6001
6002TEST_P(QuicNetworkTransactionTest,
6003 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436004 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6005 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6006 return;
6007 }
6008
Zhongyi Shia0cef1082017-08-25 01:49:506009 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
6010 // was recently supported on a different IP address on start.
6011
6012 // Set QUIC support on the last IP address, which is different with the local
6013 // IP address. Require confirmation mode will remain when local IP address is
6014 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436015 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6016 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:506017
Ryan Hamiltonabad59e2019-06-06 04:02:596018 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236019 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:496020 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:256021 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236022 mock_quic_data.AddWrite(SYNCHRONOUS,
6023 ConstructInitialSettingsPacket(packet_num++));
6024 }
Nick Harper057264a82019-09-12 23:33:496025 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:506026 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236027 SYNCHRONOUS,
6028 ConstructClientRequestHeadersPacket(
6029 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6030 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436031 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336032 ASYNC, ConstructServerResponseHeadersPacket(
6033 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6034 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436035 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336036 mock_quic_data.AddRead(
6037 ASYNC, ConstructServerDataPacket(
6038 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176039 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236040 mock_quic_data.AddWrite(SYNCHRONOUS,
6041 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506042 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6043 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6044 // No HTTP data is mocked as TCP job will be delayed and never starts.
6045
6046 CreateSession();
Matt Menkeb566c392019-09-11 23:22:436047 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6048 false);
Ryan Hamilton9835e662018-08-02 05:36:276049 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506050
6051 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
6052 // Socket will not be configured immediately and QUIC support is not sorted
6053 // out, TCP job will still be delayed as server properties indicates QUIC
6054 // support on last IP address.
6055 host_resolver_.set_synchronous_mode(false);
6056
6057 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6058 TestCompletionCallback callback;
6059 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6060 IsError(ERR_IO_PENDING));
6061
6062 // Complete host resolution in next message loop so that QUIC job could
6063 // proceed.
6064 base::RunLoop().RunUntilIdle();
6065 // Explicitly confirm the handshake so that QUIC job could succeed.
6066 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526067 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:506068 EXPECT_THAT(callback.WaitForResult(), IsOk());
6069
6070 CheckWasQuicResponse(&trans);
6071 CheckResponseData(&trans, "hello!");
6072}
6073
Ryan Hamilton75f197262017-08-17 14:00:076074TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
6075 // Test that NetErrorDetails is correctly populated, even if the
6076 // handshake has not yet been confirmed and no stream has been created.
6077
6078 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:596079 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:076080 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6081 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
6082 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6083
6084 // Main job will also fail.
6085 MockRead http_reads[] = {
6086 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6087 };
6088
Ryan Sleevib8d7ea02018-05-07 20:01:016089 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:076090 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6091 socket_factory_.AddSocketDataProvider(&http_data);
6092 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6093
6094 AddHangingNonAlternateProtocolSocketData();
6095 CreateSession();
6096 // Require handshake confirmation to ensure that no QUIC streams are
6097 // created, and to ensure that the TCP job does not wait for the QUIC
6098 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:436099 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6100 false);
Ryan Hamilton75f197262017-08-17 14:00:076101
Ryan Hamilton9835e662018-08-02 05:36:276102 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:076103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6104 TestCompletionCallback callback;
6105 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6107 // Allow the TCP job to fail.
6108 base::RunLoop().RunUntilIdle();
6109 // Now let the QUIC job fail.
6110 mock_quic_data.Resume();
6111 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6112 ExpectQuicAlternateProtocolMapping();
6113 NetErrorDetails details;
6114 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526115 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:076116}
6117
[email protected]1e960032013-12-20 19:00:206118TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:456119 // Alternate-protocol job
6120 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:026121 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:456122 };
Ryan Sleevib8d7ea02018-05-07 20:01:016123 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:456124 socket_factory_.AddSocketDataProvider(&quic_data);
6125
[email protected]c92c1b52014-05-31 04:16:066126 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:016127 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:066128 socket_factory_.AddSocketDataProvider(&quic_data2);
6129
[email protected]4d283b32013-10-17 12:57:276130 // Final job that will proceed when the QUIC job fails.
6131 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026132 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6133 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6134 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:276135
Ryan Sleevib8d7ea02018-05-07 20:01:016136 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:276137 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566138 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:276139
rch3f4b8452016-02-23 16:59:326140 CreateSession();
[email protected]77c6c162013-08-17 02:57:456141
Ryan Hamilton9835e662018-08-02 05:36:276142 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:456143
[email protected]4d283b32013-10-17 12:57:276144 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:456145
6146 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:276147
rch37de576c2015-05-17 20:28:176148 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6149 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:456150}
6151
Matt Menkeb32ba5122019-09-10 19:17:056152TEST_P(QuicNetworkTransactionTest,
6153 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436154 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6155 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6156 return;
6157 }
6158
Matt Menkeb32ba5122019-09-10 19:17:056159 base::test::ScopedFeatureList feature_list;
6160 feature_list.InitWithFeatures(
6161 // enabled_features
6162 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
6163 features::kPartitionConnectionsByNetworkIsolationKey},
6164 // disabled_features
6165 {});
6166 // Since HttpServerProperties caches the feature value, have to create a new
6167 // one.
6168 http_server_properties_ = std::make_unique<HttpServerProperties>();
6169
6170 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
6171 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
6172 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
6173 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
6174
6175 // Alternate-protocol job
6176 MockRead quic_reads[] = {
6177 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6178 };
6179 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
6180 socket_factory_.AddSocketDataProvider(&quic_data);
6181
6182 // Second Alternate-protocol job which will race with the TCP job.
6183 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
6184 socket_factory_.AddSocketDataProvider(&quic_data2);
6185
6186 // Final job that will proceed when the QUIC job fails.
6187 MockRead http_reads[] = {
6188 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6189 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6190 MockRead(ASYNC, OK)};
6191
6192 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6193 socket_factory_.AddSocketDataProvider(&http_data);
6194 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6195
6196 CreateSession();
6197
6198 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6199 kNetworkIsolationKey1);
6200 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6201 kNetworkIsolationKey2);
6202
6203 request_.network_isolation_key = kNetworkIsolationKey1;
6204 SendRequestAndExpectHttpResponse("hello from http");
6205 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6206 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6207
6208 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6209 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6210
6211 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6212 AddHttpDataAndRunRequest();
6213 // Requests using other NetworkIsolationKeys can still use QUIC.
6214 request_.network_isolation_key = kNetworkIsolationKey2;
6215 AddQuicDataAndRunRequest();
6216
6217 // The last two requests should not have changed the alternative service
6218 // mappings.
6219 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6220 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6221}
6222
[email protected]93b31772014-06-19 08:03:356223TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036224 // Alternate-protocol job
6225 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596226 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036227 };
Ryan Sleevib8d7ea02018-05-07 20:01:016228 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036229 socket_factory_.AddSocketDataProvider(&quic_data);
6230
6231 // Main job that will proceed when the QUIC job fails.
6232 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026233 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6234 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6235 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036236
Ryan Sleevib8d7ea02018-05-07 20:01:016237 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036238 socket_factory_.AddSocketDataProvider(&http_data);
6239
rtennetib8e80fb2016-05-16 00:12:096240 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326241 CreateSession();
[email protected]65768442014-06-06 23:37:036242
Ryan Hamilton9835e662018-08-02 05:36:276243 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036244
6245 SendRequestAndExpectHttpResponse("hello from http");
6246}
6247
[email protected]eb71ab62014-05-23 07:57:536248TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336249 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016250 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496251 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336252 socket_factory_.AddSocketDataProvider(&quic_data);
6253
6254 // Main job which will succeed even though the alternate job fails.
6255 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026256 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6257 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6258 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336259
Ryan Sleevib8d7ea02018-05-07 20:01:016260 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336261 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566262 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336263
rch3f4b8452016-02-23 16:59:326264 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276265 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336266 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536267
6268 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336269}
6270
[email protected]4fee9672014-01-08 14:47:156271TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:596272 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176273 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6274 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046275 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156276
6277 // When the QUIC connection fails, we will try the request again over HTTP.
6278 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486279 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566280 MockRead("hello world"),
6281 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6282 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156283
Ryan Sleevib8d7ea02018-05-07 20:01:016284 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156285 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566286 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156287
6288 // In order for a new QUIC session to be established via alternate-protocol
6289 // without racing an HTTP connection, we need the host resolution to happen
6290 // synchronously.
6291 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296292 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566293 "");
[email protected]4fee9672014-01-08 14:47:156294
rch3f4b8452016-02-23 16:59:326295 CreateSession();
David Schinazic8281052019-01-24 06:14:176296 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6297 AddQuicAlternateProtocolMapping(
6298 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156299 SendRequestAndExpectHttpResponse("hello world");
6300}
6301
tbansalc3308d72016-08-27 10:25:046302// For an alternative proxy that supports QUIC, test that the request is
6303// successfully fetched by the main job when the alternate proxy job encounters
6304// an error.
6305TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6306 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6307}
6308TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6309 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6310}
6311TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6312 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6313}
6314TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6315 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6316}
6317TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6318 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6319}
6320TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6321 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6322}
6323TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6324 TestAlternativeProxy(ERR_IO_PENDING);
6325}
6326TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6327 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6328}
6329
6330TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596331 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176332 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6333 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336334 mock_quic_data.AddWrite(
6335 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6336 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6337 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436338 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046339 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6340
6341 // When the QUIC connection fails, we will try the request again over HTTP.
6342 MockRead http_reads[] = {
6343 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6344 MockRead("hello world"),
6345 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6346 MockRead(ASYNC, OK)};
6347
Ryan Sleevib8d7ea02018-05-07 20:01:016348 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046349 socket_factory_.AddSocketDataProvider(&http_data);
6350 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6351
6352 TestProxyDelegate test_proxy_delegate;
6353 const HostPortPair host_port_pair("myproxy.org", 443);
6354 test_proxy_delegate.set_alternative_proxy_server(
6355 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6356 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6357
Ramin Halavatica8d5252018-03-12 05:33:496358 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6359 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526360 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046361 request_.url = GURL("http://mail.example.org/");
6362
6363 // In order for a new QUIC session to be established via alternate-protocol
6364 // without racing an HTTP connection, we need the host resolution to happen
6365 // synchronously.
6366 host_resolver_.set_synchronous_mode(true);
6367 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046368
6369 CreateSession();
David Schinazic8281052019-01-24 06:14:176370 crypto_client_stream_factory_.set_handshake_mode(
6371 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046372 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596373 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166374 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046375}
6376
bnc508835902015-05-12 20:10:296377TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586378 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386379 EXPECT_FALSE(
6380 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596381 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236382 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256383 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236384 mock_quic_data.AddWrite(SYNCHRONOUS,
6385 ConstructInitialSettingsPacket(packet_num++));
6386 }
rch5cb522462017-04-25 20:18:366387 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236388 SYNCHRONOUS,
6389 ConstructClientRequestHeadersPacket(
6390 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6391 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436392 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336393 ASYNC, ConstructServerResponseHeadersPacket(
6394 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6395 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436396 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336397 mock_quic_data.AddRead(
6398 ASYNC, ConstructServerDataPacket(
6399 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176400 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236401 mock_quic_data.AddWrite(SYNCHRONOUS,
6402 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506403 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296404 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6405
bncb07c05532015-05-14 19:07:206406 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096407 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326408 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276409 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296410 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386411 EXPECT_TRUE(
6412 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296413}
6414
zhongyi363c91c2017-03-23 23:16:086415// TODO(zhongyi): disabled this broken test as it was not testing the correct
6416// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6417TEST_P(QuicNetworkTransactionTest,
6418 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276419 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596420 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496421 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046422
6423 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046424
6425 test_proxy_delegate.set_alternative_proxy_server(
6426 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526427 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046428
6429 request_.url = GURL("http://mail.example.org/");
6430
6431 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6432 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016433 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046434 socket_factory_.AddSocketDataProvider(&socket_data);
6435
6436 // The non-alternate protocol job needs to hang in order to guarantee that
6437 // the alternate-protocol job will "win".
6438 AddHangingNonAlternateProtocolSocketData();
6439
6440 CreateSession();
6441 request_.method = "POST";
6442 ChunkedUploadDataStream upload_data(0);
6443 upload_data.AppendData("1", 1, true);
6444
6445 request_.upload_data_stream = &upload_data;
6446
6447 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6448 TestCompletionCallback callback;
6449 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6450 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6451 EXPECT_NE(OK, callback.WaitForResult());
6452
6453 // Verify that the alternative proxy server is not marked as broken.
6454 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6455
6456 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596457 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276458
6459 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6460 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6461 1);
tbansalc3308d72016-08-27 10:25:046462}
6463
rtenneti56977812016-01-15 19:26:566464TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386465 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576466 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566467
Renjie Tangaadb84b2019-08-31 01:00:236468 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256469 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236470 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6471 else
6472 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6473 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6474 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6475
6476 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6477 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6478 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016479 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236480 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566481
rtennetib8e80fb2016-05-16 00:12:096482 // The non-alternate protocol job needs to hang in order to guarantee that
6483 // the alternate-protocol job will "win".
6484 AddHangingNonAlternateProtocolSocketData();
6485
rtenneti56977812016-01-15 19:26:566486 CreateSession();
6487 request_.method = "POST";
6488 ChunkedUploadDataStream upload_data(0);
6489 upload_data.AppendData("1", 1, true);
6490
6491 request_.upload_data_stream = &upload_data;
6492
bnc691fda62016-08-12 00:43:166493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566494 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166495 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016496 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566497 EXPECT_NE(OK, callback.WaitForResult());
6498}
6499
rche11300ef2016-09-02 01:44:286500TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386501 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286502 ScopedMockNetworkChangeNotifier network_change_notifier;
6503 MockNetworkChangeNotifier* mock_ncn =
6504 network_change_notifier.mock_network_change_notifier();
6505 mock_ncn->ForceNetworkHandlesSupported();
6506 mock_ncn->SetConnectedNetworksList(
6507 {kDefaultNetworkForTests, kNewNetworkForTests});
6508
Victor Vasilieva1e66d72019-12-05 17:55:386509 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286510 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386511 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286512
Ryan Hamiltonabad59e2019-06-06 04:02:596513 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286514 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236515 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256516 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236517 socket_data.AddWrite(SYNCHRONOUS,
6518 ConstructInitialSettingsPacket(packet_num++));
6519 }
Fan Yang32c5a112018-12-10 20:06:336520 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236521 SYNCHRONOUS,
6522 ConstructClientRequestHeadersPacket(
6523 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6524 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286525 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6526 socket_data.AddSocketDataToFactory(&socket_factory_);
6527
Ryan Hamiltonabad59e2019-06-06 04:02:596528 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286529 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6530 socket_data2.AddSocketDataToFactory(&socket_factory_);
6531
6532 // The non-alternate protocol job needs to hang in order to guarantee that
6533 // the alternate-protocol job will "win".
6534 AddHangingNonAlternateProtocolSocketData();
6535
6536 CreateSession();
6537 request_.method = "POST";
6538 ChunkedUploadDataStream upload_data(0);
6539
6540 request_.upload_data_stream = &upload_data;
6541
rdsmith1d343be52016-10-21 20:37:506542 std::unique_ptr<HttpNetworkTransaction> trans(
6543 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286544 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506545 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286546 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6547
6548 base::RunLoop().RunUntilIdle();
6549 upload_data.AppendData("1", 1, true);
6550 base::RunLoop().RunUntilIdle();
6551
6552 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506553 trans.reset();
rche11300ef2016-09-02 01:44:286554 session_.reset();
6555}
6556
Ryan Hamilton4b3574532017-10-30 20:17:256557TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386558 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256559 HostPortPair::FromString("mail.example.org:443"));
6560
Ryan Hamiltonabad59e2019-06-06 04:02:596561 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236562 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256563 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236564 socket_data.AddWrite(SYNCHRONOUS,
6565 ConstructInitialSettingsPacket(packet_num++));
6566 }
Ryan Hamilton4b3574532017-10-30 20:17:256567 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336568 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236569 SYNCHRONOUS,
6570 ConstructClientRequestHeadersPacket(
6571 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6572 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436573 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336574 ASYNC, ConstructServerResponseHeadersPacket(
6575 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6576 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436577 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336578 socket_data.AddRead(
6579 ASYNC, ConstructServerDataPacket(
6580 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176581 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236582 socket_data.AddWrite(SYNCHRONOUS,
6583 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256584 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436585 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6586 // TLS1.3 supports multiple packet number space, so the ack is no longer
6587 // sent.
6588 socket_data.AddWrite(
6589 SYNCHRONOUS,
6590 client_maker_.MakeConnectionClosePacket(
6591 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6592 } else {
6593 socket_data.AddWrite(
6594 SYNCHRONOUS,
6595 client_maker_.MakeAckAndConnectionClosePacket(
6596 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6597 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6598 }
Ryan Hamilton4b3574532017-10-30 20:17:256599
6600 socket_data.AddSocketDataToFactory(&socket_factory_);
6601
6602 CreateSession();
6603
6604 SendRequestAndExpectQuicResponse("hello!");
6605 session_.reset();
6606}
6607
6608TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386609 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256610 HostPortPair::FromString("mail.example.org:443"));
6611
Ryan Hamiltonabad59e2019-06-06 04:02:596612 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236613 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256614 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236615 socket_data.AddWrite(SYNCHRONOUS,
6616 ConstructInitialSettingsPacket(packet_num++));
6617 }
Ryan Hamilton4b3574532017-10-30 20:17:256618 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336619 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236620 SYNCHRONOUS,
6621 ConstructClientRequestHeadersPacket(
6622 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6623 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436624 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336625 ASYNC, ConstructServerResponseHeadersPacket(
6626 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6627 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436628 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336629 socket_data.AddRead(
6630 ASYNC, ConstructServerDataPacket(
6631 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176632 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236633 socket_data.AddWrite(SYNCHRONOUS,
6634 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256635 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436636 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6637 // TLS1.3 supports multiple packet number space, so the ack is no longer
6638 // sent.
6639 socket_data.AddWrite(
6640 SYNCHRONOUS,
6641 client_maker_.MakeConnectionClosePacket(
6642 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6643 } else {
6644 socket_data.AddWrite(
6645 SYNCHRONOUS,
6646 client_maker_.MakeAckAndConnectionClosePacket(
6647 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6648 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6649 }
Ryan Hamilton4b3574532017-10-30 20:17:256650
6651 socket_data.AddSocketDataToFactory(&socket_factory_);
6652
6653 CreateSession();
6654
6655 SendRequestAndExpectQuicResponse("hello!");
6656 session_.reset();
6657}
6658
Ryan Hamilton9edcf1a2017-11-22 05:55:176659TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386660 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6661 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256662 HostPortPair::FromString("mail.example.org:443"));
6663
Ryan Hamiltonabad59e2019-06-06 04:02:596664 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256665 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256666 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236667 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176668 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256669 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6670 }
6671 socket_data.AddSocketDataToFactory(&socket_factory_);
6672
6673 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176674 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176675 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6676 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256677
Victor Vasiliev7752898d2019-11-14 21:30:226678 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256679 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6680 TestCompletionCallback callback;
6681 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6682 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176683 while (!callback.have_result()) {
6684 base::RunLoop().RunUntilIdle();
6685 quic_task_runner_->RunUntilIdle();
6686 }
6687 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256688 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176689 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6690 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6691 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226692 EXPECT_TRUE(context_.clock()->Now() - start >
6693 quic::QuicTime::Delta::FromSeconds(4));
6694 EXPECT_TRUE(context_.clock()->Now() - start <
6695 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256696}
6697
Ryan Hamilton9edcf1a2017-11-22 05:55:176698TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386699 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6700 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256701 HostPortPair::FromString("mail.example.org:443"));
6702
Ryan Hamiltonabad59e2019-06-06 04:02:596703 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256704 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256705 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236706 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176707 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256708 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6709 }
6710 socket_data.AddSocketDataToFactory(&socket_factory_);
6711
6712 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176713 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176714 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6715 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256716
Victor Vasiliev7752898d2019-11-14 21:30:226717 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6719 TestCompletionCallback callback;
6720 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176722 while (!callback.have_result()) {
6723 base::RunLoop().RunUntilIdle();
6724 quic_task_runner_->RunUntilIdle();
6725 }
6726 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256727 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176728 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6729 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6730 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226731 EXPECT_TRUE(context_.clock()->Now() - start >
6732 quic::QuicTime::Delta::FromSeconds(4));
6733 EXPECT_TRUE(context_.clock()->Now() - start <
6734 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256735}
6736
Cherie Shi7596de632018-02-22 07:28:186737TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386738 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6739 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186740 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436741 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526742 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6743 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186744
Ryan Hamiltonabad59e2019-06-06 04:02:596745 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186746 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236747 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256748 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236749 socket_data.AddWrite(SYNCHRONOUS,
6750 ConstructInitialSettingsPacket(packet_num++));
6751 }
Cherie Shi7596de632018-02-22 07:28:186752 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6753 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526754 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236755 SYNCHRONOUS,
6756 client_maker_.MakeConnectionClosePacket(
6757 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186758 socket_data.AddSocketDataToFactory(&socket_factory_);
6759
6760 CreateSession();
6761
6762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6763 TestCompletionCallback callback;
6764 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6765 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6766 base::RunLoop().RunUntilIdle();
6767 ASSERT_TRUE(callback.have_result());
6768 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6769 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6770 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6771}
6772
ckrasic769733c2016-06-30 00:42:136773// Adds coverage to catch regression such as https://crbug.com/622043
6774TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Ryan Hamilton6c6493102019-12-05 21:36:506775 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6776 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386777 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136778 HostPortPair::FromString("mail.example.org:443"));
6779
Ryan Hamiltonabad59e2019-06-06 04:02:596780 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236781 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256782 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236783 mock_quic_data.AddWrite(
6784 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6785 }
Zhongyi Shi32f2fd02018-04-16 18:23:436786 mock_quic_data.AddWrite(
6787 SYNCHRONOUS,
6788 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336789 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026790 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436791 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026792 ASYNC,
6793 ConstructServerPushPromisePacket(
6794 1, GetNthClientInitiatedBidirectionalStreamId(0),
6795 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6796 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316797 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426798 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256799 !VersionUsesHttp3(version_.transport_version)) ||
6800 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426801 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026802 mock_quic_data.AddWrite(
6803 SYNCHRONOUS,
6804 ConstructClientPriorityPacket(
6805 client_packet_number++, false,
6806 GetNthServerInitiatedUnidirectionalStreamId(0),
6807 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576808 }
Zhongyi Shi32f2fd02018-04-16 18:23:436809 mock_quic_data.AddRead(
6810 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336811 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026812 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576813 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436814 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6815 mock_quic_data.AddRead(
6816 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336817 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026818 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436819 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436820 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336821 ASYNC, ConstructServerDataPacket(
6822 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176823 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576824 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436825 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436826 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436827 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336828 ASYNC, ConstructServerDataPacket(
6829 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176830 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336831 mock_quic_data.AddWrite(SYNCHRONOUS,
6832 ConstructClientAckAndRstPacket(
6833 client_packet_number++,
6834 GetNthServerInitiatedUnidirectionalStreamId(0),
6835 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136836 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6837 mock_quic_data.AddRead(ASYNC, 0); // EOF
6838 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6839
6840 // The non-alternate protocol job needs to hang in order to guarantee that
6841 // the alternate-protocol job will "win".
6842 AddHangingNonAlternateProtocolSocketData();
6843
6844 CreateSession();
6845
6846 // PUSH_PROMISE handling in the http layer gets exercised here.
6847 SendRequestAndExpectQuicResponse("hello!");
6848
6849 request_.url = GURL("https://mail.example.org/pushed.jpg");
6850 SendRequestAndExpectQuicResponse("and hello!");
6851
6852 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546853 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136854 EXPECT_LT(0u, entries.size());
6855
6856 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6857 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006858 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6859 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136860 EXPECT_LT(0, pos);
6861}
6862
rch56ec40a2017-06-23 14:48:446863// Regression test for http://crbug.com/719461 in which a promised stream
6864// is closed before the pushed headers arrive, but after the connection
6865// is closed and before the callbacks are executed.
6866TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamilton6c6493102019-12-05 21:36:506867 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6868 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386869 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6870 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446871 HostPortPair::FromString("mail.example.org:443"));
6872
Ryan Hamiltonabad59e2019-06-06 04:02:596873 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236874 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446875 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256876 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236877 mock_quic_data.AddWrite(
6878 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6879 }
rch56ec40a2017-06-23 14:48:446880 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436881 mock_quic_data.AddWrite(
6882 SYNCHRONOUS,
6883 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336884 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026885 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446886 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436887 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026888 ASYNC,
6889 ConstructServerPushPromisePacket(
6890 1, GetNthClientInitiatedBidirectionalStreamId(0),
6891 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6892 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316893 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426894 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256895 !VersionUsesHttp3(version_.transport_version)) ||
6896 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426897 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026898 mock_quic_data.AddWrite(
6899 SYNCHRONOUS,
6900 ConstructClientPriorityPacket(
6901 client_packet_number++, false,
6902 GetNthServerInitiatedUnidirectionalStreamId(0),
6903 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576904 }
rch56ec40a2017-06-23 14:48:446905 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436906 mock_quic_data.AddRead(
6907 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336908 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026909 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:446910 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576911 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436912 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446913 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436914 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436915 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336916 ASYNC, ConstructServerDataPacket(
6917 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176918 header + "hello!"));
rch56ec40a2017-06-23 14:48:446919 // Write error for the third request.
6920 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6921 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6922 mock_quic_data.AddRead(ASYNC, 0); // EOF
6923 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6924
6925 CreateSession();
6926
6927 // Send a request which triggers a push promise from the server.
6928 SendRequestAndExpectQuicResponse("hello!");
6929
6930 // Start a push transaction that will be cancelled after the connection
6931 // is closed, but before the callback is executed.
6932 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196933 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446934 session_.get());
6935 TestCompletionCallback callback2;
6936 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6938 base::RunLoop().RunUntilIdle();
6939
6940 // Cause the connection to close on a write error.
6941 HttpRequestInfo request3;
6942 request3.method = "GET";
6943 request3.url = GURL("https://mail.example.org/");
6944 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106945 request3.traffic_annotation =
6946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446947 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6948 TestCompletionCallback callback3;
6949 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6950 IsError(ERR_IO_PENDING));
6951
6952 base::RunLoop().RunUntilIdle();
6953
6954 // When |trans2| is destroyed, the underlying stream will be closed.
6955 EXPECT_FALSE(callback2.have_result());
6956 trans2 = nullptr;
6957
6958 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6959}
6960
ckrasicda193a82016-07-09 00:39:366961TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:386962 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366963 HostPortPair::FromString("mail.example.org:443"));
6964
Ryan Hamiltonabad59e2019-06-06 04:02:596965 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366966
Renjief49758b2019-01-11 23:32:416967 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:256968 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236969 mock_quic_data.AddWrite(
6970 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
6971 }
ckrasicda193a82016-07-09 00:39:366972
Victor Vasiliev076657c2019-03-12 02:46:436973 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566974 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416975 mock_quic_data.AddWrite(
6976 SYNCHRONOUS,
6977 ConstructClientRequestHeadersAndDataFramesPacket(
6978 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6979 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026980 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:416981 } else {
6982 mock_quic_data.AddWrite(
6983 SYNCHRONOUS,
6984 ConstructClientRequestHeadersAndDataFramesPacket(
6985 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6986 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:026987 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:416988 {header, "1"}));
6989 }
ckrasicda193a82016-07-09 00:39:366990
Zhongyi Shi32f2fd02018-04-16 18:23:436991 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336992 ASYNC, ConstructServerResponseHeadersPacket(
6993 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6994 GetResponseHeaders("200 OK")));
6995
Victor Vasiliev076657c2019-03-12 02:46:436996 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336997 mock_quic_data.AddRead(
6998 ASYNC, ConstructServerDataPacket(
6999 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177000 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:367001
Renjief49758b2019-01-11 23:32:417002 mock_quic_data.AddWrite(
7003 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:367004
7005 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7006 mock_quic_data.AddRead(ASYNC, 0); // EOF
7007 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7008
7009 // The non-alternate protocol job needs to hang in order to guarantee that
7010 // the alternate-protocol job will "win".
7011 AddHangingNonAlternateProtocolSocketData();
7012
7013 CreateSession();
7014 request_.method = "POST";
7015 ChunkedUploadDataStream upload_data(0);
7016 upload_data.AppendData("1", 1, true);
7017
7018 request_.upload_data_stream = &upload_data;
7019
7020 SendRequestAndExpectQuicResponse("hello!");
7021}
7022
allada71b2efb2016-09-09 04:57:487023class QuicURLRequestContext : public URLRequestContext {
7024 public:
7025 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
7026 MockClientSocketFactory* socket_factory)
7027 : storage_(this) {
7028 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:077029 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:047030 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:487031 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:047032 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:597033 storage_.set_proxy_resolution_service(
7034 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:077035 storage_.set_ssl_config_service(
7036 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:487037 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:117038 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:487039 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:267040 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:047041 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:487042 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:047043 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
7044 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
7045 false));
allada71b2efb2016-09-09 04:57:487046 }
7047
7048 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
7049
7050 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
7051
7052 private:
7053 MockClientSocketFactory* socket_factory_;
7054 URLRequestContextStorage storage_;
7055};
7056
7057TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Victor Vasilieva1e66d72019-12-05 17:55:387058 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487059 HostPortPair::FromString("mail.example.org:443"));
7060
Ryan Hamiltonabad59e2019-06-06 04:02:597061 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237062 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257063 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237064 mock_quic_data.AddWrite(SYNCHRONOUS,
7065 ConstructInitialSettingsPacket(packet_num++));
7066 }
Ryan Hamilton0239aac2018-05-19 00:03:137067 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487068 headers["user-agent"] = "";
7069 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:337070 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237071 SYNCHRONOUS,
7072 ConstructClientRequestHeadersPacket(
7073 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7074 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487075
Fan Yang32c5a112018-12-10 20:06:337076 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027077 ASYNC, ConstructServerResponseHeadersPacket(
7078 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7079 GetResponseHeaders("200 OK")));
7080 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457081 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257082 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457083 ? GetNthClientInitiatedBidirectionalStreamId(0)
7084 : quic::QuicUtils::GetHeadersStreamId(
7085 version_.transport_version));
allada71b2efb2016-09-09 04:57:487086
Victor Vasiliev076657c2019-03-12 02:46:437087 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367088 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337089 ASYNC, ConstructServerDataPacket(
7090 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177091 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:237092 mock_quic_data.AddWrite(SYNCHRONOUS,
7093 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487094
7095 mock_quic_data.AddRead(ASYNC, 0); // EOF
7096
7097 CreateSession();
7098
7099 TestDelegate delegate;
7100 QuicURLRequestContext quic_url_request_context(std::move(session_),
7101 &socket_factory_);
7102
7103 mock_quic_data.AddSocketDataToFactory(
7104 &quic_url_request_context.socket_factory());
7105 TestNetworkDelegate network_delegate;
7106 quic_url_request_context.set_network_delegate(&network_delegate);
7107
7108 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297109 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7110 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487111 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7112 &ssl_data_);
7113
7114 request->Start();
Wez2a31b222018-06-07 22:07:157115 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487116
7117 EXPECT_LT(0, request->GetTotalSentBytes());
7118 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:487119 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
7120 request->raw_header_size());
Wez0e717112018-06-18 23:09:227121
7122 // Pump the message loop to allow all data to be consumed.
7123 base::RunLoop().RunUntilIdle();
7124
allada71b2efb2016-09-09 04:57:487125 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7126 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7127}
7128
7129TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Ryan Hamilton6c6493102019-12-05 21:36:507130 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7131 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387132 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487133 HostPortPair::FromString("mail.example.org:443"));
7134
Ryan Hamiltonabad59e2019-06-06 04:02:597135 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237136 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257137 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237138 mock_quic_data.AddWrite(
7139 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7140 }
Ryan Hamilton0239aac2018-05-19 00:03:137141 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487142 headers["user-agent"] = "";
7143 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:437144 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337145 SYNCHRONOUS,
7146 ConstructClientRequestHeadersPacket(
7147 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027148 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487149
Fan Yang2330d182019-08-05 14:50:507150 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
7151 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:437152 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027153 ASYNC,
7154 ConstructServerPushPromisePacket(
7155 1, GetNthClientInitiatedBidirectionalStreamId(0),
7156 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7157 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:507158 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:257159 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:507160 push_promise_offset = server_maker_.stream_offset(
7161 GetNthClientInitiatedBidirectionalStreamId(0)) -
7162 initial;
7163 }
allada71b2efb2016-09-09 04:57:487164
Renjie Tang703fea92019-07-23 21:08:317165 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427166 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:257167 !VersionUsesHttp3(version_.transport_version)) ||
7168 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:427169 (FLAGS_quic_allow_http3_priority))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027170 mock_quic_data.AddWrite(
7171 SYNCHRONOUS,
7172 ConstructClientPriorityPacket(
7173 client_packet_number++, false,
7174 GetNthServerInitiatedUnidirectionalStreamId(0),
7175 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577176 }
7177
Ryan Hamiltone940bd12019-06-30 02:46:457178 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257179 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457180 ? GetNthClientInitiatedBidirectionalStreamId(0)
7181 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:437182 mock_quic_data.AddRead(
7183 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337184 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027185 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:457186 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257187 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457188 ? GetNthClientInitiatedBidirectionalStreamId(0)
7189 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:027190 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457191 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:487192
Yixin Wangb470bc882018-02-15 18:43:577193 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437194 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487195
ckrasicbf2f59c2017-05-04 23:54:367196 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437197 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337198 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027199 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437200 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:437201 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337202 ASYNC, ConstructServerDataPacket(
7203 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177204 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:487205
Yixin Wangb470bc882018-02-15 18:43:577206 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437207 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:437208 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367209 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337210 ASYNC, ConstructServerDataPacket(
7211 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177212 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:487213
Zhongyi Shi32f2fd02018-04-16 18:23:437214 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:487215
7216 CreateSession();
7217
7218 TestDelegate delegate;
7219 QuicURLRequestContext quic_url_request_context(std::move(session_),
7220 &socket_factory_);
7221
7222 mock_quic_data.AddSocketDataToFactory(
7223 &quic_url_request_context.socket_factory());
7224 TestNetworkDelegate network_delegate;
7225 quic_url_request_context.set_network_delegate(&network_delegate);
7226
7227 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297228 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7229 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487230 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7231 &ssl_data_);
7232
7233 request->Start();
Wez2a31b222018-06-07 22:07:157234 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487235
7236 EXPECT_LT(0, request->GetTotalSentBytes());
7237 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:507238 EXPECT_EQ(
7239 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
7240 request->raw_header_size());
Wez0e717112018-06-18 23:09:227241
7242 // Pump the message loop to allow all data to be consumed.
7243 base::RunLoop().RunUntilIdle();
7244
allada71b2efb2016-09-09 04:57:487245 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7246 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7247}
7248
Ryan Sleevia9d6aa62019-07-26 13:32:187249TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
7250 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:207251
7252 MockRead http_reads[] = {
7253 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7254 MockRead("hello world"),
7255 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7256 MockRead(ASYNC, OK)};
7257
Ryan Sleevib8d7ea02018-05-07 20:01:017258 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207259 socket_factory_.AddSocketDataProvider(&http_data);
7260 AddCertificate(&ssl_data_);
7261 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7262
Ryan Hamiltonabad59e2019-06-06 04:02:597263 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237264 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257265 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237266 mock_quic_data.AddWrite(SYNCHRONOUS,
7267 ConstructInitialSettingsPacket(packet_num++));
7268 }
Yixin Wang10f477ed2017-11-21 04:20:207269 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237270 SYNCHRONOUS,
7271 ConstructClientRequestHeadersPacket(
7272 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7273 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437274 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337275 ASYNC, ConstructServerResponseHeadersPacket(
7276 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7277 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437278 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337279 mock_quic_data.AddRead(
7280 ASYNC, ConstructServerDataPacket(
7281 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177282 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237283 mock_quic_data.AddWrite(SYNCHRONOUS,
7284 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207285 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7286 mock_quic_data.AddRead(ASYNC, 0); // EOF
7287
7288 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7289
7290 AddHangingNonAlternateProtocolSocketData();
7291 CreateSession();
7292
7293 SendRequestAndExpectHttpResponse("hello world");
7294 SendRequestAndExpectQuicResponse("hello!");
7295}
7296
Ryan Sleevia9d6aa62019-07-26 13:32:187297TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7298 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207299
7300 MockRead http_reads[] = {
7301 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7302 MockRead("hello world"),
7303 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7304 MockRead(ASYNC, OK)};
7305
Ryan Sleevib8d7ea02018-05-07 20:01:017306 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207307 socket_factory_.AddSocketDataProvider(&http_data);
7308 AddCertificate(&ssl_data_);
7309 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7310 socket_factory_.AddSocketDataProvider(&http_data);
7311 AddCertificate(&ssl_data_);
7312 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7313
7314 AddHangingNonAlternateProtocolSocketData();
7315 CreateSession();
7316
7317 SendRequestAndExpectHttpResponse("hello world");
7318 SendRequestAndExpectHttpResponse("hello world");
7319}
7320
bnc359ed2a2016-04-29 20:43:457321class QuicNetworkTransactionWithDestinationTest
7322 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017323 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057324 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457325 protected:
7326 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557327 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057328 client_headers_include_h2_stream_dependency_(
7329 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567330 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457331 destination_type_(GetParam().destination_type),
7332 cert_transparency_verifier_(new MultiLogCTVerifier()),
7333 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:597334 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117335 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:457336 ssl_data_(ASYNC, OK) {}
7337
7338 void SetUp() override {
7339 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557340 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457341
mmenke6ddfbea2017-05-31 21:48:417342 HttpNetworkSession::Params session_params;
7343 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387344 context_.params()->allow_remote_alt_svc = true;
7345 context_.params()->supported_versions = supported_versions_;
7346 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057347 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417348
7349 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457350
Victor Vasiliev7752898d2019-11-14 21:30:227351 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457352
7353 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277354 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417355 session_context.quic_crypto_client_stream_factory =
7356 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457357
Victor Vasiliev7752898d2019-11-14 21:30:227358 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417359 session_context.client_socket_factory = &socket_factory_;
7360 session_context.host_resolver = &host_resolver_;
7361 session_context.cert_verifier = &cert_verifier_;
7362 session_context.transport_security_state = &transport_security_state_;
7363 session_context.cert_transparency_verifier =
7364 cert_transparency_verifier_.get();
7365 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7366 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457367 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417368 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597369 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417370 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7371 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457372
mmenke6ddfbea2017-05-31 21:48:417373 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437374 session_->quic_stream_factory()
7375 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457376 }
7377
7378 void TearDown() override {
7379 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7380 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557381 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457382 PlatformTest::TearDown();
7383 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557384 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407385 session_.reset();
bnc359ed2a2016-04-29 20:43:457386 }
7387
zhongyie537a002017-06-27 16:48:217388 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457389 HostPortPair destination;
7390 switch (destination_type_) {
7391 case SAME_AS_FIRST:
7392 destination = HostPortPair(origin1_, 443);
7393 break;
7394 case SAME_AS_SECOND:
7395 destination = HostPortPair(origin2_, 443);
7396 break;
7397 case DIFFERENT:
7398 destination = HostPortPair(kDifferentHostname, 443);
7399 break;
7400 }
bnc3472afd2016-11-17 15:27:217401 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457402 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217403 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077404 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7405 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457406 }
7407
Ryan Hamilton8d9ee76e2018-05-29 23:52:527408 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237409 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527410 quic::QuicStreamId stream_id,
7411 bool should_include_version,
7412 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527413 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137414 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457415 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137416 spdy::SpdyHeaderBlock headers(
7417 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027418 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457419 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027420 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457421 }
7422
Ryan Hamilton8d9ee76e2018-05-29 23:52:527423 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237424 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527425 quic::QuicStreamId stream_id,
7426 bool should_include_version,
7427 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587428 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027429 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457430 }
7431
Ryan Hamilton8d9ee76e2018-05-29 23:52:527432 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237433 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527434 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527435 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137436 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027437 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7438 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457439 }
7440
Ryan Hamilton8d9ee76e2018-05-29 23:52:527441 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237442 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527443 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457444 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437445 std::string header = "";
Nick Harper23290b82019-05-02 00:02:567446 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417447 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:577448 auto header_length =
7449 quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437450 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417451 }
Ryan Hamilton7505eb92019-06-08 00:22:177452 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417453 header + "hello");
bnc359ed2a2016-04-29 20:43:457454 }
7455
Ryan Hamilton8d9ee76e2018-05-29 23:52:527456 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237457 uint64_t packet_number,
7458 uint64_t largest_received,
7459 uint64_t smallest_received,
7460 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457461 QuicTestPacketMaker* maker) {
7462 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497463 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457464 }
7465
Ryan Hamilton8d9ee76e2018-05-29 23:52:527466 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237467 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377468 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027469 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377470 }
7471
bnc359ed2a2016-04-29 20:43:457472 void AddRefusedSocketData() {
7473 std::unique_ptr<StaticSocketDataProvider> refused_data(
7474 new StaticSocketDataProvider());
7475 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7476 refused_data->set_connect_data(refused_connect);
7477 socket_factory_.AddSocketDataProvider(refused_data.get());
7478 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7479 }
7480
7481 void AddHangingSocketData() {
7482 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7483 new StaticSocketDataProvider());
7484 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7485 hanging_data->set_connect_data(hanging_connect);
7486 socket_factory_.AddSocketDataProvider(hanging_data.get());
7487 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7488 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7489 }
7490
7491 bool AllDataConsumed() {
7492 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7493 if (!socket_data_ptr->AllReadDataConsumed() ||
7494 !socket_data_ptr->AllWriteDataConsumed()) {
7495 return false;
7496 }
7497 }
7498 return true;
7499 }
7500
7501 void SendRequestAndExpectQuicResponse(const std::string& host) {
7502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7503 HttpRequestInfo request;
7504 std::string url("https://");
7505 url.append(host);
7506 request.url = GURL(url);
7507 request.load_flags = 0;
7508 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107509 request.traffic_annotation =
7510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457511 TestCompletionCallback callback;
7512 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017513 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457514
7515 std::string response_data;
robpercival214763f2016-07-01 23:27:017516 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457517 EXPECT_EQ("hello", response_data);
7518
7519 const HttpResponseInfo* response = trans.GetResponseInfo();
7520 ASSERT_TRUE(response != nullptr);
7521 ASSERT_TRUE(response->headers.get() != nullptr);
7522 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7523 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527524 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087525 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457526 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377527 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457528 }
7529
Fan Yang32c5a112018-12-10 20:06:337530 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567531 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7532 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367533 }
7534
Nick Harper23290b82019-05-02 00:02:567535 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057536 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567537 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457538 DestinationType destination_type_;
7539 std::string origin1_;
7540 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227541 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457542 std::unique_ptr<HttpNetworkSession> session_;
7543 MockClientSocketFactory socket_factory_;
7544 MockHostResolver host_resolver_;
7545 MockCertVerifier cert_verifier_;
7546 TransportSecurityState transport_security_state_;
7547 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237548 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457549 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077550 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597551 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457552 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267553 HttpServerProperties http_server_properties_;
Matt Muellerd9342e3a2019-11-26 01:41:147554 RecordingBoundTestNetLog net_log_;
bnc359ed2a2016-04-29 20:43:457555 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7556 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7557 static_socket_data_provider_vector_;
7558 SSLSocketDataProvider ssl_data_;
7559};
7560
Victor Costane635086f2019-01-27 05:20:307561INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7562 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577563 ::testing::ValuesIn(GetPoolingTestParams()),
7564 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457565
7566// A single QUIC request fails because the certificate does not match the origin
7567// hostname, regardless of whether it matches the alternative service hostname.
7568TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7569 if (destination_type_ == DIFFERENT)
7570 return;
7571
7572 GURL url("https://mail.example.com/");
7573 origin1_ = url.host();
7574
7575 // Not used for requests, but this provides a test case where the certificate
7576 // is valid for the hostname of the alternative service.
7577 origin2_ = "mail.example.org";
7578
zhongyie537a002017-06-27 16:48:217579 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457580
7581 scoped_refptr<X509Certificate> cert(
7582 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247583 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7584 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457585
7586 ProofVerifyDetailsChromium verify_details;
7587 verify_details.cert_verify_result.verified_cert = cert;
7588 verify_details.cert_verify_result.is_issued_by_known_root = true;
7589 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7590
Ryan Hamiltonabad59e2019-06-06 04:02:597591 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457592 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7593 mock_quic_data.AddRead(ASYNC, 0);
7594
7595 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7596
7597 AddRefusedSocketData();
7598
7599 HttpRequestInfo request;
7600 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107601 request.traffic_annotation =
7602 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457603
7604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7605 TestCompletionCallback callback;
7606 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017607 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457608
7609 EXPECT_TRUE(AllDataConsumed());
7610}
7611
7612// First request opens QUIC session to alternative service. Second request
7613// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527614// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457615TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7616 origin1_ = "mail.example.org";
7617 origin2_ = "news.example.org";
7618
zhongyie537a002017-06-27 16:48:217619 SetQuicAlternativeService(origin1_);
7620 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457621
7622 scoped_refptr<X509Certificate> cert(
7623 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247624 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7625 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7626 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457627
7628 ProofVerifyDetailsChromium verify_details;
7629 verify_details.cert_verify_result.verified_cert = cert;
7630 verify_details.cert_verify_result.is_issued_by_known_root = true;
7631 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7632
Yixin Wang079ad542018-01-11 04:06:057633 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227634 version_,
7635 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7636 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057637 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177638 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227639 version_,
7640 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7641 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457642
Ryan Hamiltonabad59e2019-06-06 04:02:597643 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237644 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257645 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237646 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7647 packet_num++, &client_maker));
7648 }
Fan Yang32c5a112018-12-10 20:06:337649 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237650 SYNCHRONOUS,
7651 ConstructClientRequestHeadersPacket(
7652 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7653 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027654 mock_quic_data.AddRead(
7655 ASYNC,
7656 ConstructServerResponseHeadersPacket(
7657 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437658 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337659 ASYNC,
7660 ConstructServerDataPacket(
7661 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237662 mock_quic_data.AddWrite(
7663 SYNCHRONOUS,
7664 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457665
Yixin Wang079ad542018-01-11 04:06:057666 client_maker.set_hostname(origin2_);
7667 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457668
Zhongyi Shi32f2fd02018-04-16 18:23:437669 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027670 SYNCHRONOUS,
7671 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237672 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027673 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7674 mock_quic_data.AddRead(
7675 ASYNC,
7676 ConstructServerResponseHeadersPacket(
7677 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437678 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337679 ASYNC,
7680 ConstructServerDataPacket(
7681 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237682 mock_quic_data.AddWrite(
7683 SYNCHRONOUS,
7684 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457685 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7686 mock_quic_data.AddRead(ASYNC, 0); // EOF
7687
7688 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7689
7690 AddHangingSocketData();
7691 AddHangingSocketData();
7692
Victor Vasiliev7752898d2019-11-14 21:30:227693 scoped_refptr<TestTaskRunner> quic_task_runner(
7694 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567695 QuicStreamFactoryPeer::SetAlarmFactory(
7696 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097697 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227698 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567699
bnc359ed2a2016-04-29 20:43:457700 SendRequestAndExpectQuicResponse(origin1_);
7701 SendRequestAndExpectQuicResponse(origin2_);
7702
7703 EXPECT_TRUE(AllDataConsumed());
7704}
7705
7706// First request opens QUIC session to alternative service. Second request does
7707// not pool to it, even though destination matches, because certificate is not
7708// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527709// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457710TEST_P(QuicNetworkTransactionWithDestinationTest,
7711 DoNotPoolIfCertificateInvalid) {
7712 origin1_ = "news.example.org";
7713 origin2_ = "mail.example.com";
7714
zhongyie537a002017-06-27 16:48:217715 SetQuicAlternativeService(origin1_);
7716 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457717
7718 scoped_refptr<X509Certificate> cert1(
7719 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247720 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7721 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7722 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457723
7724 scoped_refptr<X509Certificate> cert2(
7725 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247726 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7727 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457728
7729 ProofVerifyDetailsChromium verify_details1;
7730 verify_details1.cert_verify_result.verified_cert = cert1;
7731 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7732 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7733
7734 ProofVerifyDetailsChromium verify_details2;
7735 verify_details2.cert_verify_result.verified_cert = cert2;
7736 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7737 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7738
Yixin Wang079ad542018-01-11 04:06:057739 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227740 version_,
7741 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7742 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057743 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177744 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227745 version_,
7746 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7747 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457748
Ryan Hamiltonabad59e2019-06-06 04:02:597749 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237750 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257751 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237752 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7753 packet_num++, &client_maker1));
7754 }
Fan Yang32c5a112018-12-10 20:06:337755 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237756 SYNCHRONOUS,
7757 ConstructClientRequestHeadersPacket(
7758 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7759 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437760 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337761 ASYNC,
7762 ConstructServerResponseHeadersPacket(
7763 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437764 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337765 ASYNC,
7766 ConstructServerDataPacket(
7767 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437768 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237769 SYNCHRONOUS,
7770 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457771 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7772 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7773
7774 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7775
Yixin Wang079ad542018-01-11 04:06:057776 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227777 version_,
7778 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7779 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057780 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177781 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227782 version_,
7783 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7784 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457785
Ryan Hamiltonabad59e2019-06-06 04:02:597786 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237787 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257788 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237789 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7790 packet_num2++, &client_maker2));
7791 }
Fan Yang32c5a112018-12-10 20:06:337792 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237793 SYNCHRONOUS,
7794 ConstructClientRequestHeadersPacket(
7795 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7796 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437797 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337798 ASYNC,
7799 ConstructServerResponseHeadersPacket(
7800 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437801 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337802 ASYNC,
7803 ConstructServerDataPacket(
7804 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437805 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237806 SYNCHRONOUS,
7807 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457808 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7809 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7810
7811 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7812
bnc359ed2a2016-04-29 20:43:457813 SendRequestAndExpectQuicResponse(origin1_);
7814 SendRequestAndExpectQuicResponse(origin2_);
7815
7816 EXPECT_TRUE(AllDataConsumed());
7817}
7818
ckrasicdee37572017-04-06 22:42:277819// crbug.com/705109 - this confirms that matching request with a body
7820// triggers a crash (pre-fix).
7821TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Ryan Hamilton6c6493102019-12-05 21:36:507822 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7823 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387824 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277825 HostPortPair::FromString("mail.example.org:443"));
7826
Ryan Hamiltonabad59e2019-06-06 04:02:597827 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237828 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257829 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237830 mock_quic_data.AddWrite(
7831 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7832 }
Zhongyi Shi32f2fd02018-04-16 18:23:437833 mock_quic_data.AddWrite(
7834 SYNCHRONOUS,
7835 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337836 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027837 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437838 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027839 ASYNC,
7840 ConstructServerPushPromisePacket(
7841 1, GetNthClientInitiatedBidirectionalStreamId(0),
7842 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7843 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317844
7845 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427846 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:257847 !VersionUsesHttp3(version_.transport_version)) ||
7848 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:427849 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027850 mock_quic_data.AddWrite(
7851 SYNCHRONOUS,
7852 ConstructClientPriorityPacket(
7853 client_packet_number++, false,
7854 GetNthServerInitiatedUnidirectionalStreamId(0),
7855 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577856 }
Zhongyi Shi32f2fd02018-04-16 18:23:437857 mock_quic_data.AddRead(
7858 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337859 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027860 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577861 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437862 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7863 mock_quic_data.AddRead(
7864 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337865 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027866 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437867 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437868 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337869 ASYNC, ConstructServerDataPacket(
7870 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177871 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577872 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437873 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417874
Victor Vasiliev076657c2019-03-12 02:46:437875 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437876 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337877 ASYNC, ConstructServerDataPacket(
7878 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177879 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277880
7881 // Because the matching request has a body, we will see the push
7882 // stream get cancelled, and the matching request go out on the
7883 // wire.
Fan Yang32c5a112018-12-10 20:06:337884 mock_quic_data.AddWrite(SYNCHRONOUS,
7885 ConstructClientAckAndRstPacket(
7886 client_packet_number++,
7887 GetNthServerInitiatedUnidirectionalStreamId(0),
7888 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277889 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437890 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567891 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417892 mock_quic_data.AddWrite(
7893 SYNCHRONOUS,
7894 ConstructClientRequestHeadersAndDataFramesPacket(
7895 client_packet_number++,
7896 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7897 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027898 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417899 } else {
7900 mock_quic_data.AddWrite(
7901 SYNCHRONOUS,
7902 ConstructClientRequestHeadersAndDataFramesPacket(
7903 client_packet_number++,
7904 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7905 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027906 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7907 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417908 }
ckrasicdee37572017-04-06 22:42:277909
7910 // We see the same response as for the earlier pushed and cancelled
7911 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437912 mock_quic_data.AddRead(
7913 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337914 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027915 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437916 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337917 ASYNC, ConstructServerDataPacket(
7918 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177919 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277920
Yixin Wangb470bc882018-02-15 18:43:577921 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437922 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277923 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7924 mock_quic_data.AddRead(ASYNC, 0); // EOF
7925 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7926
7927 // The non-alternate protocol job needs to hang in order to guarantee that
7928 // the alternate-protocol job will "win".
7929 AddHangingNonAlternateProtocolSocketData();
7930
7931 CreateSession();
7932
7933 // PUSH_PROMISE handling in the http layer gets exercised here.
7934 SendRequestAndExpectQuicResponse("hello!");
7935
7936 request_.url = GURL("https://mail.example.org/pushed.jpg");
7937 ChunkedUploadDataStream upload_data(0);
7938 upload_data.AppendData("1", 1, true);
7939 request_.upload_data_stream = &upload_data;
7940 SendRequestAndExpectQuicResponse("and hello!");
7941}
7942
Bence Béky7538a952018-02-01 16:59:527943// Regression test for https://crbug.com/797825: If pushed headers describe a
7944// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7945// not be called (otherwise a DCHECK fails).
7946TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton6c6493102019-12-05 21:36:507947 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7948 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
7949
Ryan Hamilton0239aac2018-05-19 00:03:137950 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527951 pushed_request_headers[":authority"] = "";
7952 pushed_request_headers[":method"] = "GET";
7953 pushed_request_headers[":path"] = "/";
7954 pushed_request_headers[":scheme"] = "nosuchscheme";
7955
Victor Vasilieva1e66d72019-12-05 17:55:387956 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527957 HostPortPair::FromString("mail.example.org:443"));
7958
Ryan Hamiltonabad59e2019-06-06 04:02:597959 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527960
Renjie Tangaadb84b2019-08-31 01:00:237961 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257962 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237963 mock_quic_data.AddWrite(SYNCHRONOUS,
7964 ConstructInitialSettingsPacket(packet_num++));
7965 }
Bence Béky7538a952018-02-01 16:59:527966 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237967 SYNCHRONOUS,
7968 ConstructClientRequestHeadersPacket(
7969 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7970 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527971
Fan Yang32c5a112018-12-10 20:06:337972 mock_quic_data.AddRead(
7973 ASYNC, ConstructServerPushPromisePacket(
7974 1, GetNthClientInitiatedBidirectionalStreamId(0),
7975 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027976 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:237977 mock_quic_data.AddWrite(
7978 SYNCHRONOUS,
7979 ConstructClientRstPacket(packet_num++,
7980 GetNthServerInitiatedUnidirectionalStreamId(0),
7981 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:527982
Zhongyi Shi32f2fd02018-04-16 18:23:437983 mock_quic_data.AddRead(
7984 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337985 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027986 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:237987 mock_quic_data.AddWrite(SYNCHRONOUS,
7988 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527989
Zhongyi Shi32f2fd02018-04-16 18:23:437990 mock_quic_data.AddRead(
7991 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337992 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027993 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437994 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437995 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337996 ASYNC, ConstructServerDataPacket(
7997 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177998 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237999 mock_quic_data.AddWrite(SYNCHRONOUS,
8000 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:528001
8002 mock_quic_data.AddRead(ASYNC, 0);
8003 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8004
8005 // The non-alternate protocol job needs to hang in order to guarantee that
8006 // the alternate-protocol job will "win".
8007 AddHangingNonAlternateProtocolSocketData();
8008
8009 CreateSession();
8010
8011 // PUSH_PROMISE handling in the http layer gets exercised here.
8012 SendRequestAndExpectQuicResponse("hello!");
8013
8014 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8015 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8016}
8017
Yixin Wang46a273ec302018-01-23 17:59:568018// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148019TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:568020 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148021 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568022 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498023 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568024
Ryan Hamiltonabad59e2019-06-06 04:02:598025 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238026 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258027 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238028 mock_quic_data.AddWrite(SYNCHRONOUS,
8029 ConstructInitialSettingsPacket(packet_num++));
8030 }
Fan Yang32c5a112018-12-10 20:06:338031 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238032 SYNCHRONOUS,
8033 ConstructClientRequestHeadersPacket(
8034 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8035 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8036 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338037 mock_quic_data.AddRead(
8038 ASYNC, ConstructServerResponseHeadersPacket(
8039 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8040 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568041
8042 const char get_request[] =
8043 "GET / HTTP/1.1\r\n"
8044 "Host: mail.example.org\r\n"
8045 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438046 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568047 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418048 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358049 SYNCHRONOUS,
8050 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238051 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8052 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418053 } else {
8054 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418055 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288056 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238057 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288058 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418059 }
8060
Yixin Wang46a273ec302018-01-23 17:59:568061 const char get_response[] =
8062 "HTTP/1.1 200 OK\r\n"
8063 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438064 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438065 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338066 ASYNC, ConstructServerDataPacket(
8067 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178068 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438069 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338070 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418071 SYNCHRONOUS, ConstructServerDataPacket(
8072 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178073 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238074 mock_quic_data.AddWrite(SYNCHRONOUS,
8075 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568076 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8077
8078 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418079 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238080 ConstructClientRstPacket(packet_num++,
8081 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418082 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568083
8084 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8085
8086 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8087
8088 CreateSession();
8089
8090 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:098091 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:568092 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8093 HeadersHandler headers_handler;
8094 trans.SetBeforeHeadersSentCallback(
8095 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8096 base::Unretained(&headers_handler)));
8097 RunTransaction(&trans);
8098 CheckWasHttpResponse(&trans);
8099 CheckResponsePort(&trans, 70);
8100 CheckResponseData(&trans, "0123456789");
8101 EXPECT_TRUE(headers_handler.was_proxied());
8102 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8103
8104 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8105 // proxy socket to disconnect.
8106 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8107
8108 base::RunLoop().RunUntilIdle();
8109 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8110 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8111}
8112
8113// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148114TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:568115 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148116 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568117 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498118 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568119
Ryan Hamiltonabad59e2019-06-06 04:02:598120 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238121 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258122 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238123 mock_quic_data.AddWrite(SYNCHRONOUS,
8124 ConstructInitialSettingsPacket(packet_num++));
8125 }
Fan Yang32c5a112018-12-10 20:06:338126 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238127 SYNCHRONOUS,
8128 ConstructClientRequestHeadersPacket(
8129 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8130 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8131 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338132 mock_quic_data.AddRead(
8133 ASYNC, ConstructServerResponseHeadersPacket(
8134 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8135 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568136
8137 SpdyTestUtil spdy_util;
8138
Ryan Hamilton0239aac2018-05-19 00:03:138139 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568140 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438141 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568142 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418143 mock_quic_data.AddWrite(
8144 SYNCHRONOUS,
8145 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238146 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8147 1, 1, 1, false,
8148 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418149 } else {
8150 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418151 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288152 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238153 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8154 1, 1, 1, false,
Renjie Tangd5133972019-12-06 00:20:288155 {header + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418156 }
Ryan Hamilton0239aac2018-05-19 00:03:138157 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568158 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438159 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438160 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178161 ASYNC, ConstructServerDataPacket(
8162 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8163 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568164
Ryan Hamilton0239aac2018-05-19 00:03:138165 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198166 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:438167 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438168 mock_quic_data.AddRead(
8169 SYNCHRONOUS,
8170 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:338171 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438172 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:238173 mock_quic_data.AddWrite(SYNCHRONOUS,
8174 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568175 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8176
8177 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438178 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238179 ConstructClientRstPacket(packet_num++,
8180 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418181 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568182
8183 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8184
8185 SSLSocketDataProvider ssl_data(ASYNC, OK);
8186 ssl_data.next_proto = kProtoHTTP2;
8187 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8188
8189 CreateSession();
8190
8191 request_.url = GURL("https://mail.example.org/");
8192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8193 HeadersHandler headers_handler;
8194 trans.SetBeforeHeadersSentCallback(
8195 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8196 base::Unretained(&headers_handler)));
8197 RunTransaction(&trans);
8198 CheckWasSpdyResponse(&trans);
8199 CheckResponsePort(&trans, 70);
8200 CheckResponseData(&trans, "0123456789");
8201 EXPECT_TRUE(headers_handler.was_proxied());
8202 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8203
Wez0e717112018-06-18 23:09:228204 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
8205 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:568206 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8207
8208 base::RunLoop().RunUntilIdle();
8209 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8210 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8211}
8212
8213// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
8214// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148215TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:568216 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148217 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568218 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498219 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568220
Ryan Hamiltonabad59e2019-06-06 04:02:598221 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:418222 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:258223 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238224 mock_quic_data.AddWrite(
8225 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
8226 }
Fan Yang32c5a112018-12-10 20:06:338227 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418228 SYNCHRONOUS,
8229 ConstructClientRequestHeadersPacket(
8230 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:048231 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028232 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338233 mock_quic_data.AddRead(
8234 ASYNC, ConstructServerResponseHeadersPacket(
8235 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8236 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568237
Ryan Hamilton8d9ee76e2018-05-29 23:52:528238 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568239 const char get_request_1[] =
8240 "GET / HTTP/1.1\r\n"
8241 "Host: mail.example.org\r\n"
8242 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438243 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:568244 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418245 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178246 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8247 write_packet_index++, false,
8248 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
8249 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:418250 } else {
8251 mock_quic_data.AddWrite(
Renjie Tangd5133972019-12-06 00:20:288252 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Ryan Hamilton7505eb92019-06-08 00:22:178253 write_packet_index++, false,
8254 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Renjie Tangd5133972019-12-06 00:20:288255 false, {header + std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:418256 }
8257
Yixin Wang46a273ec302018-01-23 17:59:568258 const char get_response_1[] =
8259 "HTTP/1.1 200 OK\r\n"
8260 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438261 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:438262 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438263 ASYNC, ConstructServerDataPacket(
8264 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178265 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418266 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568267
Victor Vasiliev076657c2019-03-12 02:46:438268 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338269 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178270 SYNCHRONOUS, ConstructServerDataPacket(
8271 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8272 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418273 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568274
Renjief49758b2019-01-11 23:32:418275 mock_quic_data.AddWrite(
8276 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568277
8278 const char get_request_2[] =
8279 "GET /2 HTTP/1.1\r\n"
8280 "Host: mail.example.org\r\n"
8281 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438282 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:568283 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418284 mock_quic_data.AddWrite(
8285 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288286 ConstructClientDataPacket(
Renjied172e812019-01-16 05:12:358287 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288288 false, false, {header4 + std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358289 } else {
8290 mock_quic_data.AddWrite(
8291 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178292 ConstructClientDataPacket(
8293 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8294 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418295 }
Yixin Wang46a273ec302018-01-23 17:59:568296
8297 const char get_response_2[] =
8298 "HTTP/1.1 200 OK\r\n"
8299 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438300 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438301 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438302 ASYNC, ConstructServerDataPacket(
8303 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178304 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418305 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568306
Victor Vasiliev076657c2019-03-12 02:46:438307 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528308 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178309 SYNCHRONOUS, ConstructServerDataPacket(
8310 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8311 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418312 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568313
Renjief49758b2019-01-11 23:32:418314 mock_quic_data.AddWrite(
8315 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568316 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8317
Renjief49758b2019-01-11 23:32:418318 mock_quic_data.AddWrite(
8319 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418320 ConstructClientRstPacket(write_packet_index++,
8321 GetNthClientInitiatedBidirectionalStreamId(0),
8322 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568323
8324 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8325
8326 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8327
8328 CreateSession();
8329
8330 request_.url = GURL("https://mail.example.org/");
8331 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8332 HeadersHandler headers_handler_1;
8333 trans_1.SetBeforeHeadersSentCallback(
8334 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8335 base::Unretained(&headers_handler_1)));
8336 RunTransaction(&trans_1);
8337 CheckWasHttpResponse(&trans_1);
8338 CheckResponsePort(&trans_1, 70);
8339 CheckResponseData(&trans_1, "0123456789");
8340 EXPECT_TRUE(headers_handler_1.was_proxied());
8341 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8342
8343 request_.url = GURL("https://mail.example.org/2");
8344 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8345 HeadersHandler headers_handler_2;
8346 trans_2.SetBeforeHeadersSentCallback(
8347 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8348 base::Unretained(&headers_handler_2)));
8349 RunTransaction(&trans_2);
8350 CheckWasHttpResponse(&trans_2);
8351 CheckResponsePort(&trans_2, 70);
8352 CheckResponseData(&trans_2, "0123456");
8353 EXPECT_TRUE(headers_handler_2.was_proxied());
8354 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8355
8356 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8357 // proxy socket to disconnect.
8358 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8359
8360 base::RunLoop().RunUntilIdle();
8361 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8362 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8363}
8364
8365// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8366// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8367// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148368TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568369 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148370 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568371 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498372 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568373
Ryan Hamiltonabad59e2019-06-06 04:02:598374 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238375 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258376 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238377 mock_quic_data.AddWrite(SYNCHRONOUS,
8378 ConstructInitialSettingsPacket(packet_num++));
8379 }
Yixin Wang46a273ec302018-01-23 17:59:568380
8381 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338382 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238383 SYNCHRONOUS,
8384 ConstructClientRequestHeadersPacket(
8385 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8386 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8387 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438388 mock_quic_data.AddRead(
8389 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338390 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028391 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568392
8393 // GET request, response, and data over QUIC tunnel for first request
8394 const char get_request[] =
8395 "GET / HTTP/1.1\r\n"
8396 "Host: mail.example.org\r\n"
8397 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438398 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568399 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418400 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358401 SYNCHRONOUS,
8402 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238403 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8404 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418405 } else {
8406 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418407 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288408 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238409 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288410 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418411 }
8412
Yixin Wang46a273ec302018-01-23 17:59:568413 const char get_response[] =
8414 "HTTP/1.1 200 OK\r\n"
8415 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438416 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568417 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338418 ASYNC, ConstructServerDataPacket(
8419 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178420 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438421 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338422 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418423 SYNCHRONOUS, ConstructServerDataPacket(
8424 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178425 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238426 mock_quic_data.AddWrite(SYNCHRONOUS,
8427 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568428
8429 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438430 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238431 SYNCHRONOUS,
8432 ConstructClientRequestHeadersPacket(
8433 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8434 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8435 ConnectRequestHeaders("different.example.org:443"),
8436 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438437 mock_quic_data.AddRead(
8438 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338439 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028440 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568441
8442 // GET request, response, and data over QUIC tunnel for second request
8443 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138444 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568445 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438446 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568447 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418448 mock_quic_data.AddWrite(
8449 SYNCHRONOUS,
8450 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238451 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8452 4, 4, 1, false,
8453 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418454 } else {
8455 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418456 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288457 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238458 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8459 4, 4, 1, false,
Renjie Tangd5133972019-12-06 00:20:288460 {header4 + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418461 }
Yixin Wang46a273ec302018-01-23 17:59:568462
Ryan Hamilton0239aac2018-05-19 00:03:138463 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568464 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438465 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438466 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178467 ASYNC, ConstructServerDataPacket(
8468 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8469 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568470
Ryan Hamilton0239aac2018-05-19 00:03:138471 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198472 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438473 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438474 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438475 ASYNC, ConstructServerDataPacket(
8476 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438477 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568478
Renjie Tangaadb84b2019-08-31 01:00:238479 mock_quic_data.AddWrite(SYNCHRONOUS,
8480 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568481 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8482
8483 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418484 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238485 ConstructClientRstPacket(packet_num++,
8486 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418487 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568488 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438489 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238490 ConstructClientRstPacket(packet_num++,
8491 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418492 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568493
8494 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8495
8496 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8497
8498 SSLSocketDataProvider ssl_data(ASYNC, OK);
8499 ssl_data.next_proto = kProtoHTTP2;
8500 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8501
8502 CreateSession();
8503
8504 request_.url = GURL("https://mail.example.org/");
8505 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8506 HeadersHandler headers_handler_1;
8507 trans_1.SetBeforeHeadersSentCallback(
8508 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8509 base::Unretained(&headers_handler_1)));
8510 RunTransaction(&trans_1);
8511 CheckWasHttpResponse(&trans_1);
8512 CheckResponsePort(&trans_1, 70);
8513 CheckResponseData(&trans_1, "0123456789");
8514 EXPECT_TRUE(headers_handler_1.was_proxied());
8515 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8516
8517 request_.url = GURL("https://different.example.org/");
8518 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8519 HeadersHandler headers_handler_2;
8520 trans_2.SetBeforeHeadersSentCallback(
8521 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8522 base::Unretained(&headers_handler_2)));
8523 RunTransaction(&trans_2);
8524 CheckWasSpdyResponse(&trans_2);
8525 CheckResponsePort(&trans_2, 70);
8526 CheckResponseData(&trans_2, "0123456");
8527 EXPECT_TRUE(headers_handler_2.was_proxied());
8528 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8529
8530 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8531 // proxy socket to disconnect.
8532 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8533
8534 base::RunLoop().RunUntilIdle();
8535 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8536 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8537}
8538
8539// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148540TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568541 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148542 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568543 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498544 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568545
Ryan Hamiltonabad59e2019-06-06 04:02:598546 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238547 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258548 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238549 mock_quic_data.AddWrite(SYNCHRONOUS,
8550 ConstructInitialSettingsPacket(packet_num++));
8551 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528552 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238553 SYNCHRONOUS,
8554 ConstructClientRequestHeadersPacket(
8555 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8556 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8557 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338558 mock_quic_data.AddRead(
8559 ASYNC, ConstructServerResponseHeadersPacket(
8560 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8561 GetResponseHeaders("500")));
8562 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238563 mock_quic_data.AddWrite(
8564 SYNCHRONOUS,
8565 ConstructClientAckAndRstPacket(
8566 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8567 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568568
8569 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8570
8571 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8572
8573 CreateSession();
8574
8575 request_.url = GURL("https://mail.example.org/");
8576 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8577 HeadersHandler headers_handler;
8578 trans.SetBeforeHeadersSentCallback(
8579 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8580 base::Unretained(&headers_handler)));
8581 TestCompletionCallback callback;
8582 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8583 EXPECT_EQ(ERR_IO_PENDING, rv);
8584 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8585 EXPECT_EQ(false, headers_handler.was_proxied());
8586
8587 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8588 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8589}
8590
8591// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148592TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568593 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148594 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568595 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498596 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568597
Ryan Hamiltonabad59e2019-06-06 04:02:598598 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238599 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258600 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238601 mock_quic_data.AddWrite(SYNCHRONOUS,
8602 ConstructInitialSettingsPacket(packet_num++));
8603 }
Fan Yang32c5a112018-12-10 20:06:338604 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238605 SYNCHRONOUS,
8606 ConstructClientRequestHeadersPacket(
8607 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8608 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8609 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568610 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8611
8612 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8613
8614 CreateSession();
8615
8616 request_.url = GURL("https://mail.example.org/");
8617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8618 HeadersHandler headers_handler;
8619 trans.SetBeforeHeadersSentCallback(
8620 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8621 base::Unretained(&headers_handler)));
8622 TestCompletionCallback callback;
8623 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8624 EXPECT_EQ(ERR_IO_PENDING, rv);
8625 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8626
8627 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8628 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8629}
8630
8631// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8632// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148633TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568634 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148635 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568636 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498637 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568638
Ryan Hamiltonabad59e2019-06-06 04:02:598639 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238640 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258641 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238642 mock_quic_data.AddWrite(SYNCHRONOUS,
8643 ConstructInitialSettingsPacket(packet_num++));
8644 }
Fan Yang32c5a112018-12-10 20:06:338645 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238646 SYNCHRONOUS,
8647 ConstructClientRequestHeadersPacket(
8648 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8649 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8650 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438651 mock_quic_data.AddRead(
8652 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338653 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028654 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238655 mock_quic_data.AddWrite(
8656 SYNCHRONOUS,
8657 ConstructClientAckAndRstPacket(
8658 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8659 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568660
Zhongyi Shi32f2fd02018-04-16 18:23:438661 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238662 SYNCHRONOUS,
8663 ConstructClientRequestHeadersPacket(
8664 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8665 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8666 ConnectRequestHeaders("mail.example.org:443"),
8667 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438668 mock_quic_data.AddRead(
8669 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338670 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028671 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568672
8673 const char get_request[] =
8674 "GET / HTTP/1.1\r\n"
8675 "Host: mail.example.org\r\n"
8676 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438677 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568678 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418679 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358680 SYNCHRONOUS,
8681 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238682 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8683 2, 2, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418684 } else {
8685 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418686 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288687 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238688 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangd5133972019-12-06 00:20:288689 2, 2, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418690 }
Yixin Wang46a273ec302018-01-23 17:59:568691 const char get_response[] =
8692 "HTTP/1.1 200 OK\r\n"
8693 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438694 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438695 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338696 ASYNC, ConstructServerDataPacket(
8697 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178698 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528699
Victor Vasiliev076657c2019-03-12 02:46:438700 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338701 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418702 SYNCHRONOUS, ConstructServerDataPacket(
8703 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178704 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238705 mock_quic_data.AddWrite(SYNCHRONOUS,
8706 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568707 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8708
8709 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418710 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238711 ConstructClientRstPacket(packet_num++,
8712 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418713 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568714
8715 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8716
8717 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8718 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8719
8720 SSLSocketDataProvider ssl_data(ASYNC, OK);
8721 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8722
8723 CreateSession();
8724
8725 request_.url = GURL("https://mail.example.org/");
8726 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8727 HeadersHandler headers_handler;
8728 trans.SetBeforeHeadersSentCallback(
8729 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8730 base::Unretained(&headers_handler)));
8731 TestCompletionCallback callback;
8732 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8733 EXPECT_EQ(ERR_IO_PENDING, rv);
8734 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8735
8736 rv = trans.RestartIgnoringLastError(callback.callback());
8737 EXPECT_EQ(ERR_IO_PENDING, rv);
8738 EXPECT_EQ(OK, callback.WaitForResult());
8739
8740 CheckWasHttpResponse(&trans);
8741 CheckResponsePort(&trans, 70);
8742 CheckResponseData(&trans, "0123456789");
8743 EXPECT_EQ(true, headers_handler.was_proxied());
8744 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8745
8746 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8747 // proxy socket to disconnect.
8748 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8749
8750 base::RunLoop().RunUntilIdle();
8751 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8752 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8753}
8754
8755// Checks if a request's specified "user-agent" header shows up correctly in the
8756// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148757TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008758 const char kConfiguredUserAgent[] = "Configured User-Agent";
8759 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568760 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148761 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568762 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498763 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568764
Ryan Hamiltonabad59e2019-06-06 04:02:598765 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238766 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258767 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238768 mock_quic_data.AddWrite(SYNCHRONOUS,
8769 ConstructInitialSettingsPacket(packet_num++));
8770 }
Yixin Wang46a273ec302018-01-23 17:59:568771
Ryan Hamilton0239aac2018-05-19 00:03:138772 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008773 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338774 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028775 SYNCHRONOUS,
8776 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238777 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8778 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
8779 0));
Yixin Wang46a273ec302018-01-23 17:59:568780 // Return an error, so the transaction stops here (this test isn't interested
8781 // in the rest).
8782 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8783
8784 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8785
Matt Menked732ea42019-03-08 12:05:008786 StaticHttpUserAgentSettings http_user_agent_settings(
8787 std::string() /* accept_language */, kConfiguredUserAgent);
8788 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568789 CreateSession();
8790
8791 request_.url = GURL("https://mail.example.org/");
8792 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008793 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8795 HeadersHandler headers_handler;
8796 trans.SetBeforeHeadersSentCallback(
8797 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8798 base::Unretained(&headers_handler)));
8799 TestCompletionCallback callback;
8800 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8801 EXPECT_EQ(ERR_IO_PENDING, rv);
8802 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8803
8804 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8805 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8806}
8807
Yixin Wang00fc44c2018-01-23 21:12:208808// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8809// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148810TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208811 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148812 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208813 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498814 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208815
8816 const RequestPriority request_priority = MEDIUM;
8817
Ryan Hamiltonabad59e2019-06-06 04:02:598818 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238819 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258820 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238821 mock_quic_data.AddWrite(SYNCHRONOUS,
8822 ConstructInitialSettingsPacket(packet_num++));
8823 }
Zhongyi Shi32f2fd02018-04-16 18:23:438824 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238825 SYNCHRONOUS,
8826 ConstructClientRequestHeadersPacket(
8827 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8828 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8829 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208830 // Return an error, so the transaction stops here (this test isn't interested
8831 // in the rest).
8832 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8833
8834 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8835
8836 CreateSession();
8837
8838 request_.url = GURL("https://mail.example.org/");
8839 HttpNetworkTransaction trans(request_priority, session_.get());
8840 TestCompletionCallback callback;
8841 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8842 EXPECT_EQ(ERR_IO_PENDING, rv);
8843 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8844
8845 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8846 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8847}
8848
Matt Menkeedaf3b82019-03-14 21:39:448849// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8850// HTTP/2 stream dependency and weights given the request priority.
8851TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8852 session_params_.enable_quic = true;
8853 session_params_.enable_quic_proxies_for_https_urls = true;
8854 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8855 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8856
8857 const RequestPriority kRequestPriority = MEDIUM;
8858 const RequestPriority kRequestPriority2 = LOWEST;
8859
Ryan Hamiltonabad59e2019-06-06 04:02:598860 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258861 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238862 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8863 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8864 } else {
8865 mock_quic_data.AddWrite(
8866 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8867 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8868 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8869 ConnectRequestHeaders("mail.example.org:443"), 0));
8870 }
Matt Menkeedaf3b82019-03-14 21:39:448871 // This should never be reached.
8872 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8873 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8874
8875 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598876 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448877 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8878 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8879
8880 int original_max_sockets_per_group =
8881 ClientSocketPoolManager::max_sockets_per_group(
8882 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8883 ClientSocketPoolManager::set_max_sockets_per_group(
8884 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8885 int original_max_sockets_per_pool =
8886 ClientSocketPoolManager::max_sockets_per_pool(
8887 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8888 ClientSocketPoolManager::set_max_sockets_per_pool(
8889 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8890 CreateSession();
8891
8892 request_.url = GURL("https://mail.example.org/");
8893 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8894 TestCompletionCallback callback;
8895 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8896 EXPECT_EQ(ERR_IO_PENDING, rv);
8897
8898 HttpRequestInfo request2;
8899 request2.url = GURL("https://mail.example.org/some/other/path/");
8900 request2.traffic_annotation =
8901 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8902
8903 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8904 TestCompletionCallback callback2;
8905 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8906 EXPECT_EQ(ERR_IO_PENDING, rv2);
8907
8908 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8909 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8910
8911 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8912
8913 ClientSocketPoolManager::set_max_sockets_per_pool(
8914 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8915 original_max_sockets_per_pool);
8916 ClientSocketPoolManager::set_max_sockets_per_group(
8917 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8918 original_max_sockets_per_group);
8919}
8920
Yixin Wang46a273ec302018-01-23 17:59:568921// Test the request-challenge-retry sequence for basic auth, over a QUIC
8922// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148923TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568924 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8925 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568926
8927 std::unique_ptr<QuicTestPacketMaker> client_maker;
8928 std::unique_ptr<QuicTestPacketMaker> server_maker;
8929
8930 // On the second pass, the body read of the auth challenge is synchronous, so
8931 // IsConnectedAndIdle returns false. The socket should still be drained and
8932 // reused. See http://crbug.com/544255.
8933 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338934 client_maker.reset(new QuicTestPacketMaker(
Victor Vasiliev7752898d2019-11-14 21:30:228935 version_,
8936 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8937 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338938 client_headers_include_h2_stream_dependency_));
8939 server_maker.reset(new QuicTestPacketMaker(
Victor Vasiliev7752898d2019-11-14 21:30:228940 version_,
8941 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8942 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
8943 false));
Yixin Wang46a273ec302018-01-23 17:59:568944
8945 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148946 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568947 proxy_resolution_service_ =
8948 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498949 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568950
Ryan Hamiltonabad59e2019-06-06 04:02:598951 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528952 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568953
Renjie Tangaadb84b2019-08-31 01:00:238954 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258955 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238956 mock_quic_data.AddWrite(
8957 SYNCHRONOUS, client_maker->MakeInitialSettingsPacket(packet_num++));
8958 }
Yixin Wang46a273ec302018-01-23 17:59:568959
8960 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438961 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028962 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238963 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8964 false,
Matt Menke6e879bd2019-03-18 17:26:048965 ConvertRequestPriorityToQuicPriority(
8966 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568967 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028968 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568969
Ryan Hamilton0239aac2018-05-19 00:03:138970 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568971 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8972 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8973 headers["content-length"] = "10";
8974 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:028975 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338976 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028977 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568978
8979 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438980 mock_quic_data.AddRead(
8981 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338982 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178983 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568984 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438985 mock_quic_data.AddRead(
8986 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338987 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178988 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568989 }
8990 server_data_offset += 10;
8991
Renjie Tangaadb84b2019-08-31 01:00:238992 mock_quic_data.AddWrite(
8993 SYNCHRONOUS, client_maker->MakeAckPacket(packet_num++, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568994
8995 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338996 SYNCHRONOUS,
8997 client_maker->MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:238998 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418999 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:189000 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:569001
9002 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
9003 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
9004 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:049005 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029006 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239007 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
9008 false,
Matt Menke6e879bd2019-03-18 17:26:049009 ConvertRequestPriorityToQuicPriority(
9010 HttpProxyConnectJob::kH2QuicTunnelPriority),
9011 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:029012 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569013
9014 // Response to wrong password
9015 headers =
9016 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
9017 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9018 headers["content-length"] = "10";
9019 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029020 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339021 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029022 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569023 mock_quic_data.AddRead(SYNCHRONOUS,
9024 ERR_IO_PENDING); // No more data to read
9025
Fan Yang32c5a112018-12-10 20:06:339026 mock_quic_data.AddWrite(
9027 SYNCHRONOUS,
9028 client_maker->MakeAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:239029 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Fan Yang32c5a112018-12-10 20:06:339030 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:569031
9032 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9033 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
9034
9035 CreateSession();
9036
9037 request_.url = GURL("https://mail.example.org/");
9038 // Ensure that proxy authentication is attempted even
9039 // when the no authentication data flag is set.
9040 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
9041 {
9042 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9043 HeadersHandler headers_handler;
9044 trans.SetBeforeHeadersSentCallback(
9045 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
9046 base::Unretained(&headers_handler)));
9047 RunTransaction(&trans);
9048
9049 const HttpResponseInfo* response = trans.GetResponseInfo();
9050 ASSERT_TRUE(response != nullptr);
9051 ASSERT_TRUE(response->headers.get() != nullptr);
9052 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9053 response->headers->GetStatusLine());
9054 EXPECT_TRUE(response->headers->IsKeepAlive());
9055 EXPECT_EQ(407, response->headers->response_code());
9056 EXPECT_EQ(10, response->headers->GetContentLength());
9057 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589058 base::Optional<AuthChallengeInfo> auth_challenge =
9059 response->auth_challenge;
9060 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569061 EXPECT_TRUE(auth_challenge->is_proxy);
9062 EXPECT_EQ("https://proxy.example.org:70",
9063 auth_challenge->challenger.Serialize());
9064 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9065 EXPECT_EQ("basic", auth_challenge->scheme);
9066
9067 TestCompletionCallback callback;
9068 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
9069 callback.callback());
9070 EXPECT_EQ(ERR_IO_PENDING, rv);
9071 EXPECT_EQ(OK, callback.WaitForResult());
9072
9073 response = trans.GetResponseInfo();
9074 ASSERT_TRUE(response != nullptr);
9075 ASSERT_TRUE(response->headers.get() != nullptr);
9076 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9077 response->headers->GetStatusLine());
9078 EXPECT_TRUE(response->headers->IsKeepAlive());
9079 EXPECT_EQ(407, response->headers->response_code());
9080 EXPECT_EQ(10, response->headers->GetContentLength());
9081 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589082 auth_challenge = response->auth_challenge;
9083 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569084 EXPECT_TRUE(auth_challenge->is_proxy);
9085 EXPECT_EQ("https://proxy.example.org:70",
9086 auth_challenge->challenger.Serialize());
9087 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9088 EXPECT_EQ("basic", auth_challenge->scheme);
9089 }
9090 // HttpNetworkTransaction is torn down now that it's out of scope, causing
9091 // the QUIC stream to be cleaned up (since the proxy socket cannot be
9092 // reused because it's not connected).
9093 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9094 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9095 }
9096}
9097
Yixin Wang385652a2018-02-16 02:37:239098TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
Ryan Hamilton6c6493102019-12-05 21:36:509099 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
9100 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
9101
Yixin Wang385652a2018-02-16 02:37:239102 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
9103 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:569104 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:239105 !client_headers_include_h2_stream_dependency_) {
9106 return;
9107 }
9108
Victor Vasiliev7da08172019-10-14 06:04:259109 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:289110 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:459111 return;
9112 }
9113
Victor Vasilieva1e66d72019-12-05 17:55:389114 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:239115 HostPortPair::FromString("mail.example.org:443"));
9116
Fan Yang32c5a112018-12-10 20:06:339117 const quic::QuicStreamId client_stream_0 =
9118 GetNthClientInitiatedBidirectionalStreamId(0);
9119 const quic::QuicStreamId client_stream_1 =
9120 GetNthClientInitiatedBidirectionalStreamId(1);
9121 const quic::QuicStreamId client_stream_2 =
9122 GetNthClientInitiatedBidirectionalStreamId(2);
9123 const quic::QuicStreamId push_stream_0 =
9124 GetNthServerInitiatedUnidirectionalStreamId(0);
9125 const quic::QuicStreamId push_stream_1 =
9126 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:239127
Ryan Hamiltonabad59e2019-06-06 04:02:599128 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239129 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259130 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239131 mock_quic_data.AddWrite(SYNCHRONOUS,
9132 ConstructInitialSettingsPacket(packet_num++));
9133 }
Yixin Wang385652a2018-02-16 02:37:239134
9135 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:239136 mock_quic_data.AddWrite(
9137 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9138 packet_num++, client_stream_0, true, true, HIGHEST,
9139 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:029140 mock_quic_data.AddWrite(
9141 SYNCHRONOUS,
9142 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239143 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029144 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
9145 mock_quic_data.AddWrite(
9146 SYNCHRONOUS,
9147 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239148 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029149 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:239150
9151 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:029152 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9153 1, client_stream_0, false, false,
9154 GetResponseHeaders("200 OK")));
9155 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9156 2, client_stream_1, false, false,
9157 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239158 mock_quic_data.AddWrite(SYNCHRONOUS,
9159 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:029160 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9161 3, client_stream_2, false, false,
9162 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239163
9164 // Server sends two push promises associated with |client_stream_0|; client
9165 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
9166 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:029167 mock_quic_data.AddRead(
9168 ASYNC,
9169 ConstructServerPushPromisePacket(
9170 4, client_stream_0, push_stream_0, false,
9171 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:239172 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439173 SYNCHRONOUS,
9174 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239175 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439176 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:029177 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
9178 mock_quic_data.AddRead(
9179 ASYNC,
9180 ConstructServerPushPromisePacket(
9181 5, client_stream_0, push_stream_1, false,
9182 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
9183 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:239184 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:029185 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:239186
9187 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:439188 mock_quic_data.AddRead(
9189 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029190 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239191 mock_quic_data.AddWrite(SYNCHRONOUS,
9192 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439193 mock_quic_data.AddRead(
9194 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029195 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239196
9197 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
9198 // priority updates to match the request's priority. Client sends PRIORITY
9199 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:439200 mock_quic_data.AddWrite(
9201 SYNCHRONOUS,
9202 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239203 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439204 {{push_stream_1, client_stream_2,
9205 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
9206 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029207 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:239208
9209 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:439210 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:439211 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179212 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419213 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:439214 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179215 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419216 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:239217 mock_quic_data.AddWrite(SYNCHRONOUS,
9218 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439219 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179220 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:419221 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:439222 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:439223 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179224 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419225 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:239226 mock_quic_data.AddWrite(SYNCHRONOUS,
9227 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439228 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179229 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419230 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:239231
Yixin Wang385652a2018-02-16 02:37:239232 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9233 mock_quic_data.AddRead(ASYNC, 0); // EOF
9234 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9235
9236 // The non-alternate protocol job needs to hang in order to guarantee that
9237 // the alternate-protocol job will "win".
9238 AddHangingNonAlternateProtocolSocketData();
9239
9240 CreateSession();
9241
9242 request_.url = GURL("https://mail.example.org/0.jpg");
9243 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
9244 TestCompletionCallback callback_0;
9245 EXPECT_EQ(ERR_IO_PENDING,
9246 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
9247 base::RunLoop().RunUntilIdle();
9248
9249 request_.url = GURL("https://mail.example.org/1.jpg");
9250 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
9251 TestCompletionCallback callback_1;
9252 EXPECT_EQ(ERR_IO_PENDING,
9253 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
9254 base::RunLoop().RunUntilIdle();
9255
9256 request_.url = GURL("https://mail.example.org/2.jpg");
9257 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
9258 TestCompletionCallback callback_2;
9259 EXPECT_EQ(ERR_IO_PENDING,
9260 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
9261 base::RunLoop().RunUntilIdle();
9262
9263 // Client makes request that matches resource pushed in |pushed_stream_0|.
9264 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
9265 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
9266 TestCompletionCallback callback_3;
9267 EXPECT_EQ(ERR_IO_PENDING,
9268 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9269 base::RunLoop().RunUntilIdle();
9270
9271 EXPECT_TRUE(callback_0.have_result());
9272 EXPECT_EQ(OK, callback_0.WaitForResult());
9273 EXPECT_TRUE(callback_1.have_result());
9274 EXPECT_EQ(OK, callback_1.WaitForResult());
9275 EXPECT_TRUE(callback_2.have_result());
9276 EXPECT_EQ(OK, callback_2.WaitForResult());
9277
9278 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9279 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9280 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9281 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9282
9283 mock_quic_data.Resume();
9284 base::RunLoop().RunUntilIdle();
9285 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9286 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9287}
9288
Matt Menke26e41542019-06-05 01:09:519289// Test that NetworkIsolationKey is respected by QUIC connections, when
9290// kPartitionConnectionsByNetworkIsolationKey is enabled.
9291TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279292 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9293 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9294 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9295 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519296
Victor Vasilieva1e66d72019-12-05 17:55:389297 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519298 HostPortPair::FromString("mail.example.org:443"));
9299
9300 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9301 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9302 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9303 // the same way as the HTTP over H2 proxy case.
9304 for (bool use_proxy : {false, true}) {
9305 SCOPED_TRACE(use_proxy);
9306
9307 if (use_proxy) {
9308 proxy_resolution_service_ =
9309 ProxyResolutionService::CreateFixedFromPacResult(
9310 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9311 } else {
9312 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
9313 }
9314
9315 GURL url1;
9316 GURL url2;
9317 GURL url3;
9318 if (use_proxy) {
9319 url1 = GURL("http://mail.example.org/1");
9320 url2 = GURL("http://mail.example.org/2");
9321 url3 = GURL("http://mail.example.org/3");
9322 } else {
9323 url1 = GURL("https://mail.example.org/1");
9324 url2 = GURL("https://mail.example.org/2");
9325 url3 = GURL("https://mail.example.org/3");
9326 }
9327
9328 for (bool partition_connections : {false, true}) {
9329 SCOPED_TRACE(partition_connections);
9330
9331 base::test::ScopedFeatureList feature_list;
9332 if (partition_connections) {
9333 feature_list.InitAndEnableFeature(
9334 features::kPartitionConnectionsByNetworkIsolationKey);
9335 } else {
9336 feature_list.InitAndDisableFeature(
9337 features::kPartitionConnectionsByNetworkIsolationKey);
9338 }
9339
9340 // Reads and writes for the unpartitioned case, where only one socket is
9341 // used.
9342
Victor Vasilieva1e66d72019-12-05 17:55:389343 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519344 HostPortPair::FromString("mail.example.org:443"));
9345
Ryan Hamiltonabad59e2019-06-06 04:02:599346 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519347 QuicTestPacketMaker client_maker1(
9348 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229349 quic::QuicUtils::CreateRandomConnectionId(
9350 context_.random_generator()),
9351 context_.clock(), kDefaultServerHostName,
9352 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519353 client_headers_include_h2_stream_dependency_);
9354 QuicTestPacketMaker server_maker1(
9355 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229356 quic::QuicUtils::CreateRandomConnectionId(
9357 context_.random_generator()),
9358 context_.clock(), kDefaultServerHostName,
9359 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519360
Renjie Tangaadb84b2019-08-31 01:00:239361 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259362 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239363 unpartitioned_mock_quic_data.AddWrite(
9364 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9365 }
Matt Menke26e41542019-06-05 01:09:519366
9367 unpartitioned_mock_quic_data.AddWrite(
9368 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029369 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239370 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9371 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029372 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519373 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029374 ASYNC, server_maker1.MakeResponseHeadersPacket(
9375 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9376 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519377 unpartitioned_mock_quic_data.AddRead(
9378 ASYNC, server_maker1.MakeDataPacket(
9379 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179380 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519381 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239382 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519383
9384 unpartitioned_mock_quic_data.AddWrite(
9385 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029386 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239387 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9388 false, true,
Matt Menke26e41542019-06-05 01:09:519389 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029390 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519391 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029392 ASYNC, server_maker1.MakeResponseHeadersPacket(
9393 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9394 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519395 unpartitioned_mock_quic_data.AddRead(
9396 ASYNC, server_maker1.MakeDataPacket(
9397 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179398 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519399 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239400 SYNCHRONOUS,
9401 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519402
9403 unpartitioned_mock_quic_data.AddWrite(
9404 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029405 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239406 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9407 false, true,
Matt Menke26e41542019-06-05 01:09:519408 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029409 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519410 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029411 ASYNC, server_maker1.MakeResponseHeadersPacket(
9412 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9413 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519414 unpartitioned_mock_quic_data.AddRead(
9415 ASYNC, server_maker1.MakeDataPacket(
9416 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179417 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519418 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239419 SYNCHRONOUS,
9420 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519421
9422 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9423
9424 // Reads and writes for the partitioned case, where two sockets are used.
9425
Ryan Hamiltonabad59e2019-06-06 04:02:599426 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519427 QuicTestPacketMaker client_maker2(
9428 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229429 quic::QuicUtils::CreateRandomConnectionId(
9430 context_.random_generator()),
9431 context_.clock(), kDefaultServerHostName,
9432 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519433 client_headers_include_h2_stream_dependency_);
9434 QuicTestPacketMaker server_maker2(
9435 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229436 quic::QuicUtils::CreateRandomConnectionId(
9437 context_.random_generator()),
9438 context_.clock(), kDefaultServerHostName,
9439 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519440
Renjie Tangaadb84b2019-08-31 01:00:239441 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259442 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239443 partitioned_mock_quic_data1.AddWrite(
9444 SYNCHRONOUS,
9445 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9446 }
Matt Menke26e41542019-06-05 01:09:519447
9448 partitioned_mock_quic_data1.AddWrite(
9449 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029450 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239451 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9452 true, true,
Matt Menke26e41542019-06-05 01:09:519453 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029454 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519455 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029456 ASYNC, server_maker2.MakeResponseHeadersPacket(
9457 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9458 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519459 partitioned_mock_quic_data1.AddRead(
9460 ASYNC, server_maker2.MakeDataPacket(
9461 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179462 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519463 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239464 SYNCHRONOUS,
9465 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519466
9467 partitioned_mock_quic_data1.AddWrite(
9468 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029469 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239470 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9471 false, true,
Matt Menke26e41542019-06-05 01:09:519472 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029473 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519474 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029475 ASYNC, server_maker2.MakeResponseHeadersPacket(
9476 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9477 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519478 partitioned_mock_quic_data1.AddRead(
9479 ASYNC, server_maker2.MakeDataPacket(
9480 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179481 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519482 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239483 SYNCHRONOUS,
9484 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:519485
9486 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9487
Ryan Hamiltonabad59e2019-06-06 04:02:599488 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519489 QuicTestPacketMaker client_maker3(
9490 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229491 quic::QuicUtils::CreateRandomConnectionId(
9492 context_.random_generator()),
9493 context_.clock(), kDefaultServerHostName,
9494 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519495 client_headers_include_h2_stream_dependency_);
9496 QuicTestPacketMaker server_maker3(
9497 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229498 quic::QuicUtils::CreateRandomConnectionId(
9499 context_.random_generator()),
9500 context_.clock(), kDefaultServerHostName,
9501 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519502
Renjie Tangaadb84b2019-08-31 01:00:239503 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259504 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239505 partitioned_mock_quic_data2.AddWrite(
9506 SYNCHRONOUS,
9507 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9508 }
Matt Menke26e41542019-06-05 01:09:519509
9510 partitioned_mock_quic_data2.AddWrite(
9511 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029512 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239513 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9514 true, true,
Matt Menke26e41542019-06-05 01:09:519515 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029516 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519517 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029518 ASYNC, server_maker3.MakeResponseHeadersPacket(
9519 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9520 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519521 partitioned_mock_quic_data2.AddRead(
9522 ASYNC, server_maker3.MakeDataPacket(
9523 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179524 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519525 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239526 SYNCHRONOUS,
9527 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519528
9529 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9530
9531 if (partition_connections) {
9532 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9533 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9534 } else {
9535 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9536 }
9537
9538 CreateSession();
9539
9540 TestCompletionCallback callback;
9541 HttpRequestInfo request1;
9542 request1.method = "GET";
9543 request1.url = GURL(url1);
9544 request1.traffic_annotation =
9545 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9546 request1.network_isolation_key = network_isolation_key1;
9547 HttpNetworkTransaction trans1(LOWEST, session_.get());
9548 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9549 EXPECT_THAT(callback.GetResult(rv), IsOk());
9550 std::string response_data1;
9551 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9552 EXPECT_EQ("1", response_data1);
9553
9554 HttpRequestInfo request2;
9555 request2.method = "GET";
9556 request2.url = GURL(url2);
9557 request2.traffic_annotation =
9558 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9559 request2.network_isolation_key = network_isolation_key2;
9560 HttpNetworkTransaction trans2(LOWEST, session_.get());
9561 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9562 EXPECT_THAT(callback.GetResult(rv), IsOk());
9563 std::string response_data2;
9564 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9565 EXPECT_EQ("2", response_data2);
9566
9567 HttpRequestInfo request3;
9568 request3.method = "GET";
9569 request3.url = GURL(url3);
9570 request3.traffic_annotation =
9571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9572 request3.network_isolation_key = network_isolation_key1;
9573 HttpNetworkTransaction trans3(LOWEST, session_.get());
9574 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9575 EXPECT_THAT(callback.GetResult(rv), IsOk());
9576 std::string response_data3;
9577 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9578 EXPECT_EQ("3", response_data3);
9579
9580 if (partition_connections) {
9581 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9582 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9583 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9584 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9585 } else {
9586 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9587 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9588 }
9589 }
9590 }
9591}
9592
9593// Test that two requests to the same origin over QUIC tunnels use different
9594// QUIC sessions if their NetworkIsolationKeys don't match, and
9595// kPartitionConnectionsByNetworkIsolationKey is enabled.
9596TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9597 base::test::ScopedFeatureList feature_list;
9598 feature_list.InitAndEnableFeature(
9599 features::kPartitionConnectionsByNetworkIsolationKey);
9600
9601 session_params_.enable_quic = true;
9602 session_params_.enable_quic_proxies_for_https_urls = true;
9603 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9604 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9605
9606 const char kGetRequest[] =
9607 "GET / HTTP/1.1\r\n"
9608 "Host: mail.example.org\r\n"
9609 "Connection: keep-alive\r\n\r\n";
9610 const char kGetResponse[] =
9611 "HTTP/1.1 200 OK\r\n"
9612 "Content-Length: 10\r\n\r\n";
9613
Ryan Hamiltonabad59e2019-06-06 04:02:599614 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9615 std::make_unique<MockQuicData>(version_),
9616 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519617
9618 for (int index : {0, 1}) {
9619 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229620 version_,
9621 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9622 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519623 client_headers_include_h2_stream_dependency_);
9624 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229625 version_,
9626 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9627 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9628 false);
Matt Menke26e41542019-06-05 01:09:519629
Renjie Tangaadb84b2019-08-31 01:00:239630 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259631 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239632 mock_quic_data[index]->AddWrite(
9633 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9634 }
Matt Menke26e41542019-06-05 01:09:519635
Ryan Hamiltonabad59e2019-06-06 04:02:599636 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519637 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029638 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239639 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9640 false,
Matt Menke26e41542019-06-05 01:09:519641 ConvertRequestPriorityToQuicPriority(
9642 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029643 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599644 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029645 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519646 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9647 false, GetResponseHeaders("200 OK"), nullptr));
9648
9649 std::string header = ConstructDataHeader(strlen(kGetRequest));
9650 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599651 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239652 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9653 packet_num++, false,
9654 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9655 1, false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519656 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599657 mock_quic_data[index]->AddWrite(
Renjie Tangd5133972019-12-06 00:20:289658 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:239659 packet_num++, false,
9660 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Renjie Tangd5133972019-12-06 00:20:289661 1, false, {header + std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519662 }
9663
9664 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599665 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519666 ASYNC, server_maker.MakeDataPacket(
9667 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179668 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599669 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179670 SYNCHRONOUS,
9671 server_maker.MakeDataPacket(
9672 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9673 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599674 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239675 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599676 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9677 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519678
Ryan Hamiltonabad59e2019-06-06 04:02:599679 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519680 }
9681
9682 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9683 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9684 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9685
9686 CreateSession();
9687
9688 request_.url = GURL("https://mail.example.org/");
9689 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9691 RunTransaction(&trans);
9692 CheckResponseData(&trans, "0123456789");
9693
9694 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279695 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9696 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519697 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9698 RunTransaction(&trans2);
9699 CheckResponseData(&trans2, "0123456789");
9700
Ryan Hamiltonabad59e2019-06-06 04:02:599701 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9702 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9703 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9704 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519705}
9706
[email protected]61a527782013-02-21 03:58:009707} // namespace test
9708} // namespace net