blob: 38b2afc9482f7baa64c18c4124c3a7d4ea6b3a11 [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
Bence Béky6e243aa2019-12-13 19:01:07981 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56982 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
983 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36984 }
985
Bence Béky6e243aa2019-12-13 19:01:07986 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
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éky6e243aa2019-12-13 19:01:07991 quic::QuicStreamId GetQpackDecoderStreamId() const {
992 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
993 version_.transport_version, 1);
994 }
995
996 std::string StreamCancellationQpackDecoderInstruction(int n) const {
997 const quic::QuicStreamId cancelled_stream_id =
998 GetNthClientInitiatedBidirectionalStreamId(n);
999 EXPECT_LT(cancelled_stream_id, 63u);
1000
1001 const unsigned char opcode = 0x40;
1002 return {opcode | static_cast<unsigned char>(cancelled_stream_id)};
1003 }
1004
Bence Béky230ac612017-08-30 19:17:081005 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:491006 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:081007 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:491008 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:081009 }
1010
Nick Harper23290b82019-05-02 00:02:561011 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:051012 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561013 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011014 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221015 MockQuicContext context_;
alyssar2adf3ac2016-05-03 17:12:581016 QuicTestPacketMaker client_maker_;
1017 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091018 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421019 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001020 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561021 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051022 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431023 MockHostResolver host_resolver_;
1024 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111025 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421026 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231027 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381028 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071029 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:591030 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421031 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491032 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411033 HttpNetworkSession::Params session_params_;
1034 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191035 HttpRequestInfo request_;
Matt Muellerd9342e3a2019-11-26 01:41:141036 RecordingBoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421037 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561038 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031039 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121040
1041 private:
1042 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1043 const std::string& expected,
bnc62a44f022015-04-02 15:59:411044 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271045 uint16_t port,
1046 const std::string& status_line) {
bnc691fda62016-08-12 00:43:161047 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091048 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161049 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091050 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1051 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161052 RunTransaction(&trans);
David Schinazif832cb82019-11-08 22:25:271053 CheckWasQuicResponse(&trans, status_line);
bnc691fda62016-08-12 00:43:161054 CheckResponsePort(&trans, port);
1055 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091056 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471057 if (used_proxy) {
1058 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1059 } else {
1060 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1061 }
tbansal7cec3812015-02-05 21:25:121062 }
David Schinazif832cb82019-11-08 22:25:271063
1064 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1065 const std::string& expected,
1066 bool used_proxy,
1067 uint16_t port) {
1068 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1069 "HTTP/1.1 200 OK");
1070 }
[email protected]61a527782013-02-21 03:58:001071};
1072
David Schinazi09e9a6012019-10-03 17:37:571073INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1074 QuicNetworkTransactionTest,
1075 ::testing::ValuesIn(GetTestParams()),
1076 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201077
Shivani Sharma8ae506c2019-07-21 21:08:271078// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1079// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1080
Ryan Hamiltona64a5bcf2017-11-30 07:35:281081TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381082 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281083 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381084 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281085 HostPortPair::FromString("mail.example.org:443"));
1086 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271087 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281088
Ryan Hamiltonabad59e2019-06-06 04:02:591089 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251090 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231091 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281092 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1093 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1094 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1095
1096 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1097
1098 CreateSession();
1099
1100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1101 TestCompletionCallback callback;
1102 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1104 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1105
1106 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1107 -ERR_INTERNET_DISCONNECTED, 1);
1108 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1109 -ERR_INTERNET_DISCONNECTED, 1);
1110}
1111
1112TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381113 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281114 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381115 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281116 HostPortPair::FromString("mail.example.org:443"));
1117 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271118 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281119
Ryan Hamiltonabad59e2019-06-06 04:02:591120 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251121 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231122 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281123 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1124 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1125 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1126
1127 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1128
1129 CreateSession();
1130
1131 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1132 TestCompletionCallback callback;
1133 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1134 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1135 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1136
1137 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1138 -ERR_INTERNET_DISCONNECTED, 1);
1139 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1140 -ERR_INTERNET_DISCONNECTED, 1);
1141}
1142
tbansal180587c2017-02-16 15:13:231143TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381144 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231145 HostPortPair::FromString("mail.example.org:443"));
1146
Ryan Hamiltonabad59e2019-06-06 04:02:591147 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231148 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251149 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231150 mock_quic_data.AddWrite(SYNCHRONOUS,
1151 ConstructInitialSettingsPacket(packet_num++));
1152 }
rch5cb522462017-04-25 20:18:361153 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231154 SYNCHRONOUS,
1155 ConstructClientRequestHeadersPacket(
1156 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1157 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431158 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331159 ASYNC, ConstructServerResponseHeadersPacket(
1160 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1161 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431162 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331163 mock_quic_data.AddRead(
1164 ASYNC, ConstructServerDataPacket(
1165 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171166 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231167 mock_quic_data.AddWrite(SYNCHRONOUS,
1168 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231169 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1170
1171 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1172
1173 CreateSession();
1174 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1175
1176 EXPECT_FALSE(
1177 test_socket_performance_watcher_factory_.rtt_notification_received());
1178 SendRequestAndExpectQuicResponse("hello!");
1179 EXPECT_TRUE(
1180 test_socket_performance_watcher_factory_.rtt_notification_received());
1181}
1182
1183TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381184 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231185 HostPortPair::FromString("mail.example.org:443"));
1186
Ryan Hamiltonabad59e2019-06-06 04:02:591187 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231188 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251189 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231190 mock_quic_data.AddWrite(SYNCHRONOUS,
1191 ConstructInitialSettingsPacket(packet_num++));
1192 }
rch5cb522462017-04-25 20:18:361193 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231194 SYNCHRONOUS,
1195 ConstructClientRequestHeadersPacket(
1196 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1197 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431198 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331199 ASYNC, ConstructServerResponseHeadersPacket(
1200 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1201 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431202 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331203 mock_quic_data.AddRead(
1204 ASYNC, ConstructServerDataPacket(
1205 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171206 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231207 mock_quic_data.AddWrite(SYNCHRONOUS,
1208 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231209 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1210
1211 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1212
1213 CreateSession();
1214 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1215
1216 EXPECT_FALSE(
1217 test_socket_performance_watcher_factory_.rtt_notification_received());
1218 SendRequestAndExpectQuicResponse("hello!");
1219 EXPECT_FALSE(
1220 test_socket_performance_watcher_factory_.rtt_notification_received());
1221}
1222
[email protected]1e960032013-12-20 19:00:201223TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381224 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571225 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471226
Ryan Hamiltonabad59e2019-06-06 04:02:591227 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231228 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251229 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231230 mock_quic_data.AddWrite(SYNCHRONOUS,
1231 ConstructInitialSettingsPacket(packet_num++));
1232 }
rch5cb522462017-04-25 20:18:361233 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231234 SYNCHRONOUS,
1235 ConstructClientRequestHeadersPacket(
1236 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1237 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431238 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331239 ASYNC, ConstructServerResponseHeadersPacket(
1240 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1241 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431242 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331243 mock_quic_data.AddRead(
1244 ASYNC, ConstructServerDataPacket(
1245 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171246 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231247 mock_quic_data.AddWrite(SYNCHRONOUS,
1248 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591249 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471250
rcha5399e02015-04-21 19:32:041251 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471252
[email protected]4dca587c2013-03-07 16:54:471253 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471254
[email protected]aa9b14d2013-05-10 23:45:191255 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471256
[email protected]98b20ce2013-05-10 05:55:261257 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541258 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261259 EXPECT_LT(0u, entries.size());
1260
1261 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291262 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001263 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1264 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261265 EXPECT_LT(0, pos);
1266
rchfd527212015-08-25 00:41:261267 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291268 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261269 entries, 0,
mikecirone8b85c432016-09-08 19:11:001270 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1271 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261272 EXPECT_LT(0, pos);
1273
Eric Roman79cc7552019-07-19 02:17:541274 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261275
rchfd527212015-08-25 00:41:261276 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1277 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001278 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1279 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261280 EXPECT_LT(0, pos);
1281
[email protected]98b20ce2013-05-10 05:55:261282 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291283 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001284 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1285 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261286 EXPECT_LT(0, pos);
1287
Eric Roman79cc7552019-07-19 02:17:541288 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251289 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451290 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1291 static_cast<quic::QuicStreamId>(log_stream_id));
1292 } else {
1293 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1294 static_cast<quic::QuicStreamId>(log_stream_id));
1295 }
[email protected]4dca587c2013-03-07 16:54:471296}
1297
rchbd089ab2017-05-26 23:05:041298TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381299 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041300 HostPortPair::FromString("mail.example.org:443"));
1301
Ryan Hamiltonabad59e2019-06-06 04:02:591302 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231303 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251304 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231305 mock_quic_data.AddWrite(SYNCHRONOUS,
1306 ConstructInitialSettingsPacket(packet_num++));
1307 }
rchbd089ab2017-05-26 23:05:041308 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231309 SYNCHRONOUS,
1310 ConstructClientRequestHeadersPacket(
1311 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1312 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131313 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041314 response_headers["key1"] = std::string(30000, 'A');
1315 response_headers["key2"] = std::string(30000, 'A');
1316 response_headers["key3"] = std::string(30000, 'A');
1317 response_headers["key4"] = std::string(30000, 'A');
1318 response_headers["key5"] = std::string(30000, 'A');
1319 response_headers["key6"] = std::string(30000, 'A');
1320 response_headers["key7"] = std::string(30000, 'A');
1321 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451322 quic::QuicStreamId stream_id;
1323 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251324 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451325 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281326 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451327 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451328 } else {
1329 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1330 spdy::SpdyHeadersIR headers_frame(
1331 GetNthClientInitiatedBidirectionalStreamId(0),
1332 std::move(response_headers));
1333 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1334 spdy::SpdySerializedFrame spdy_frame =
1335 response_framer.SerializeFrame(headers_frame);
1336 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1337 }
rchbd089ab2017-05-26 23:05:041338
Fan Yangac867502019-01-28 21:10:231339 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041340 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451341 for (size_t offset = 0; offset < response_data.length();
1342 offset += chunk_size) {
1343 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431344 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451345 ASYNC, ConstructServerDataPacket(
1346 packet_number++, stream_id, false, false,
1347 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041348 }
1349
Victor Vasiliev076657c2019-03-12 02:46:431350 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041351 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331352 ASYNC, ConstructServerDataPacket(
1353 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171354 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041355 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431356 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231357 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1358 mock_quic_data.AddWrite(
1359 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041360
1361 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1362
1363 CreateSession();
1364
1365 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421366 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1367 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041368}
1369
1370TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381371 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1372 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041373 HostPortPair::FromString("mail.example.org:443"));
1374
Ryan Hamiltonabad59e2019-06-06 04:02:591375 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231376 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251377 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231378 mock_quic_data.AddWrite(SYNCHRONOUS,
1379 ConstructInitialSettingsPacket(packet_num++));
1380 }
rchbd089ab2017-05-26 23:05:041381 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231382 SYNCHRONOUS,
1383 ConstructClientRequestHeadersPacket(
1384 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1385 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451386
Ryan Hamilton0239aac2018-05-19 00:03:131387 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041388 response_headers["key1"] = std::string(30000, 'A');
1389 response_headers["key2"] = std::string(30000, 'A');
1390 response_headers["key3"] = std::string(30000, 'A');
1391 response_headers["key4"] = std::string(30000, 'A');
1392 response_headers["key5"] = std::string(30000, 'A');
1393 response_headers["key6"] = std::string(30000, 'A');
1394 response_headers["key7"] = std::string(30000, 'A');
1395 response_headers["key8"] = std::string(30000, 'A');
1396 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451397
1398 quic::QuicStreamId stream_id;
1399 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251400 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451401 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281402 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451403 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451404 } else {
1405 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1406 spdy::SpdyHeadersIR headers_frame(
1407 GetNthClientInitiatedBidirectionalStreamId(0),
1408 std::move(response_headers));
1409 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1410 spdy::SpdySerializedFrame spdy_frame =
1411 response_framer.SerializeFrame(headers_frame);
1412 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1413 }
rchbd089ab2017-05-26 23:05:041414
Fan Yangac867502019-01-28 21:10:231415 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041416 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451417 for (size_t offset = 0; offset < response_data.length();
1418 offset += chunk_size) {
1419 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431420 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451421 ASYNC, ConstructServerDataPacket(
1422 packet_number++, stream_id, false, false,
1423 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041424 }
1425
Victor Vasiliev076657c2019-03-12 02:46:431426 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411427
rchbd089ab2017-05-26 23:05:041428 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331429 ASYNC, ConstructServerDataPacket(
1430 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171431 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041432 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231433 mock_quic_data.AddWrite(ASYNC,
1434 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431435 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331436 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231437 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331438 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041439
1440 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1441
1442 CreateSession();
1443
1444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1445 TestCompletionCallback callback;
1446 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1448 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1449}
1450
rcha2bd44b2016-07-02 00:42:551451TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381452 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551453
Ryan Hamilton9835e662018-08-02 05:36:271454 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551455
Ryan Hamiltonabad59e2019-06-06 04:02:591456 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231457 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251458 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231459 mock_quic_data.AddWrite(SYNCHRONOUS,
1460 ConstructInitialSettingsPacket(packet_num++));
1461 }
rch5cb522462017-04-25 20:18:361462 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231463 SYNCHRONOUS,
1464 ConstructClientRequestHeadersPacket(
1465 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1466 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431467 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331468 ASYNC, ConstructServerResponseHeadersPacket(
1469 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1470 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431471 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331472 mock_quic_data.AddRead(
1473 ASYNC, ConstructServerDataPacket(
1474 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171475 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231476 mock_quic_data.AddWrite(SYNCHRONOUS,
1477 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551478 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1479
1480 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1481
1482 CreateSession();
1483
1484 SendRequestAndExpectQuicResponse("hello!");
1485 EXPECT_TRUE(
1486 test_socket_performance_watcher_factory_.rtt_notification_received());
1487}
1488
David Schinazif832cb82019-11-08 22:25:271489// Regression test for https://crbug.com/695225
1490TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381491 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271492
1493 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1494
1495 MockQuicData mock_quic_data(version_);
1496 int packet_num = 1;
1497 if (VersionUsesHttp3(version_.transport_version)) {
1498 mock_quic_data.AddWrite(SYNCHRONOUS,
1499 ConstructInitialSettingsPacket(packet_num++));
1500 }
1501 mock_quic_data.AddWrite(
1502 SYNCHRONOUS,
1503 ConstructClientRequestHeadersPacket(
1504 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1505 true, GetRequestHeaders("GET", "https", "/")));
1506 mock_quic_data.AddRead(
1507 ASYNC, ConstructServerResponseHeadersPacket(
1508 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1509 GetResponseHeaders("408 Request Timeout")));
1510 std::string header = ConstructDataHeader(6);
1511 mock_quic_data.AddRead(
1512 ASYNC, ConstructServerDataPacket(
1513 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1514 header + "hello!"));
1515 mock_quic_data.AddWrite(SYNCHRONOUS,
1516 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1517 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1518
1519 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1520
1521 CreateSession();
1522
1523 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1524}
1525
[email protected]cf3e3cd62014-02-05 16:16:161526TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411527 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591528 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491529 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161530
Ryan Hamiltonabad59e2019-06-06 04:02:591531 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231532 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251533 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231534 mock_quic_data.AddWrite(SYNCHRONOUS,
1535 ConstructInitialSettingsPacket(packet_num++));
1536 }
rch5cb522462017-04-25 20:18:361537 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231538 SYNCHRONOUS,
1539 ConstructClientRequestHeadersPacket(
1540 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1541 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431542 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331543 ASYNC, ConstructServerResponseHeadersPacket(
1544 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1545 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431546 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331547 mock_quic_data.AddRead(
1548 ASYNC, ConstructServerDataPacket(
1549 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171550 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231551 mock_quic_data.AddWrite(SYNCHRONOUS,
1552 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501553 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591554 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161555
rcha5399e02015-04-21 19:32:041556 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161557
tbansal0f56a39a2016-04-07 22:03:381558 EXPECT_FALSE(
1559 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161560 // There is no need to set up an alternate protocol job, because
1561 // no attempt will be made to speak to the proxy over TCP.
1562
rch9ae5b3b2016-02-11 00:36:291563 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161564 CreateSession();
1565
bnc62a44f022015-04-02 15:59:411566 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381567 EXPECT_TRUE(
1568 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161569}
1570
bnc313ba9c2015-06-11 15:42:311571// Regression test for https://crbug.com/492458. Test that for an HTTP
1572// connection through a QUIC proxy, the certificate exhibited by the proxy is
1573// checked against the proxy hostname, not the origin hostname.
1574TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291575 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311576 const std::string proxy_host = "www.example.org";
1577
mmenke6ddfbea2017-05-31 21:48:411578 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591579 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491580 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311581
alyssar2adf3ac2016-05-03 17:12:581582 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591583 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231584 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251585 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231586 mock_quic_data.AddWrite(SYNCHRONOUS,
1587 ConstructInitialSettingsPacket(packet_num++));
1588 }
rch5cb522462017-04-25 20:18:361589 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231590 SYNCHRONOUS,
1591 ConstructClientRequestHeadersPacket(
1592 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1593 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431594 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331595 ASYNC, ConstructServerResponseHeadersPacket(
1596 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1597 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431598 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331599 mock_quic_data.AddRead(
1600 ASYNC, ConstructServerDataPacket(
1601 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171602 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231603 mock_quic_data.AddWrite(SYNCHRONOUS,
1604 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501605 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591606 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311607 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1608
1609 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291610 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311611 ASSERT_TRUE(cert.get());
1612 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241613 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1614 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311615 ProofVerifyDetailsChromium verify_details;
1616 verify_details.cert_verify_result.verified_cert = cert;
1617 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561618 ProofVerifyDetailsChromium verify_details2;
1619 verify_details2.cert_verify_result.verified_cert = cert;
1620 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311621
1622 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091623 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321624 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271625 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311626 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1627}
1628
rchbe69cb902016-02-11 01:10:481629TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381630 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481631 HostPortPair origin("www.example.org", 443);
1632 HostPortPair alternative("mail.example.org", 443);
1633
1634 base::FilePath certs_dir = GetTestCertsDirectory();
1635 scoped_refptr<X509Certificate> cert(
1636 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1637 ASSERT_TRUE(cert.get());
1638 // TODO(rch): the connection should be "to" the origin, so if the cert is
1639 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241640 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1641 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481642 ProofVerifyDetailsChromium verify_details;
1643 verify_details.cert_verify_result.verified_cert = cert;
1644 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1645
alyssar2adf3ac2016-05-03 17:12:581646 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591647 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021648
Renjie Tangaadb84b2019-08-31 01:00:231649 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251650 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231651 mock_quic_data.AddWrite(SYNCHRONOUS,
1652 ConstructInitialSettingsPacket(packet_num++));
1653 }
rch5cb522462017-04-25 20:18:361654 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231655 SYNCHRONOUS,
1656 ConstructClientRequestHeadersPacket(
1657 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1658 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431659 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331660 ASYNC, ConstructServerResponseHeadersPacket(
1661 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1662 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431663 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331664 mock_quic_data.AddRead(
1665 ASYNC, ConstructServerDataPacket(
1666 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171667 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231668 mock_quic_data.AddWrite(SYNCHRONOUS,
1669 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481670 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1671 mock_quic_data.AddRead(ASYNC, 0);
1672 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1673
1674 request_.url = GURL("https://" + origin.host());
1675 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271676 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091677 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321678 CreateSession();
rchbe69cb902016-02-11 01:10:481679
1680 SendRequestAndExpectQuicResponse("hello!");
1681}
1682
zhongyief3f4ce52017-07-05 23:53:281683TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561684 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281685 // Add support for another QUIC version besides |version_|. Also find a
1686 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561687 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281688 if (version == version_)
1689 continue;
1690 if (supported_versions_.size() != 2) {
1691 supported_versions_.push_back(version);
1692 continue;
1693 }
1694 unsupported_version = version;
1695 break;
1696 }
Nick Harper23290b82019-05-02 00:02:561697 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281698
1699 // Set up alternative service to use QUIC with a version that is not
1700 // supported.
1701 url::SchemeHostPort server(request_.url);
1702 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1703 443);
1704 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491705 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071706 server, NetworkIsolationKey(), alternative_service, expiration,
1707 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281708
1709 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491710 http_server_properties_->GetAlternativeServiceInfos(
1711 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281712 EXPECT_EQ(1u, alt_svc_info_vector.size());
1713 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1714 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1715 EXPECT_EQ(unsupported_version,
1716 alt_svc_info_vector[0].advertised_versions()[0]);
1717
1718 // First request should still be sent via TCP as the QUIC version advertised
1719 // in the stored AlternativeService is not supported by the client. However,
1720 // the response from the server will advertise new Alt-Svc with supported
1721 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061722 quic::ParsedQuicVersionVector versions;
1723 for (quic::QuicTransportVersion version :
1724 quic::AllSupportedTransportVersions()) {
1725 versions.push_back(
1726 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1727 }
zhongyief3f4ce52017-07-05 23:53:281728 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061729 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281730 std::string altsvc_header =
1731 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1732 advertised_versions_list_str.c_str());
1733 MockRead http_reads[] = {
1734 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1735 MockRead("hello world"),
1736 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1737 MockRead(ASYNC, OK)};
1738
Ryan Sleevib8d7ea02018-05-07 20:01:011739 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281740 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081741 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281742 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1743
1744 // Second request should be sent via QUIC as a new list of verions supported
1745 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591746 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231747 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251748 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231749 mock_quic_data.AddWrite(SYNCHRONOUS,
1750 ConstructInitialSettingsPacket(packet_num++));
1751 }
zhongyief3f4ce52017-07-05 23:53:281752 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231753 SYNCHRONOUS,
1754 ConstructClientRequestHeadersPacket(
1755 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1756 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431757 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331758 ASYNC, ConstructServerResponseHeadersPacket(
1759 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1760 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431761 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331762 mock_quic_data.AddRead(
1763 ASYNC, ConstructServerDataPacket(
1764 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171765 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231766 mock_quic_data.AddWrite(SYNCHRONOUS,
1767 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281768 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1769 mock_quic_data.AddRead(ASYNC, 0); // EOF
1770
1771 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1772
1773 AddHangingNonAlternateProtocolSocketData();
1774
1775 CreateSession(supported_versions_);
1776
1777 SendRequestAndExpectHttpResponse("hello world");
1778 SendRequestAndExpectQuicResponse("hello!");
1779
1780 // Check alternative service list is updated with new versions.
1781 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491782 session_->http_server_properties()->GetAlternativeServiceInfos(
1783 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281784 EXPECT_EQ(1u, alt_svc_info_vector.size());
1785 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1786 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1787 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561788 std::sort(
1789 supported_versions_.begin(), supported_versions_.end(),
1790 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1791 return a.transport_version < b.transport_version;
1792 });
zhongyief3f4ce52017-07-05 23:53:281793 EXPECT_EQ(supported_versions_[0],
1794 alt_svc_info_vector[0].advertised_versions()[0]);
1795 EXPECT_EQ(supported_versions_[1],
1796 alt_svc_info_vector[0].advertised_versions()[1]);
1797}
1798
bncaccd4962017-04-06 21:00:261799// Regression test for https://crbug.com/546991.
1800// The server might not be able to serve a request on an alternative connection,
1801// and might send a 421 Misdirected Request response status to indicate this.
1802// HttpNetworkTransaction should reset the request and retry without using
1803// alternative services.
1804TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1805 // Set up alternative service to use QUIC.
1806 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1807 // that overrides |enable_alternative_services|.
1808 url::SchemeHostPort server(request_.url);
1809 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1810 443);
1811 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491812 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071813 server, NetworkIsolationKey(), alternative_service, expiration,
1814 supported_versions_);
bncaccd4962017-04-06 21:00:261815
davidbena4449722017-05-05 23:30:531816 // First try: The alternative job uses QUIC and reports an HTTP 421
1817 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1818 // paused at Connect(), so it will never exit the socket pool. This ensures
1819 // that the alternate job always wins the race and keeps whether the
1820 // |http_data| exits the socket pool before the main job is aborted
1821 // deterministic. The first main job gets aborted without the socket pool ever
1822 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591823 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231824 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251825 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231826 mock_quic_data.AddWrite(SYNCHRONOUS,
1827 ConstructInitialSettingsPacket(packet_num++));
1828 }
rch5cb522462017-04-25 20:18:361829 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231830 SYNCHRONOUS,
1831 ConstructClientRequestHeadersPacket(
1832 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1833 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331834 mock_quic_data.AddRead(
1835 ASYNC, ConstructServerResponseHeadersPacket(
1836 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021837 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261838 mock_quic_data.AddRead(ASYNC, OK);
1839 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1840
davidbena4449722017-05-05 23:30:531841 // Second try: The main job uses TCP, and there is no alternate job. Once the
1842 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1843 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261844 // Note that if there was an alternative QUIC Job created for the second try,
1845 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1846 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531847 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1848 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1849 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1850 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1851 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1852 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011853 reads, writes);
bncaccd4962017-04-06 21:00:261854 socket_factory_.AddSocketDataProvider(&http_data);
1855 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1856
bncaccd4962017-04-06 21:00:261857 CreateSession();
1858 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531859
1860 // Run until |mock_quic_data| has failed and |http_data| has paused.
1861 TestCompletionCallback callback;
1862 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1863 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1864 base::RunLoop().RunUntilIdle();
1865
1866 // |mock_quic_data| must have run to completion.
1867 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1868 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1869
1870 // Now that the QUIC data has been consumed, unblock |http_data|.
1871 http_data.socket()->OnConnectComplete(MockConnect());
1872
1873 // The retry logic must hide the 421 status. The transaction succeeds on
1874 // |http_data|.
1875 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261876 CheckWasHttpResponse(&trans);
1877 CheckResponsePort(&trans, 443);
1878 CheckResponseData(&trans, "hello!");
1879}
1880
[email protected]1e960032013-12-20 19:00:201881TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381882 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571883 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301884
Ryan Hamiltonabad59e2019-06-06 04:02:591885 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251886 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231887 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401888 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021889 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591890 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251891 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231892 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301893 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401894 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431895 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401896
1897 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1898 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301899
1900 CreateSession();
1901
tbansal0f56a39a2016-04-07 22:03:381902 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401903 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401905 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161906 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1908 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381909 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531910
1911 NetErrorDetails details;
1912 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521913 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401914 }
[email protected]cebe3282013-05-22 23:49:301915}
1916
tbansalc8a94ea2015-11-02 23:58:511917TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1918 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381919 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571920 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511921
1922 MockRead http_reads[] = {
1923 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1924 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1925 MockRead(ASYNC, OK)};
1926
Ryan Sleevib8d7ea02018-05-07 20:01:011927 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511928 socket_factory_.AddSocketDataProvider(&data);
1929 SSLSocketDataProvider ssl(ASYNC, OK);
1930 socket_factory_.AddSSLSocketDataProvider(&ssl);
1931
1932 CreateSession();
1933
1934 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381935 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511936}
1937
bncc958faa2015-07-31 18:14:521938TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521939 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561940 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1941 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521942 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1943 MockRead(ASYNC, OK)};
1944
Ryan Sleevib8d7ea02018-05-07 20:01:011945 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521946 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081947 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561948 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521949
Ryan Hamiltonabad59e2019-06-06 04:02:591950 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231951 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251952 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231953 mock_quic_data.AddWrite(SYNCHRONOUS,
1954 ConstructInitialSettingsPacket(packet_num++));
1955 }
rch5cb522462017-04-25 20:18:361956 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231957 SYNCHRONOUS,
1958 ConstructClientRequestHeadersPacket(
1959 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1960 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431961 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331962 ASYNC, ConstructServerResponseHeadersPacket(
1963 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1964 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431965 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331966 mock_quic_data.AddRead(
1967 ASYNC, ConstructServerDataPacket(
1968 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171969 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231970 mock_quic_data.AddWrite(SYNCHRONOUS,
1971 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:521972 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591973 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521974
1975 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1976
rtennetib8e80fb2016-05-16 00:12:091977 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321978 CreateSession();
bncc958faa2015-07-31 18:14:521979
1980 SendRequestAndExpectHttpResponse("hello world");
1981 SendRequestAndExpectQuicResponse("hello!");
1982}
1983
Ryan Hamilton64f21d52019-08-31 07:10:511984TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
1985 std::string alt_svc_header =
1986 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
1987 MockRead http_reads[] = {
1988 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
1989 MockRead("hello world"),
1990 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1991 MockRead(ASYNC, OK)};
1992
1993 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
1994 socket_factory_.AddSocketDataProvider(&http_data);
1995 AddCertificate(&ssl_data_);
1996 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1997
1998 MockQuicData mock_quic_data(version_);
1999 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252000 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512001 mock_quic_data.AddWrite(SYNCHRONOUS,
2002 ConstructInitialSettingsPacket(packet_num++));
2003 }
2004 mock_quic_data.AddWrite(
2005 SYNCHRONOUS,
2006 ConstructClientRequestHeadersPacket(
2007 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2008 true, GetRequestHeaders("GET", "https", "/")));
2009 mock_quic_data.AddRead(
2010 ASYNC, ConstructServerResponseHeadersPacket(
2011 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2012 GetResponseHeaders("200 OK")));
2013 std::string header = ConstructDataHeader(6);
2014 mock_quic_data.AddRead(
2015 ASYNC, ConstructServerDataPacket(
2016 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2017 header + "hello!"));
2018 mock_quic_data.AddWrite(SYNCHRONOUS,
2019 ConstructClientAckPacket(packet_num++, 2, 1, 1));
2020 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2021 mock_quic_data.AddRead(ASYNC, 0); // EOF
2022
2023 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2024
2025 AddHangingNonAlternateProtocolSocketData();
2026 CreateSession();
2027
2028 SendRequestAndExpectHttpResponse("hello world");
2029 SendRequestAndExpectQuicResponse("hello!");
2030}
2031
Matt Menke3233d8f22019-08-20 21:01:492032// Much like above, but makes sure NetworkIsolationKey is respected.
2033TEST_P(QuicNetworkTransactionTest,
2034 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2035 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052036 feature_list.InitWithFeatures(
2037 // enabled_features
2038 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2039 features::kPartitionConnectionsByNetworkIsolationKey},
2040 // disabled_features
2041 {});
Matt Menke3233d8f22019-08-20 21:01:492042 // Since HttpServerProperties caches the feature value, have to create a new
2043 // one.
2044 http_server_properties_ = std::make_unique<HttpServerProperties>();
2045
2046 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2047 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2048 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2049 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2050
2051 MockRead http_reads[] = {
2052 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2053 MockRead("hello world"),
2054 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2055 MockRead(ASYNC, OK)};
2056
2057 AddCertificate(&ssl_data_);
2058
2059 // Request with empty NetworkIsolationKey.
2060 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2061 socket_factory_.AddSocketDataProvider(&http_data1);
2062 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2063
2064 // First request with kNetworkIsolationKey1.
2065 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2066 socket_factory_.AddSocketDataProvider(&http_data2);
2067 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2068
2069 // Request with kNetworkIsolationKey2.
2070 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2071 socket_factory_.AddSocketDataProvider(&http_data3);
2072 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2073
2074 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2075 // alternative service infrmation has been received in this context before.
2076 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232077 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252078 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232079 mock_quic_data.AddWrite(SYNCHRONOUS,
2080 ConstructInitialSettingsPacket(packet_num++));
2081 }
Matt Menke3233d8f22019-08-20 21:01:492082 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232083 SYNCHRONOUS,
2084 ConstructClientRequestHeadersPacket(
2085 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2086 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492087 mock_quic_data.AddRead(
2088 ASYNC, ConstructServerResponseHeadersPacket(
2089 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2090 GetResponseHeaders("200 OK")));
2091 std::string header = ConstructDataHeader(6);
2092 mock_quic_data.AddRead(
2093 ASYNC, ConstructServerDataPacket(
2094 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2095 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232096 mock_quic_data.AddWrite(SYNCHRONOUS,
2097 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492098 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2099 mock_quic_data.AddRead(ASYNC, 0); // EOF
2100
2101 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2102
2103 AddHangingNonAlternateProtocolSocketData();
2104 CreateSession();
2105
2106 // This is first so that the test fails if alternative service info is
2107 // written with the right NetworkIsolationKey, but always queried with an
2108 // empty one.
2109 request_.network_isolation_key = NetworkIsolationKey();
2110 SendRequestAndExpectHttpResponse("hello world");
2111 request_.network_isolation_key = kNetworkIsolationKey1;
2112 SendRequestAndExpectHttpResponse("hello world");
2113 request_.network_isolation_key = kNetworkIsolationKey2;
2114 SendRequestAndExpectHttpResponse("hello world");
2115
2116 // Only use QUIC when using a NetworkIsolationKey which has been used when
2117 // alternative service information was received.
2118 request_.network_isolation_key = kNetworkIsolationKey1;
2119 SendRequestAndExpectQuicResponse("hello!");
2120}
2121
zhongyia00ca012017-07-06 23:36:392122TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2123 // Both server advertises and client supports two QUIC versions.
2124 // Only |version_| is advertised and supported.
2125 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2126 // PacketMakers are using |version_|.
2127
2128 // Add support for another QUIC version besides |version_| on the client side.
2129 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562130 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2131 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392132 if (version == version_)
2133 continue;
2134 if (supported_versions_.size() != 2) {
2135 supported_versions_.push_back(version);
2136 continue;
2137 }
2138 advertised_version_2 = version;
2139 break;
2140 }
Nick Harper23290b82019-05-02 00:02:562141 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392142
Nick Harper23290b82019-05-02 00:02:562143 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
2144 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2145 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392146
2147 MockRead http_reads[] = {
2148 MockRead("HTTP/1.1 200 OK\r\n"),
2149 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2150 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2151 MockRead(ASYNC, OK)};
2152
Ryan Sleevib8d7ea02018-05-07 20:01:012153 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392154 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082155 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392156 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2157
Ryan Hamiltonabad59e2019-06-06 04:02:592158 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232159 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252160 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232161 mock_quic_data.AddWrite(SYNCHRONOUS,
2162 ConstructInitialSettingsPacket(packet_num++));
2163 }
zhongyia00ca012017-07-06 23:36:392164 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232165 SYNCHRONOUS,
2166 ConstructClientRequestHeadersPacket(
2167 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2168 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432169 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332170 ASYNC, ConstructServerResponseHeadersPacket(
2171 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2172 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432173 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332174 mock_quic_data.AddRead(
2175 ASYNC, ConstructServerDataPacket(
2176 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172177 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232178 mock_quic_data.AddWrite(SYNCHRONOUS,
2179 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392180 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2181 mock_quic_data.AddRead(ASYNC, 0); // EOF
2182
2183 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2184
2185 AddHangingNonAlternateProtocolSocketData();
2186 CreateSession(supported_versions_);
2187
2188 SendRequestAndExpectHttpResponse("hello world");
2189 SendRequestAndExpectQuicResponse("hello!");
2190}
2191
2192TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
2193 // Client and server mutually support more than one QUIC_VERSION.
2194 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2195 // which is verified as the PacketMakers are using |version_|.
2196
Nick Harper23290b82019-05-02 00:02:562197 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2198 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392199 if (version == version_)
2200 continue;
2201 common_version_2 = version;
2202 break;
2203 }
Nick Harper23290b82019-05-02 00:02:562204 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392205
2206 supported_versions_.push_back(
2207 common_version_2); // Supported but unpreferred.
2208
2209 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562210 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2211 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392212
2213 MockRead http_reads[] = {
2214 MockRead("HTTP/1.1 200 OK\r\n"),
2215 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2216 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2217 MockRead(ASYNC, OK)};
2218
Ryan Sleevib8d7ea02018-05-07 20:01:012219 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392220 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082221 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392222 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2223
Ryan Hamiltonabad59e2019-06-06 04:02:592224 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232225 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252226 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232227 mock_quic_data.AddWrite(SYNCHRONOUS,
2228 ConstructInitialSettingsPacket(packet_num++));
2229 }
zhongyia00ca012017-07-06 23:36:392230 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232231 SYNCHRONOUS,
2232 ConstructClientRequestHeadersPacket(
2233 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2234 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432235 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332236 ASYNC, ConstructServerResponseHeadersPacket(
2237 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2238 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432239 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332240 mock_quic_data.AddRead(
2241 ASYNC, ConstructServerDataPacket(
2242 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172243 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232244 mock_quic_data.AddWrite(SYNCHRONOUS,
2245 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392246 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2247 mock_quic_data.AddRead(ASYNC, 0); // EOF
2248
2249 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2250
2251 AddHangingNonAlternateProtocolSocketData();
2252 CreateSession(supported_versions_);
2253
2254 SendRequestAndExpectHttpResponse("hello world");
2255 SendRequestAndExpectQuicResponse("hello!");
2256}
2257
rchf47265dc2016-03-21 21:33:122258TEST_P(QuicNetworkTransactionTest,
2259 UseAlternativeServiceWithProbabilityForQuic) {
2260 MockRead http_reads[] = {
2261 MockRead("HTTP/1.1 200 OK\r\n"),
2262 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2263 MockRead("hello world"),
2264 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2265 MockRead(ASYNC, OK)};
2266
Ryan Sleevib8d7ea02018-05-07 20:01:012267 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122268 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082269 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122270 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2271
Ryan Hamiltonabad59e2019-06-06 04:02:592272 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232273 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252274 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232275 mock_quic_data.AddWrite(SYNCHRONOUS,
2276 ConstructInitialSettingsPacket(packet_num++));
2277 }
rch5cb522462017-04-25 20:18:362278 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232279 SYNCHRONOUS,
2280 ConstructClientRequestHeadersPacket(
2281 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2282 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432283 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332284 ASYNC, ConstructServerResponseHeadersPacket(
2285 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2286 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432287 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332288 mock_quic_data.AddRead(
2289 ASYNC, ConstructServerDataPacket(
2290 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172291 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232292 mock_quic_data.AddWrite(SYNCHRONOUS,
2293 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122294 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2295 mock_quic_data.AddRead(ASYNC, 0); // EOF
2296
2297 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2298
rtennetib8e80fb2016-05-16 00:12:092299 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122300 CreateSession();
2301
2302 SendRequestAndExpectHttpResponse("hello world");
2303 SendRequestAndExpectQuicResponse("hello!");
2304}
2305
zhongyi3d4a55e72016-04-22 20:36:462306TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2307 MockRead http_reads[] = {
2308 MockRead("HTTP/1.1 200 OK\r\n"),
2309 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2310 MockRead("hello world"),
2311 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2312 MockRead(ASYNC, OK)};
2313
Ryan Sleevib8d7ea02018-05-07 20:01:012314 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462315 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082316 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462317 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2318
2319 CreateSession();
bncb26024382016-06-29 02:39:452320 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462321 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452322 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462323 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402324 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462325 session_->http_server_properties();
2326 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2327 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2328 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462329 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492330 2u, http_server_properties
2331 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2332 .size());
bncb26024382016-06-29 02:39:452333 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492334 http_server_properties
2335 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2336 .empty());
zhongyi3d4a55e72016-04-22 20:36:462337}
2338
2339TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2340 MockRead http_reads[] = {
2341 MockRead("HTTP/1.1 200 OK\r\n"),
2342 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2343 MockRead("hello world"),
2344 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2345 MockRead(ASYNC, OK)};
2346
Ryan Sleevib8d7ea02018-05-07 20:01:012347 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082348 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462349
2350 socket_factory_.AddSocketDataProvider(&http_data);
2351 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2352 socket_factory_.AddSocketDataProvider(&http_data);
2353 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2354
2355 CreateSession();
2356
2357 // Send https request and set alternative services if response header
2358 // advertises alternative service for mail.example.org.
2359 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402360 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462361 session_->http_server_properties();
2362
2363 const url::SchemeHostPort https_server(request_.url);
2364 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342365 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492366 2u, http_server_properties
2367 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2368 .size());
zhongyi3d4a55e72016-04-22 20:36:462369
2370 // Send http request to the same origin but with diffrent scheme, should not
2371 // use QUIC.
2372 request_.url = GURL("http://mail.example.org:443");
2373 SendRequestAndExpectHttpResponse("hello world");
2374}
2375
zhongyie537a002017-06-27 16:48:212376TEST_P(QuicNetworkTransactionTest,
2377 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442378 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562379 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442380 if (version == version_)
2381 continue;
2382 supported_versions_.push_back(version);
2383 break;
2384 }
2385
Ryan Hamilton8380c652019-06-04 02:25:062386 quic::ParsedQuicVersionVector versions;
2387 for (quic::QuicTransportVersion version :
2388 quic::AllSupportedTransportVersions()) {
2389 versions.push_back(
2390 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2391 }
zhongyie537a002017-06-27 16:48:212392 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062393 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212394 std::string altsvc_header =
2395 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2396 advertised_versions_list_str.c_str());
2397 MockRead http_reads[] = {
2398 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2399 MockRead("hello world"),
2400 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2401 MockRead(ASYNC, OK)};
2402
Ryan Sleevib8d7ea02018-05-07 20:01:012403 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212404 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082405 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212406 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2407
Ryan Hamiltonabad59e2019-06-06 04:02:592408 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232409 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252410 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232411 mock_quic_data.AddWrite(SYNCHRONOUS,
2412 ConstructInitialSettingsPacket(packet_num++));
2413 }
zhongyie537a002017-06-27 16:48:212414 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232415 SYNCHRONOUS,
2416 ConstructClientRequestHeadersPacket(
2417 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2418 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432419 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332420 ASYNC, ConstructServerResponseHeadersPacket(
2421 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2422 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432423 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332424 mock_quic_data.AddRead(
2425 ASYNC, ConstructServerDataPacket(
2426 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172427 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232428 mock_quic_data.AddWrite(SYNCHRONOUS,
2429 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212430 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2431 mock_quic_data.AddRead(ASYNC, 0); // EOF
2432
2433 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2434
2435 AddHangingNonAlternateProtocolSocketData();
2436
zhongyi86838d52017-06-30 01:19:442437 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212438
2439 SendRequestAndExpectHttpResponse("hello world");
2440 SendRequestAndExpectQuicResponse("hello!");
2441
2442 // Check alternative service is set with only mutually supported versions.
2443 const url::SchemeHostPort https_server(request_.url);
2444 const AlternativeServiceInfoVector alt_svc_info_vector =
2445 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492446 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212447 EXPECT_EQ(1u, alt_svc_info_vector.size());
2448 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2449 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2450 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562451 std::sort(
2452 supported_versions_.begin(), supported_versions_.end(),
2453 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2454 return a.transport_version < b.transport_version;
2455 });
zhongyi86838d52017-06-30 01:19:442456 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212457 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442458 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212459 alt_svc_info_vector[0].advertised_versions()[1]);
2460}
2461
danzh3134c2562016-08-12 14:07:522462TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562463 std::string altsvc_header = base::StringPrintf(
2464 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072465 MockRead http_reads[] = {
2466 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2467 MockRead("hello world"),
2468 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2469 MockRead(ASYNC, OK)};
2470
Ryan Sleevib8d7ea02018-05-07 20:01:012471 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072472 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082473 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072474 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2475
Ryan Hamiltonabad59e2019-06-06 04:02:592476 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232477 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252478 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232479 mock_quic_data.AddWrite(SYNCHRONOUS,
2480 ConstructInitialSettingsPacket(packet_num++));
2481 }
rch5cb522462017-04-25 20:18:362482 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232483 SYNCHRONOUS,
2484 ConstructClientRequestHeadersPacket(
2485 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2486 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432487 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332488 ASYNC, ConstructServerResponseHeadersPacket(
2489 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2490 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432491 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332492 mock_quic_data.AddRead(
2493 ASYNC, ConstructServerDataPacket(
2494 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172495 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232496 mock_quic_data.AddWrite(SYNCHRONOUS,
2497 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072498 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592499 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072500
2501 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2502
rtennetib8e80fb2016-05-16 00:12:092503 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322504 CreateSession();
bnc8be55ebb2015-10-30 14:12:072505
2506 SendRequestAndExpectHttpResponse("hello world");
2507 SendRequestAndExpectQuicResponse("hello!");
2508}
2509
zhongyi6b5a3892016-03-12 04:46:202510TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562511 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangba21e032019-09-27 21:52:282512 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092513 return;
2514 }
Ryan Hamiltonabad59e2019-06-06 04:02:592515 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232516 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252517 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232518 mock_quic_data.AddWrite(SYNCHRONOUS,
2519 ConstructInitialSettingsPacket(packet_num++));
2520 }
rch5cb522462017-04-25 20:18:362521 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232522 SYNCHRONOUS,
2523 ConstructClientRequestHeadersPacket(
2524 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2525 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332526 mock_quic_data.AddRead(
2527 ASYNC, ConstructServerResponseHeadersPacket(
2528 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2529 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202530 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522531 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432532 mock_quic_data.AddRead(SYNCHRONOUS,
2533 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522534 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432535 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232536 mock_quic_data.AddWrite(SYNCHRONOUS,
2537 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432538 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332539 mock_quic_data.AddRead(
2540 SYNCHRONOUS, ConstructServerDataPacket(
2541 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172542 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232543 mock_quic_data.AddWrite(
2544 SYNCHRONOUS,
2545 ConstructClientAckAndRstPacket(
2546 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2547 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202548 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2549 mock_quic_data.AddRead(ASYNC, 0); // EOF
2550
2551 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2552
2553 // The non-alternate protocol job needs to hang in order to guarantee that
2554 // the alternate-protocol job will "win".
2555 AddHangingNonAlternateProtocolSocketData();
2556
2557 // In order for a new QUIC session to be established via alternate-protocol
2558 // without racing an HTTP connection, we need the host resolution to happen
2559 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2560 // connection to the the server, in this test we require confirmation
2561 // before encrypting so the HTTP job will still start.
2562 host_resolver_.set_synchronous_mode(true);
2563 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2564 "");
zhongyi6b5a3892016-03-12 04:46:202565
2566 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432567 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2568 false);
Ryan Hamilton9835e662018-08-02 05:36:272569 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202570
bnc691fda62016-08-12 00:43:162571 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202572 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362573 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202575
2576 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522577 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012578 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202579
2580 // Check whether this transaction is correctly marked as received a go-away
2581 // because of migrating port.
2582 NetErrorDetails details;
2583 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162584 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202585 EXPECT_TRUE(details.quic_port_migration_detected);
2586}
2587
Zhongyi Shia6b68d112018-09-24 07:49:032588// This test verifies that a new QUIC connection will be attempted on the
2589// alternate network if the original QUIC connection fails with idle timeout
2590// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2591// alternate network as well, QUIC is marked as broken and the brokenness will
2592// not expire when default network changes.
2593TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432594 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2595 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2596 return;
2597 }
Zhongyi Shia6b68d112018-09-24 07:49:032598 SetUpTestForRetryConnectionOnAlternateNetwork();
2599
Michael Warres167db3e2019-03-01 21:38:032600 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032601
2602 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592603 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032604 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2605 int packet_num = 1;
2606 quic_data.AddWrite(SYNCHRONOUS,
2607 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2608 // Retranmit the handshake messages.
2609 quic_data.AddWrite(SYNCHRONOUS,
2610 client_maker_.MakeDummyCHLOPacket(packet_num++));
2611 quic_data.AddWrite(SYNCHRONOUS,
2612 client_maker_.MakeDummyCHLOPacket(packet_num++));
2613 quic_data.AddWrite(SYNCHRONOUS,
2614 client_maker_.MakeDummyCHLOPacket(packet_num++));
2615 quic_data.AddWrite(SYNCHRONOUS,
2616 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032617 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2618 quic_data.AddWrite(SYNCHRONOUS,
2619 client_maker_.MakeConnectionClosePacket(
2620 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2621 "No recent network activity."));
2622 quic_data.AddSocketDataToFactory(&socket_factory_);
2623
2624 // Add successful TCP data so that TCP job will succeed.
2625 MockWrite http_writes[] = {
2626 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2627 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2628 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2629
2630 MockRead http_reads[] = {
2631 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2632 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2633 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2634 SequencedSocketData http_data(http_reads, http_writes);
2635 socket_factory_.AddSocketDataProvider(&http_data);
2636 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2637
2638 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592639 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032640 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2641 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2642 quic_data2.AddSocketDataToFactory(&socket_factory_);
2643
2644 // Resolve the host resolution synchronously.
2645 host_resolver_.set_synchronous_mode(true);
2646 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2647 "");
Zhongyi Shia6b68d112018-09-24 07:49:032648
2649 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432650 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2651 false);
Zhongyi Shia6b68d112018-09-24 07:49:032652 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032653 QuicStreamFactoryPeer::SetAlarmFactory(
2654 session_->quic_stream_factory(),
2655 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222656 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032657 // Add alternate protocol mapping to race QUIC and TCP.
2658 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2659 // peer.
2660 AddQuicAlternateProtocolMapping(
2661 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2662
2663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2664 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362665 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2667
2668 // Pump the message loop to get the request started.
2669 // Request will be served with TCP job.
2670 base::RunLoop().RunUntilIdle();
2671 EXPECT_THAT(callback.WaitForResult(), IsOk());
2672 CheckResponseData(&trans, "TCP succeeds");
2673
Zhongyi Shia6b68d112018-09-24 07:49:032674 // Fast forward to idle timeout the original connection. A new connection will
2675 // be kicked off on the alternate network.
2676 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2677 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2678 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2679
2680 // Run the message loop to execute posted tasks, which will report job status.
2681 base::RunLoop().RunUntilIdle();
2682
2683 // Verify that QUIC is marked as broken.
2684 ExpectBrokenAlternateProtocolMapping();
2685
2686 // Deliver a message to notify the new network becomes default, the brokenness
2687 // will not expire as QUIC is broken on both networks.
2688 scoped_mock_change_notifier_->mock_network_change_notifier()
2689 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2690 ExpectBrokenAlternateProtocolMapping();
2691
2692 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2693 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2694}
2695
2696// This test verifies that a new QUIC connection will be attempted on the
2697// alternate network if the original QUIC connection fails with idle timeout
2698// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2699// alternate network, QUIC is marked as broken. The brokenness will expire when
2700// the default network changes.
2701TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432702 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2703 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2704 return;
2705 }
2706
Zhongyi Shia6b68d112018-09-24 07:49:032707 SetUpTestForRetryConnectionOnAlternateNetwork();
2708
Michael Warres167db3e2019-03-01 21:38:032709 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032710
2711 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592712 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032713 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2714 int packet_num = 1;
2715 quic_data.AddWrite(SYNCHRONOUS,
2716 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2717 // Retranmit the handshake messages.
2718 quic_data.AddWrite(SYNCHRONOUS,
2719 client_maker_.MakeDummyCHLOPacket(packet_num++));
2720 quic_data.AddWrite(SYNCHRONOUS,
2721 client_maker_.MakeDummyCHLOPacket(packet_num++));
2722 quic_data.AddWrite(SYNCHRONOUS,
2723 client_maker_.MakeDummyCHLOPacket(packet_num++));
2724 quic_data.AddWrite(SYNCHRONOUS,
2725 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032726 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2727 quic_data.AddWrite(SYNCHRONOUS,
2728 client_maker_.MakeConnectionClosePacket(
2729 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2730 "No recent network activity."));
2731 quic_data.AddSocketDataToFactory(&socket_factory_);
2732
2733 // Add successful TCP data so that TCP job will succeed.
2734 MockWrite http_writes[] = {
2735 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2736 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2737 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2738
2739 MockRead http_reads[] = {
2740 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2741 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2742 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2743 SequencedSocketData http_data(http_reads, http_writes);
2744 socket_factory_.AddSocketDataProvider(&http_data);
2745 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2746
2747 // Quic connection will be retried on the alternate network after the initial
2748 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592749 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032750 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2751 quic_data2.AddWrite(SYNCHRONOUS,
2752 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2753
2754 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252755 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232756 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032757 quic_data2.AddSocketDataToFactory(&socket_factory_);
2758
2759 // Resolve the host resolution synchronously.
2760 host_resolver_.set_synchronous_mode(true);
2761 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2762 "");
Zhongyi Shia6b68d112018-09-24 07:49:032763
2764 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432765 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2766 false);
Zhongyi Shia6b68d112018-09-24 07:49:032767 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032768 QuicStreamFactoryPeer::SetAlarmFactory(
2769 session_->quic_stream_factory(),
2770 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222771 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032772 // Add alternate protocol mapping to race QUIC and TCP.
2773 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2774 // peer.
2775 AddQuicAlternateProtocolMapping(
2776 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2777
2778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2779 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362780 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2782
2783 // Pump the message loop to get the request started.
2784 // Request will be served with TCP job.
2785 base::RunLoop().RunUntilIdle();
2786 EXPECT_THAT(callback.WaitForResult(), IsOk());
2787 CheckResponseData(&trans, "TCP succeeds");
2788
Zhongyi Shia6b68d112018-09-24 07:49:032789 // Fast forward to idle timeout the original connection. A new connection will
2790 // be kicked off on the alternate network.
2791 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2792 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2793 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2794
2795 // The second connection hasn't finish handshake, verify that QUIC is not
2796 // marked as broken.
2797 ExpectQuicAlternateProtocolMapping();
2798 // Explicitly confirm the handshake on the second connection.
2799 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2800 quic::QuicSession::HANDSHAKE_CONFIRMED);
2801 // Run message loop to execute posted tasks, which will notify JoController
2802 // about the orphaned job status.
2803 base::RunLoop().RunUntilIdle();
2804
2805 // Verify that QUIC is marked as broken.
2806 ExpectBrokenAlternateProtocolMapping();
2807
2808 // Deliver a message to notify the new network becomes default, the previous
2809 // brokenness will be clear as the brokenness is bond with old default
2810 // network.
2811 scoped_mock_change_notifier_->mock_network_change_notifier()
2812 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2813 ExpectQuicAlternateProtocolMapping();
2814
2815 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2816 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2817}
2818
Matt Menkeb32ba5122019-09-10 19:17:052819// Much like above test, but verifies NetworkIsolationKeys are respected.
2820TEST_P(QuicNetworkTransactionTest,
2821 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432822 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2823 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2824 return;
2825 }
2826
Matt Menkeb32ba5122019-09-10 19:17:052827 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2828 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2829 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2830 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2831
2832 base::test::ScopedFeatureList feature_list;
2833 feature_list.InitWithFeatures(
2834 // enabled_features
2835 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2836 // Need to partition connections by NetworkIsolationKey for
2837 // QuicSessionAliasKey to include NetworkIsolationKeys.
2838 features::kPartitionConnectionsByNetworkIsolationKey},
2839 // disabled_features
2840 {});
2841 // Since HttpServerProperties caches the feature value, have to create a new
2842 // one.
2843 http_server_properties_ = std::make_unique<HttpServerProperties>();
2844
2845 SetUpTestForRetryConnectionOnAlternateNetwork();
2846
2847 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2848
2849 // The request will initially go out over QUIC.
2850 MockQuicData quic_data(version_);
2851 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2852 int packet_num = 1;
2853 quic_data.AddWrite(SYNCHRONOUS,
2854 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2855 // Retranmit the handshake messages.
2856 quic_data.AddWrite(SYNCHRONOUS,
2857 client_maker_.MakeDummyCHLOPacket(packet_num++));
2858 quic_data.AddWrite(SYNCHRONOUS,
2859 client_maker_.MakeDummyCHLOPacket(packet_num++));
2860 quic_data.AddWrite(SYNCHRONOUS,
2861 client_maker_.MakeDummyCHLOPacket(packet_num++));
2862 quic_data.AddWrite(SYNCHRONOUS,
2863 client_maker_.MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052864 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2865 quic_data.AddWrite(SYNCHRONOUS,
2866 client_maker_.MakeConnectionClosePacket(
2867 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2868 "No recent network activity."));
2869 quic_data.AddSocketDataToFactory(&socket_factory_);
2870
2871 // Add successful TCP data so that TCP job will succeed.
2872 MockWrite http_writes[] = {
2873 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2874 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2875 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2876
2877 MockRead http_reads[] = {
2878 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2879 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2880 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2881 SequencedSocketData http_data(http_reads, http_writes);
2882 socket_factory_.AddSocketDataProvider(&http_data);
2883 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2884
2885 // Quic connection will be retried on the alternate network after the initial
2886 // one fails on the default network.
2887 MockQuicData quic_data2(version_);
2888 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2889 quic_data2.AddWrite(SYNCHRONOUS,
2890 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2891
2892 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252893 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:052894 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2895 quic_data2.AddSocketDataToFactory(&socket_factory_);
2896
2897 // Resolve the host resolution synchronously.
2898 host_resolver_.set_synchronous_mode(true);
2899 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2900 "");
2901
2902 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432903 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2904 false);
Matt Menkeb32ba5122019-09-10 19:17:052905 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2906 QuicStreamFactoryPeer::SetAlarmFactory(
2907 session_->quic_stream_factory(),
2908 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222909 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:052910 // Add alternate protocol mapping to race QUIC and TCP.
2911 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2912 // peer.
2913 AddQuicAlternateProtocolMapping(
2914 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2915 AddQuicAlternateProtocolMapping(
2916 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2917
2918 request_.network_isolation_key = kNetworkIsolationKey1;
2919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2920 TestCompletionCallback callback;
2921 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2923
2924 // Pump the message loop to get the request started.
2925 // Request will be served with TCP job.
2926 base::RunLoop().RunUntilIdle();
2927 EXPECT_THAT(callback.WaitForResult(), IsOk());
2928 CheckResponseData(&trans, "TCP succeeds");
2929
2930 // Fast forward to idle timeout the original connection. A new connection will
2931 // be kicked off on the alternate network.
2932 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2933 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2934 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2935
2936 // The second connection hasn't finish handshake, verify that QUIC is not
2937 // marked as broken.
2938 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2939 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2940 // Explicitly confirm the handshake on the second connection.
2941 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2942 quic::QuicSession::HANDSHAKE_CONFIRMED);
2943 // Run message loop to execute posted tasks, which will notify JoController
2944 // about the orphaned job status.
2945 base::RunLoop().RunUntilIdle();
2946
2947 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2948 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2949 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2950
2951 // Deliver a message to notify the new network becomes default, the previous
2952 // brokenness will be clear as the brokenness is bond with old default
2953 // network.
2954 scoped_mock_change_notifier_->mock_network_change_notifier()
2955 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2956 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2957 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2958
2959 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2960 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2961}
2962
Zhongyi Shia6b68d112018-09-24 07:49:032963// This test verifies that a new QUIC connection will be attempted on the
2964// alternate network if the original QUIC connection fails with idle timeout
2965// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2966// alternative network succeeds, QUIC is not marked as broken.
2967TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432968 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2969 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2970 return;
2971 }
2972
Zhongyi Shia6b68d112018-09-24 07:49:032973 SetUpTestForRetryConnectionOnAlternateNetwork();
2974
Michael Warres167db3e2019-03-01 21:38:032975 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032976
2977 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592978 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032979 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2980 int packet_num = 1;
2981 quic_data.AddWrite(SYNCHRONOUS,
2982 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2983 // Retranmit the handshake messages.
2984 quic_data.AddWrite(SYNCHRONOUS,
2985 client_maker_.MakeDummyCHLOPacket(packet_num++));
2986 quic_data.AddWrite(SYNCHRONOUS,
2987 client_maker_.MakeDummyCHLOPacket(packet_num++));
2988 quic_data.AddWrite(SYNCHRONOUS,
2989 client_maker_.MakeDummyCHLOPacket(packet_num++));
2990 quic_data.AddWrite(SYNCHRONOUS,
2991 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032992 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2993 quic_data.AddWrite(SYNCHRONOUS,
2994 client_maker_.MakeConnectionClosePacket(
2995 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2996 "No recent network activity."));
2997 quic_data.AddSocketDataToFactory(&socket_factory_);
2998
2999 // Add hanging TCP data so that TCP job will never succeeded.
3000 AddHangingNonAlternateProtocolSocketData();
3001
3002 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593003 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233004 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:033005 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:233006 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033007
Victor Vasiliev076657c2019-03-12 02:46:433008 const std::string body = "hello!";
3009 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:413010
Zhongyi Shia6b68d112018-09-24 07:49:033011 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253012 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233013 quic_data2.AddWrite(SYNCHRONOUS,
3014 ConstructInitialSettingsPacket(packet_num++));
3015 }
Zhongyi Shia6b68d112018-09-24 07:49:033016 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233017 SYNCHRONOUS,
3018 ConstructClientRequestHeadersPacket(
3019 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3020 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033021 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333022 ASYNC, ConstructServerResponseHeadersPacket(
3023 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3024 GetResponseHeaders("200 OK")));
3025 quic_data2.AddRead(
3026 ASYNC, ConstructServerDataPacket(
3027 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173028 header + body));
Renjie Tangaadb84b2019-08-31 01:00:233029 quic_data2.AddWrite(SYNCHRONOUS,
3030 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033031 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3032 quic_data2.AddSocketDataToFactory(&socket_factory_);
3033
3034 // Resolve the host resolution synchronously.
3035 host_resolver_.set_synchronous_mode(true);
3036 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3037 "");
Zhongyi Shia6b68d112018-09-24 07:49:033038
3039 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433040 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3041 false);
Zhongyi Shia6b68d112018-09-24 07:49:033042 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033043 QuicStreamFactoryPeer::SetAlarmFactory(
3044 session_->quic_stream_factory(),
3045 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223046 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033047 // Add alternate protocol mapping to race QUIC and TCP.
3048 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3049 // peer.
3050 AddQuicAlternateProtocolMapping(
3051 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3052
3053 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3054 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363055 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033056 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3057
3058 // Pump the message loop to get the request started.
3059 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033060
3061 // Fast forward to idle timeout the original connection. A new connection will
3062 // be kicked off on the alternate network.
3063 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3064 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3065 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3066
3067 // Verify that QUIC is not marked as broken.
3068 ExpectQuicAlternateProtocolMapping();
3069 // Explicitly confirm the handshake on the second connection.
3070 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3071 quic::QuicSession::HANDSHAKE_CONFIRMED);
3072
3073 // Read the response.
3074 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413075 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033076 // Verify that QUIC is not marked as broken.
3077 ExpectQuicAlternateProtocolMapping();
3078
3079 // Deliver a message to notify the new network becomes default.
3080 scoped_mock_change_notifier_->mock_network_change_notifier()
3081 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3082 ExpectQuicAlternateProtocolMapping();
3083 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3084 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3085}
3086
rch9ecde09b2017-04-08 00:18:233087// Verify that if a QUIC connection times out, the QuicHttpStream will
3088// return QUIC_PROTOCOL_ERROR.
3089TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433090 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3091 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3092 return;
3093 }
3094
Victor Vasilieva1e66d72019-12-05 17:55:383095 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3096 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233097
3098 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593099 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133100 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233101 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3102
Ryan Hamiltone940bd12019-06-30 02:46:453103 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033104 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493105 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253106 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493107 quic_data.AddWrite(SYNCHRONOUS,
3108 ConstructInitialSettingsPacket(packet_num++));
3109 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023110 quic_data.AddWrite(
3111 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453112 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493113 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3114 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453115
3116 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233117
Victor Vasiliev7da08172019-10-14 06:04:253118 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493119 // TLP 1
3120 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3121 1, packet_num++, true));
3122 // TLP 2
3123 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3124 2, packet_num++, true));
3125 // RTO 1
3126 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3127 1, packet_num++, true));
3128 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3129 2, packet_num++, true));
3130 // RTO 2
3131 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3132 1, packet_num++, true));
3133 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3134 2, packet_num++, true));
3135 // RTO 3
3136 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3137 1, packet_num++, true));
3138 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3139 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013140
Findit2403b85d2019-11-19 05:06:373141 quic_data.AddWrite(SYNCHRONOUS,
3142 client_maker_.MakeConnectionClosePacket(
3143 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3144 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493145 } else {
3146 // Settings were sent in the request packet so there is only 1 packet to
3147 // retransmit.
3148 // TLP 1
3149 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3150 1, packet_num++, true));
3151 // TLP 2
3152 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3153 1, packet_num++, true));
3154 // RTO 1
3155 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3156 1, packet_num++, true));
3157 // RTO 2
3158 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3159 1, packet_num++, true));
3160 // RTO 3
3161 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3162 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373163
Nick Harper057264a82019-09-12 23:33:493164 quic_data.AddWrite(SYNCHRONOUS,
3165 client_maker_.MakeConnectionClosePacket(
3166 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3167 "No recent network activity."));
3168 }
Fan Yang928f1632017-12-14 18:55:223169
rch9ecde09b2017-04-08 00:18:233170 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3171 quic_data.AddRead(ASYNC, OK);
3172 quic_data.AddSocketDataToFactory(&socket_factory_);
3173
3174 // In order for a new QUIC session to be established via alternate-protocol
3175 // without racing an HTTP connection, we need the host resolution to happen
3176 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3177 // connection to the the server, in this test we require confirmation
3178 // before encrypting so the HTTP job will still start.
3179 host_resolver_.set_synchronous_mode(true);
3180 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3181 "");
rch9ecde09b2017-04-08 00:18:233182
3183 CreateSession();
3184 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233185 QuicStreamFactoryPeer::SetAlarmFactory(
3186 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193187 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223188 context_.clock()));
rch9ecde09b2017-04-08 00:18:233189
Ryan Hamilton9835e662018-08-02 05:36:273190 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233191
3192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3193 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363194 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3196
3197 // Pump the message loop to get the request started.
3198 base::RunLoop().RunUntilIdle();
3199 // Explicitly confirm the handshake.
3200 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523201 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233202
3203 // Run the QUIC session to completion.
3204 quic_task_runner_->RunUntilIdle();
3205
3206 ExpectQuicAlternateProtocolMapping();
3207 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3208 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3209}
3210
3211// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3212// return QUIC_PROTOCOL_ERROR.
3213TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433214 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3215 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3216 return;
3217 }
3218
Victor Vasilieva1e66d72019-12-05 17:55:383219 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3220 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233221
3222 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593223 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133224 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233225 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3226
Ryan Hamiltone940bd12019-06-30 02:46:453227 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033228 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493229 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253230 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493231 quic_data.AddWrite(
3232 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3233 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023234 quic_data.AddWrite(
3235 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453236 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493237 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3238 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453239
3240 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253241 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493242 // TLP 1
3243 quic_data.AddWrite(SYNCHRONOUS,
3244 client_maker_.MakeRetransmissionPacket(1, 3, true));
3245 // TLP 2
3246 quic_data.AddWrite(SYNCHRONOUS,
3247 client_maker_.MakeRetransmissionPacket(2, 4, true));
3248 // RTO 1
3249 quic_data.AddWrite(SYNCHRONOUS,
3250 client_maker_.MakeRetransmissionPacket(1, 5, true));
3251 quic_data.AddWrite(SYNCHRONOUS,
3252 client_maker_.MakeRetransmissionPacket(2, 6, true));
3253 // RTO 2
3254 quic_data.AddWrite(SYNCHRONOUS,
3255 client_maker_.MakeRetransmissionPacket(1, 7, true));
3256 quic_data.AddWrite(SYNCHRONOUS,
3257 client_maker_.MakeRetransmissionPacket(2, 8, true));
3258 // RTO 3
3259 quic_data.AddWrite(SYNCHRONOUS,
3260 client_maker_.MakeRetransmissionPacket(1, 9, true));
3261 quic_data.AddWrite(SYNCHRONOUS,
3262 client_maker_.MakeRetransmissionPacket(2, 10, true));
3263 // RTO 4
3264 quic_data.AddWrite(SYNCHRONOUS,
3265 client_maker_.MakeRetransmissionPacket(1, 11, true));
3266 quic_data.AddWrite(SYNCHRONOUS,
3267 client_maker_.MakeRetransmissionPacket(2, 12, true));
3268 // RTO 5
3269 quic_data.AddWrite(SYNCHRONOUS,
3270 client_maker_.MakeConnectionClosePacket(
3271 13, true, quic::QUIC_TOO_MANY_RTOS,
3272 "5 consecutive retransmission timeouts"));
3273 } else {
3274 // TLP 1
3275 quic_data.AddWrite(SYNCHRONOUS,
3276 client_maker_.MakeRetransmissionPacket(1, 2, true));
3277 // TLP 2
3278 quic_data.AddWrite(SYNCHRONOUS,
3279 client_maker_.MakeRetransmissionPacket(1, 3, true));
3280 // RTO 1
3281 quic_data.AddWrite(SYNCHRONOUS,
3282 client_maker_.MakeRetransmissionPacket(1, 4, true));
3283 // RTO 2
3284 quic_data.AddWrite(SYNCHRONOUS,
3285 client_maker_.MakeRetransmissionPacket(1, 5, true));
3286 // RTO 3
3287 quic_data.AddWrite(SYNCHRONOUS,
3288 client_maker_.MakeRetransmissionPacket(1, 6, true));
3289 // RTO 4
3290 quic_data.AddWrite(SYNCHRONOUS,
3291 client_maker_.MakeRetransmissionPacket(1, 7, true));
3292 // RTO 5
3293 quic_data.AddWrite(SYNCHRONOUS,
3294 client_maker_.MakeConnectionClosePacket(
3295 8, true, quic::QUIC_TOO_MANY_RTOS,
3296 "5 consecutive retransmission timeouts"));
3297 }
rch9ecde09b2017-04-08 00:18:233298
3299 quic_data.AddRead(ASYNC, OK);
3300 quic_data.AddSocketDataToFactory(&socket_factory_);
3301
3302 // In order for a new QUIC session to be established via alternate-protocol
3303 // without racing an HTTP connection, we need the host resolution to happen
3304 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3305 // connection to the the server, in this test we require confirmation
3306 // before encrypting so the HTTP job will still start.
3307 host_resolver_.set_synchronous_mode(true);
3308 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3309 "");
rch9ecde09b2017-04-08 00:18:233310
3311 CreateSession();
3312 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233313 QuicStreamFactoryPeer::SetAlarmFactory(
3314 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193315 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223316 context_.clock()));
rch9ecde09b2017-04-08 00:18:233317
Ryan Hamilton9835e662018-08-02 05:36:273318 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233319
3320 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3321 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363322 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3324
3325 // Pump the message loop to get the request started.
3326 base::RunLoop().RunUntilIdle();
3327 // Explicitly confirm the handshake.
3328 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523329 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233330
3331 // Run the QUIC session to completion.
3332 quic_task_runner_->RunUntilIdle();
3333
3334 ExpectQuicAlternateProtocolMapping();
3335 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3336 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3337}
3338
3339// Verify that if a QUIC connection RTOs, while there are no active streams
3340// QUIC will not be marked as broken.
3341TEST_P(QuicNetworkTransactionTest,
3342 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433343 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3344 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3345 return;
3346 }
3347
Victor Vasilieva1e66d72019-12-05 17:55:383348 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233349
3350 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593351 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133352 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233353 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3354
Ryan Hamiltone940bd12019-06-30 02:46:453355 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033356 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493357 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253358 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493359 quic_data.AddWrite(
3360 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3361 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023362 quic_data.AddWrite(
3363 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453364 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493365 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3366 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453367
3368 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233369
Victor Vasiliev7da08172019-10-14 06:04:253370 if (!VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493371 quic_data.AddWrite(SYNCHRONOUS,
3372 client_maker_.MakeRstPacket(
3373 packet_number++, true,
3374 GetNthClientInitiatedBidirectionalStreamId(0),
3375 quic::QUIC_STREAM_CANCELLED));
3376 // TLP 1
Bence Béky6e243aa2019-12-13 19:01:073377 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3378 1, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493379 // TLP 2
Bence Béky6e243aa2019-12-13 19:01:073380 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3381 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493382 // RTO 1
Bence Béky6e243aa2019-12-13 19:01:073383 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3384 1, packet_number++, true));
3385 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3386 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493387 // RTO 2
Bence Béky6e243aa2019-12-13 19:01:073388 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3389 1, packet_number++, true));
3390 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3391 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493392 // RTO 3
Bence Béky6e243aa2019-12-13 19:01:073393 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3394 1, packet_number++, true));
3395 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3396 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493397 // RTO 4
Bence Béky6e243aa2019-12-13 19:01:073398 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3399 1, packet_number++, true));
3400 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3401 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493402 // RTO 5
3403 quic_data.AddWrite(SYNCHRONOUS,
3404 client_maker_.MakeConnectionClosePacket(
Bence Béky6e243aa2019-12-13 19:01:073405 packet_number++, true, quic::QUIC_TOO_MANY_RTOS,
Nick Harper057264a82019-09-12 23:33:493406 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423407 } else {
3408 quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:073409 SYNCHRONOUS, ConstructClientDataPacket(
3410 packet_number++, GetQpackDecoderStreamId(), true,
3411 false, StreamCancellationQpackDecoderInstruction(0)));
3412 quic_data.AddWrite(SYNCHRONOUS,
3413 client_maker_.MakeRstPacket(
3414 packet_number++, true,
3415 GetNthClientInitiatedBidirectionalStreamId(0),
3416 quic::QUIC_STREAM_CANCELLED));
Renjie Tang33f43ce2019-09-23 22:11:423417 client_maker_.RemoveSavedStreamFrames(
3418 GetNthClientInitiatedBidirectionalStreamId(0));
Bence Béky6e243aa2019-12-13 19:01:073419
3420 if (FLAGS_quic_allow_http3_priority) {
3421 // TLP 1
3422 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3423 1, packet_number++, true));
3424 // TLP 2
3425 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3426 2, packet_number++, true));
3427 // RTO 1
3428 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3429 3, packet_number++, true));
3430 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3431 4, packet_number++, true));
3432 // RTO 2
3433 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3434 1, packet_number++, true));
3435 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3436 2, packet_number++, true));
3437 // RTO 3
3438 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3439 3, packet_number++, true));
3440 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3441 4, packet_number++, true));
3442 // RTO 4
3443 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3444 1, packet_number++, true));
3445 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3446 2, packet_number++, true));
3447 // RTO 5
3448 quic_data.AddWrite(SYNCHRONOUS,
3449 client_maker_.MakeConnectionClosePacket(
3450 packet_number++, true, quic::QUIC_TOO_MANY_RTOS,
3451 "5 consecutive retransmission timeouts"));
3452 } else {
3453 // When PRIORITY is disabled, packet 2 only contains request headers. And
3454 // since the request stream is reset, packet 2 will not be retransmitted.
3455 // TLP 1
3456 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3457 1, packet_number++, true));
3458 // TLP 2
3459 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3460 3, packet_number++, true));
3461 // RTO 1
3462 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3463 4, packet_number++, true));
3464 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3465 1, packet_number++, true));
3466 // RTO 2
3467 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3468 3, packet_number++, true));
3469 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3470 4, packet_number++, true));
3471 // RTO 3
3472 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3473 1, packet_number++, true));
3474 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3475 3, packet_number++, true));
3476 // RTO 4
3477 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3478 4, packet_number++, true));
3479 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3480 1, packet_number++, true));
3481 // RTO 5
3482 quic_data.AddWrite(SYNCHRONOUS,
3483 client_maker_.MakeConnectionClosePacket(
3484 packet_number++, true, quic::QUIC_TOO_MANY_RTOS,
3485 "5 consecutive retransmission timeouts"));
3486 }
Nick Harper057264a82019-09-12 23:33:493487 }
rch9ecde09b2017-04-08 00:18:233488
3489 quic_data.AddRead(ASYNC, OK);
3490 quic_data.AddSocketDataToFactory(&socket_factory_);
3491
3492 // In order for a new QUIC session to be established via alternate-protocol
3493 // without racing an HTTP connection, we need the host resolution to happen
3494 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3495 // connection to the the server, in this test we require confirmation
3496 // before encrypting so the HTTP job will still start.
3497 host_resolver_.set_synchronous_mode(true);
3498 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3499 "");
rch9ecde09b2017-04-08 00:18:233500
3501 CreateSession();
3502 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233503 QuicStreamFactoryPeer::SetAlarmFactory(
3504 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193505 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223506 context_.clock()));
rch9ecde09b2017-04-08 00:18:233507
Ryan Hamilton9835e662018-08-02 05:36:273508 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233509
Jeremy Roman0579ed62017-08-29 15:56:193510 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233511 session_.get());
3512 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363513 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3515
3516 // Pump the message loop to get the request started.
3517 base::RunLoop().RunUntilIdle();
3518 // Explicitly confirm the handshake.
3519 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523520 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233521
3522 // Now cancel the request.
3523 trans.reset();
3524
3525 // Run the QUIC session to completion.
3526 quic_task_runner_->RunUntilIdle();
3527
3528 ExpectQuicAlternateProtocolMapping();
3529
3530 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3531}
3532
rch2f2991c2017-04-13 19:28:173533// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3534// the request fails with QUIC_PROTOCOL_ERROR.
3535TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433536 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3537 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3538 return;
3539 }
3540
Victor Vasilieva1e66d72019-12-05 17:55:383541 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173542 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593543 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033544 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493545 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253546 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493547 quic_data.AddWrite(SYNCHRONOUS,
3548 ConstructInitialSettingsPacket(packet_num++));
3549 }
3550 quic_data.AddWrite(
3551 SYNCHRONOUS,
3552 ConstructClientRequestHeadersPacket(
3553 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3554 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023555 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553556 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173557 // Peer sending data from an non-existing stream causes this end to raise
3558 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333559 quic_data.AddRead(
3560 ASYNC, ConstructServerRstPacket(
3561 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3562 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173563 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373564 quic_data.AddWrite(SYNCHRONOUS,
3565 ConstructClientAckAndConnectionClosePacket(
3566 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3567 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3568 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173569 quic_data.AddSocketDataToFactory(&socket_factory_);
3570
3571 // In order for a new QUIC session to be established via alternate-protocol
3572 // without racing an HTTP connection, we need the host resolution to happen
3573 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3574 // connection to the the server, in this test we require confirmation
3575 // before encrypting so the HTTP job will still start.
3576 host_resolver_.set_synchronous_mode(true);
3577 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3578 "");
rch2f2991c2017-04-13 19:28:173579
3580 CreateSession();
3581
Ryan Hamilton9835e662018-08-02 05:36:273582 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173583
3584 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3585 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363586 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173587 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3588
3589 // Pump the message loop to get the request started.
3590 base::RunLoop().RunUntilIdle();
3591 // Explicitly confirm the handshake.
3592 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523593 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173594
3595 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553596 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173597
3598 // Run the QUIC session to completion.
3599 base::RunLoop().RunUntilIdle();
3600 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3601 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3602
3603 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3604 ExpectQuicAlternateProtocolMapping();
3605 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3606}
3607
rch2f2991c2017-04-13 19:28:173608// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3609// connection times out, then QUIC will be marked as broken and the request
3610// retried over TCP.
3611TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433612 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3613 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3614 return;
3615 }
3616
Victor Vasilieva1e66d72019-12-05 17:55:383617 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173618
3619 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593620 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133621 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173622 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3623
Ryan Hamiltone940bd12019-06-30 02:46:453624 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033625 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493626 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253627 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493628 quic_data.AddWrite(SYNCHRONOUS,
3629 client_maker_.MakeInitialSettingsPacket(packet_num++));
3630 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023631 quic_data.AddWrite(
3632 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453633 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493634 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3635 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453636
3637 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253638 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493639 // TLP 1
3640 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3641 1, packet_num++, true));
3642 // TLP 2
3643 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3644 2, packet_num++, true));
3645 // RTO 1
3646 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3647 1, packet_num++, true));
3648 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3649 2, packet_num++, true));
3650 // RTO 2
3651 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3652 1, packet_num++, true));
3653 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3654 2, packet_num++, true));
3655 // RTO 3
3656 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3657 1, packet_num++, true));
3658 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3659 2, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373660
3661 quic_data.AddWrite(SYNCHRONOUS,
3662 client_maker_.MakeConnectionClosePacket(
3663 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3664 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493665 } else {
3666 // TLP 1
3667 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3668 1, packet_num++, true));
3669 // TLP 2
3670 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3671 1, packet_num++, true));
3672 // RTO 1
3673 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3674 1, packet_num++, true));
3675 // RTO 2
3676 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3677 1, packet_num++, true));
3678 // RTO 3
3679 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3680 1, packet_num++, true));
3681
3682 quic_data.AddWrite(SYNCHRONOUS,
3683 client_maker_.MakeConnectionClosePacket(
3684 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3685 "No recent network activity."));
3686 }
Fan Yang928f1632017-12-14 18:55:223687
rch2f2991c2017-04-13 19:28:173688 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3689 quic_data.AddRead(ASYNC, OK);
3690 quic_data.AddSocketDataToFactory(&socket_factory_);
3691
3692 // After that fails, it will be resent via TCP.
3693 MockWrite http_writes[] = {
3694 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3695 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3696 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3697
3698 MockRead http_reads[] = {
3699 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3700 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3701 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013702 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173703 socket_factory_.AddSocketDataProvider(&http_data);
3704 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3705
3706 // In order for a new QUIC session to be established via alternate-protocol
3707 // without racing an HTTP connection, we need the host resolution to happen
3708 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3709 // connection to the the server, in this test we require confirmation
3710 // before encrypting so the HTTP job will still start.
3711 host_resolver_.set_synchronous_mode(true);
3712 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3713 "");
rch2f2991c2017-04-13 19:28:173714
3715 CreateSession();
3716 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173717 QuicStreamFactoryPeer::SetAlarmFactory(
3718 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193719 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223720 context_.clock()));
rch2f2991c2017-04-13 19:28:173721
Ryan Hamilton9835e662018-08-02 05:36:273722 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173723
3724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3725 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363726 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3728
3729 // Pump the message loop to get the request started.
3730 base::RunLoop().RunUntilIdle();
3731 // Explicitly confirm the handshake.
3732 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523733 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173734
3735 // Run the QUIC session to completion.
3736 quic_task_runner_->RunUntilIdle();
3737 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3738
3739 ExpectQuicAlternateProtocolMapping();
3740
3741 // Let the transaction proceed which will result in QUIC being marked
3742 // as broken and the request falling back to TCP.
3743 EXPECT_THAT(callback.WaitForResult(), IsOk());
3744
3745 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3746 ASSERT_FALSE(http_data.AllReadDataConsumed());
3747
3748 // Read the response body over TCP.
3749 CheckResponseData(&trans, "hello world");
3750 ExpectBrokenAlternateProtocolMapping();
3751 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3752 ASSERT_TRUE(http_data.AllReadDataConsumed());
3753}
3754
rch2f2991c2017-04-13 19:28:173755// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3756// protocol error occurs after the handshake is confirmed, the request
3757// retried over TCP and the QUIC will be marked as broken.
3758TEST_P(QuicNetworkTransactionTest,
3759 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433760 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3761 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3762 return;
3763 }
3764
Victor Vasilieva1e66d72019-12-05 17:55:383765 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173766
3767 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593768 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033769 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493770 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253771 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493772 quic_data.AddWrite(SYNCHRONOUS,
3773 ConstructInitialSettingsPacket(packet_num++));
3774 }
3775 quic_data.AddWrite(
3776 SYNCHRONOUS,
3777 ConstructClientRequestHeadersPacket(
3778 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3779 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023780 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553781 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3782
rch2f2991c2017-04-13 19:28:173783 // Peer sending data from an non-existing stream causes this end to raise
3784 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333785 quic_data.AddRead(
3786 ASYNC, ConstructServerRstPacket(
3787 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3788 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173789 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373790 quic_data.AddWrite(SYNCHRONOUS,
3791 ConstructClientAckAndConnectionClosePacket(
3792 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3793 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3794 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173795 quic_data.AddSocketDataToFactory(&socket_factory_);
3796
3797 // After that fails, it will be resent via TCP.
3798 MockWrite http_writes[] = {
3799 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3800 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3801 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3802
3803 MockRead http_reads[] = {
3804 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3805 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3806 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013807 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173808 socket_factory_.AddSocketDataProvider(&http_data);
3809 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3810
3811 // In order for a new QUIC session to be established via alternate-protocol
3812 // without racing an HTTP connection, we need the host resolution to happen
3813 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3814 // connection to the the server, in this test we require confirmation
3815 // before encrypting so the HTTP job will still start.
3816 host_resolver_.set_synchronous_mode(true);
3817 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3818 "");
rch2f2991c2017-04-13 19:28:173819
3820 CreateSession();
3821
Ryan Hamilton9835e662018-08-02 05:36:273822 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173823
3824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3825 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363826 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3828
3829 // Pump the message loop to get the request started.
3830 base::RunLoop().RunUntilIdle();
3831 // Explicitly confirm the handshake.
3832 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523833 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553834 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173835
3836 // Run the QUIC session to completion.
3837 base::RunLoop().RunUntilIdle();
3838 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3839
3840 ExpectQuicAlternateProtocolMapping();
3841
3842 // Let the transaction proceed which will result in QUIC being marked
3843 // as broken and the request falling back to TCP.
3844 EXPECT_THAT(callback.WaitForResult(), IsOk());
3845
3846 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3847 ASSERT_FALSE(http_data.AllReadDataConsumed());
3848
3849 // Read the response body over TCP.
3850 CheckResponseData(&trans, "hello world");
3851 ExpectBrokenAlternateProtocolMapping();
3852 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3853 ASSERT_TRUE(http_data.AllReadDataConsumed());
3854}
3855
Matt Menkeb32ba5122019-09-10 19:17:053856// Much like above test, but verifies that NetworkIsolationKey is respected.
3857TEST_P(QuicNetworkTransactionTest,
3858 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433859 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3860 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3861 return;
3862 }
3863
Matt Menkeb32ba5122019-09-10 19:17:053864 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3865 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3866 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3867 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3868
3869 base::test::ScopedFeatureList feature_list;
3870 feature_list.InitWithFeatures(
3871 // enabled_features
3872 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3873 features::kPartitionConnectionsByNetworkIsolationKey},
3874 // disabled_features
3875 {});
3876 // Since HttpServerProperties caches the feature value, have to create a new
3877 // one.
3878 http_server_properties_ = std::make_unique<HttpServerProperties>();
3879
Victor Vasilieva1e66d72019-12-05 17:55:383880 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053881
3882 // The request will initially go out over QUIC.
3883 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563884 uint64_t packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:053885 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253886 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563887 quic_data.AddWrite(SYNCHRONOUS,
3888 ConstructInitialSettingsPacket(packet_number++));
3889 }
3890 quic_data.AddWrite(
3891 SYNCHRONOUS,
3892 ConstructClientRequestHeadersPacket(
3893 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3894 true, GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053895 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053896 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3897
3898 // Peer sending data from an non-existing stream causes this end to raise
3899 // error and close connection.
3900 quic_data.AddRead(
3901 ASYNC, ConstructServerRstPacket(
3902 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3903 quic::QUIC_STREAM_LAST_ERROR));
3904 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373905 quic_data.AddWrite(
3906 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3907 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3908 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3909 quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053910 quic_data.AddSocketDataToFactory(&socket_factory_);
3911
3912 // After that fails, it will be resent via TCP.
3913 MockWrite http_writes[] = {
3914 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3915 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3916 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3917
3918 MockRead http_reads[] = {
3919 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3920 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3921 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3922 SequencedSocketData http_data(http_reads, http_writes);
3923 socket_factory_.AddSocketDataProvider(&http_data);
3924 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3925
3926 // In order for a new QUIC session to be established via alternate-protocol
3927 // without racing an HTTP connection, we need the host resolution to happen
3928 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3929 // connection to the the server, in this test we require confirmation
3930 // before encrypting so the HTTP job will still start.
3931 host_resolver_.set_synchronous_mode(true);
3932 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3933 "");
3934
3935 CreateSession();
3936
3937 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3938 kNetworkIsolationKey1);
3939 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3940 kNetworkIsolationKey2);
3941
3942 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3943 TestCompletionCallback callback;
3944 request_.network_isolation_key = kNetworkIsolationKey1;
3945 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3947
3948 // Pump the message loop to get the request started.
3949 base::RunLoop().RunUntilIdle();
3950 // Explicitly confirm the handshake.
3951 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3952 quic::QuicSession::HANDSHAKE_CONFIRMED);
3953 quic_data.Resume();
3954
3955 // Run the QUIC session to completion.
3956 base::RunLoop().RunUntilIdle();
3957 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3958
3959 // Let the transaction proceed which will result in QUIC being marked
3960 // as broken and the request falling back to TCP.
3961 EXPECT_THAT(callback.WaitForResult(), IsOk());
3962 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3963 ASSERT_FALSE(http_data.AllReadDataConsumed());
3964
3965 // Read the response body over TCP.
3966 CheckResponseData(&trans, "hello world");
3967 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3968 ASSERT_TRUE(http_data.AllReadDataConsumed());
3969
3970 // The alternative service shouldhave been marked as broken under
3971 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3972 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3973 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3974
3975 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3976 AddHttpDataAndRunRequest();
3977 // Requests using other NetworkIsolationKeys can still use QUIC.
3978 request_.network_isolation_key = kNetworkIsolationKey2;
3979 AddQuicDataAndRunRequest();
3980
3981 // The last two requests should not have changed the alternative service
3982 // mappings.
3983 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3984 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3985}
3986
rch30943ee2017-06-12 21:28:443987// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3988// request is reset from, then QUIC will be marked as broken and the request
3989// retried over TCP.
3990TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433991 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3992 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3993 return;
3994 }
3995
rch30943ee2017-06-12 21:28:443996 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593997 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133998 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443999 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
4000
Michael Warres167db3e2019-03-01 21:38:034001 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494002 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254003 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494004 quic_data.AddWrite(SYNCHRONOUS,
4005 ConstructInitialSettingsPacket(packet_num++));
4006 }
Ryan Hamilton0d65a8c2019-06-07 00:46:024007 quic_data.AddWrite(
4008 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:454009 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:494010 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4011 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:454012
4013 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:554014 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:444015
Fan Yang32c5a112018-12-10 20:06:334016 quic_data.AddRead(ASYNC,
4017 ConstructServerRstPacket(
4018 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
4019 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444020
Bence Béky6e243aa2019-12-13 19:01:074021 if (VersionUsesHttp3(version_.transport_version)) {
4022 quic_data.AddWrite(SYNCHRONOUS,
4023 ConstructClientDataPacket(
4024 packet_num++, GetQpackDecoderStreamId(), true, false,
4025 StreamCancellationQpackDecoderInstruction(0)));
4026 }
4027
rch30943ee2017-06-12 21:28:444028 quic_data.AddRead(ASYNC, OK);
4029 quic_data.AddSocketDataToFactory(&socket_factory_);
4030
4031 // After that fails, it will be resent via TCP.
4032 MockWrite http_writes[] = {
4033 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4034 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
4035 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4036
4037 MockRead http_reads[] = {
4038 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4039 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4040 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014041 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444042 socket_factory_.AddSocketDataProvider(&http_data);
4043 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4044
4045 // In order for a new QUIC session to be established via alternate-protocol
4046 // without racing an HTTP connection, we need the host resolution to happen
4047 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4048 // connection to the the server, in this test we require confirmation
4049 // before encrypting so the HTTP job will still start.
4050 host_resolver_.set_synchronous_mode(true);
4051 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4052 "");
rch30943ee2017-06-12 21:28:444053
4054 CreateSession();
4055
Ryan Hamilton9835e662018-08-02 05:36:274056 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:444057
4058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4059 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364060 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:444061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4062
4063 // Pump the message loop to get the request started.
4064 base::RunLoop().RunUntilIdle();
4065 // Explicitly confirm the handshake.
4066 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524067 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:554068 quic_data.Resume();
rch30943ee2017-06-12 21:28:444069
4070 // Run the QUIC session to completion.
4071 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4072
4073 ExpectQuicAlternateProtocolMapping();
4074
4075 // Let the transaction proceed which will result in QUIC being marked
4076 // as broken and the request falling back to TCP.
4077 EXPECT_THAT(callback.WaitForResult(), IsOk());
4078
4079 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4080 ASSERT_FALSE(http_data.AllReadDataConsumed());
4081
4082 // Read the response body over TCP.
4083 CheckResponseData(&trans, "hello world");
4084 ExpectBrokenAlternateProtocolMapping();
4085 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4086 ASSERT_TRUE(http_data.AllReadDataConsumed());
4087}
4088
Ryan Hamilton6c2a2a82017-12-15 02:06:284089// Verify that when an origin has two alt-svc advertisements, one local and one
4090// remote, that when the local is broken the request will go over QUIC via
4091// the remote Alt-Svc.
4092// This is a regression test for crbug/825646.
4093TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384094 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:284095
4096 GURL origin1 = request_.url; // mail.example.org
4097 GURL origin2("https://www.example.org/");
4098 ASSERT_NE(origin1.host(), origin2.host());
4099
4100 scoped_refptr<X509Certificate> cert(
4101 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244102 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4103 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284104
4105 ProofVerifyDetailsChromium verify_details;
4106 verify_details.cert_verify_result.verified_cert = cert;
4107 verify_details.cert_verify_result.is_issued_by_known_root = true;
4108 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4109
Ryan Hamiltonabad59e2019-06-06 04:02:594110 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234111 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254112 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234113 mock_quic_data.AddWrite(SYNCHRONOUS,
4114 ConstructInitialSettingsPacket(packet_num++));
4115 }
Ryan Hamilton6c2a2a82017-12-15 02:06:284116 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234117 SYNCHRONOUS,
4118 ConstructClientRequestHeadersPacket(
4119 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4120 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434121 mock_quic_data.AddRead(
4122 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334123 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024124 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434125 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434126 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334127 ASYNC, ConstructServerDataPacket(
4128 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174129 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234130 mock_quic_data.AddWrite(SYNCHRONOUS,
4131 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284132 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4133 mock_quic_data.AddRead(ASYNC, 0); // EOF
4134
4135 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594136 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284137 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4138 AddHangingNonAlternateProtocolSocketData();
4139
4140 CreateSession();
4141
4142 // Set up alternative service for |origin1|.
4143 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4144 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4145 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4146 AlternativeServiceInfoVector alternative_services;
4147 alternative_services.push_back(
4148 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4149 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384150 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284151 alternative_services.push_back(
4152 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4153 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384154 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494155 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4156 NetworkIsolationKey(),
4157 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284158
Matt Menkeb32ba5122019-09-10 19:17:054159 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4160 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284161
4162 SendRequestAndExpectQuicResponse("hello!");
4163}
4164
Ryan Hamilton899c2e082019-11-14 01:22:024165// Verify that when multiple alternatives are broken,
4166// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
4167// This is a regression test for crbug/1024613.
4168TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
4169 base::HistogramTester histogram_tester;
4170
4171 MockRead http_reads[] = {
4172 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4173 MockRead("hello world"),
4174 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4175 MockRead(ASYNC, OK)};
4176
4177 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4178 socket_factory_.AddSocketDataProvider(&http_data);
4179 AddCertificate(&ssl_data_);
4180 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4181
4182 GURL origin1 = request_.url; // mail.example.org
4183
4184 scoped_refptr<X509Certificate> cert(
4185 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4186 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4187
4188 ProofVerifyDetailsChromium verify_details;
4189 verify_details.cert_verify_result.verified_cert = cert;
4190 verify_details.cert_verify_result.is_issued_by_known_root = true;
4191 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4192
4193 CreateSession();
4194
4195 // Set up alternative service for |origin1|.
4196 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4197 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4198 AlternativeServiceInfoVector alternative_services;
4199 alternative_services.push_back(
4200 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4201 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384202 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024203 alternative_services.push_back(
4204 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4205 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384206 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024207 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4208 NetworkIsolationKey(),
4209 alternative_services);
4210
4211 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4212 NetworkIsolationKey());
4213
4214 SendRequestAndExpectHttpResponse("hello world");
4215
4216 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4217 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4218}
4219
rch30943ee2017-06-12 21:28:444220// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4221// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054222// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444223// connection instead of going back to the broken QUIC connection.
4224// This is a regression tests for crbug/731303.
4225TEST_P(QuicNetworkTransactionTest,
4226 ResetPooledAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384227 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444228
4229 GURL origin1 = request_.url;
4230 GURL origin2("https://www.example.org/");
4231 ASSERT_NE(origin1.host(), origin2.host());
4232
Ryan Hamiltonabad59e2019-06-06 04:02:594233 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444234
4235 scoped_refptr<X509Certificate> cert(
4236 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244237 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4238 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444239
4240 ProofVerifyDetailsChromium verify_details;
4241 verify_details.cert_verify_result.verified_cert = cert;
4242 verify_details.cert_verify_result.is_issued_by_known_root = true;
4243 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4244
Renjie Tangaadb84b2019-08-31 01:00:234245 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254246 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234247 mock_quic_data.AddWrite(SYNCHRONOUS,
4248 ConstructInitialSettingsPacket(packet_num++));
4249 }
rch30943ee2017-06-12 21:28:444250 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434251 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234252 SYNCHRONOUS,
4253 ConstructClientRequestHeadersPacket(
4254 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4255 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434256 mock_quic_data.AddRead(
4257 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334258 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024259 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434260 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434261 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334262 ASYNC, ConstructServerDataPacket(
4263 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174264 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234265 mock_quic_data.AddWrite(SYNCHRONOUS,
4266 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444267
4268 // Second request will go over the pooled QUIC connection, but will be
4269 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054270 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224271 version_,
4272 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4273 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054274 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174275 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224276 version_,
4277 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4278 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434279 mock_quic_data.AddWrite(
4280 SYNCHRONOUS,
4281 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234282 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4283 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024284 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334285 mock_quic_data.AddRead(
4286 ASYNC, ConstructServerRstPacket(
4287 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4288 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074289
4290 if (VersionUsesHttp3(version_.transport_version)) {
4291 mock_quic_data.AddWrite(
4292 SYNCHRONOUS, ConstructClientDataPacket(
4293 packet_num++, GetQpackDecoderStreamId(), true, false,
4294 StreamCancellationQpackDecoderInstruction(1)));
4295 }
4296
rch30943ee2017-06-12 21:28:444297 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4298 mock_quic_data.AddRead(ASYNC, 0); // EOF
4299
4300 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4301
4302 // After that fails, it will be resent via TCP.
4303 MockWrite http_writes[] = {
4304 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4305 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4306 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4307
4308 MockRead http_reads[] = {
4309 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4310 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4311 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014312 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444313 socket_factory_.AddSocketDataProvider(&http_data);
4314 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4315
Ryan Hamilton6c2a2a82017-12-15 02:06:284316 // Then the next request to the second origin will be sent over TCP.
4317 socket_factory_.AddSocketDataProvider(&http_data);
4318 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444319
4320 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564321 QuicStreamFactoryPeer::SetAlarmFactory(
4322 session_->quic_stream_factory(),
4323 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224324 context_.clock()));
rch30943ee2017-06-12 21:28:444325
4326 // Set up alternative service for |origin1|.
4327 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244328 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494329 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074330 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4331 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444332
4333 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244334 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494335 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074336 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4337 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344338
rch30943ee2017-06-12 21:28:444339 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524340 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444341 SendRequestAndExpectQuicResponse("hello!");
4342
4343 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524344 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054345 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444346 request_.url = origin2;
4347 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054348 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4349 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244350 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054351 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4352 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244353 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444354
Matt Menkeb32ba5122019-09-10 19:17:054355 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444356 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284357 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444358}
4359
bnc8be55ebb2015-10-30 14:12:074360TEST_P(QuicNetworkTransactionTest,
4361 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564362 std::string altsvc_header =
4363 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4364 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074365 MockRead http_reads[] = {
4366 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4367 MockRead("hello world"),
4368 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4369 MockRead(ASYNC, OK)};
4370
Ryan Sleevib8d7ea02018-05-07 20:01:014371 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074372 socket_factory_.AddSocketDataProvider(&http_data);
4373 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4374 socket_factory_.AddSocketDataProvider(&http_data);
4375 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4376
rch3f4b8452016-02-23 16:59:324377 CreateSession();
bnc8be55ebb2015-10-30 14:12:074378
4379 SendRequestAndExpectHttpResponse("hello world");
4380 SendRequestAndExpectHttpResponse("hello world");
4381}
4382
Xida Chen9bfe0b62018-04-24 19:52:214383// When multiple alternative services are advertised, HttpStreamFactory should
4384// select the alternative service which uses existing QUIC session if available.
4385// If no existing QUIC session can be used, use the first alternative service
4386// from the list.
zhongyi32569c62016-01-08 02:54:304387TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:384388 context_.params()->allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524389 MockRead http_reads[] = {
4390 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294391 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524392 MockRead("hello world"),
4393 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4394 MockRead(ASYNC, OK)};
4395
Ryan Sleevib8d7ea02018-05-07 20:01:014396 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524397 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084398 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564399 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524400
zhongyi32569c62016-01-08 02:54:304401 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294402 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304403 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594404 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234405 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254406 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234407 mock_quic_data.AddWrite(SYNCHRONOUS,
4408 ConstructInitialSettingsPacket(packet_num++));
4409 }
rch5cb522462017-04-25 20:18:364410 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234411 SYNCHRONOUS,
4412 ConstructClientRequestHeadersPacket(
4413 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4414 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304415
4416 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294417 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4418 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434419 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024420 ASYNC, ConstructServerResponseHeadersPacket(
4421 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4422 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434423 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434424 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334425 ASYNC, ConstructServerDataPacket(
4426 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174427 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234428 mock_quic_data.AddWrite(SYNCHRONOUS,
4429 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304430
4431 // Second QUIC request data.
4432 // Connection pooling, using existing session, no need to include version
4433 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584434 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234435 SYNCHRONOUS,
4436 ConstructClientRequestHeadersPacket(
4437 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4438 true, GetRequestHeaders("GET", "https", "/"),
4439 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434440 mock_quic_data.AddRead(
4441 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334442 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024443 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434444 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334445 ASYNC, ConstructServerDataPacket(
4446 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174447 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434448 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234449 SYNCHRONOUS,
4450 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524451 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594452 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524453
4454 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4455
rtennetib8e80fb2016-05-16 00:12:094456 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324457 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564458 QuicStreamFactoryPeer::SetAlarmFactory(
4459 session_->quic_stream_factory(),
4460 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224461 context_.clock()));
bncc958faa2015-07-31 18:14:524462
4463 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304464
bnc359ed2a2016-04-29 20:43:454465 SendRequestAndExpectQuicResponse("hello!");
4466 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304467}
4468
tbansal6490783c2016-09-20 17:55:274469// Check that an existing QUIC connection to an alternative proxy server is
4470// used.
4471TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4472 base::HistogramTester histogram_tester;
4473
tbansal6490783c2016-09-20 17:55:274474 // First QUIC request data.
4475 // Open a session to foo.example.org:443 using the first entry of the
4476 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594477 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234478 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254479 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234480 mock_quic_data.AddWrite(SYNCHRONOUS,
4481 ConstructInitialSettingsPacket(packet_num++));
4482 }
rch5cb522462017-04-25 20:18:364483 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234484 SYNCHRONOUS,
4485 ConstructClientRequestHeadersPacket(
4486 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4487 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274488
4489 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434490 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024491 ASYNC, ConstructServerResponseHeadersPacket(
4492 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4493 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434494 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434495 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334496 ASYNC, ConstructServerDataPacket(
4497 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174498 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234499 mock_quic_data.AddWrite(SYNCHRONOUS,
4500 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274501
4502 // Second QUIC request data.
4503 // Connection pooling, using existing session, no need to include version
4504 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274505 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234506 SYNCHRONOUS,
4507 ConstructClientRequestHeadersPacket(
4508 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4509 true, GetRequestHeaders("GET", "http", "/"),
4510 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434511 mock_quic_data.AddRead(
4512 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334513 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024514 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434515 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334516 ASYNC, ConstructServerDataPacket(
4517 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174518 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434519 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234520 SYNCHRONOUS,
4521 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274522 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4523 mock_quic_data.AddRead(ASYNC, 0); // EOF
4524
4525 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4526
4527 AddHangingNonAlternateProtocolSocketData();
4528
4529 TestProxyDelegate test_proxy_delegate;
4530
Lily Houghton8c2f97d2018-01-22 05:06:594531 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494532 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274533
4534 test_proxy_delegate.set_alternative_proxy_server(
4535 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524536 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274537
4538 request_.url = GURL("http://mail.example.org/");
4539
4540 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564541 QuicStreamFactoryPeer::SetAlarmFactory(
4542 session_->quic_stream_factory(),
4543 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224544 context_.clock()));
tbansal6490783c2016-09-20 17:55:274545
4546 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4547 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4548 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4549 1);
4550
4551 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4552 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4553 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4554 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4555 1);
4556}
4557
Ryan Hamilton8d9ee76e2018-05-29 23:52:524558// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454559// even if alternative service destination is different.
4560TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384561 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594562 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454563
Renjie Tangaadb84b2019-08-31 01:00:234564 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254565 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234566 mock_quic_data.AddWrite(SYNCHRONOUS,
4567 ConstructInitialSettingsPacket(packet_num++));
4568 }
bnc359ed2a2016-04-29 20:43:454569 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434570 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234571 SYNCHRONOUS,
4572 ConstructClientRequestHeadersPacket(
4573 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4574 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434575 mock_quic_data.AddRead(
4576 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334577 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024578 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434579 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434580 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334581 ASYNC, ConstructServerDataPacket(
4582 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174583 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234584 mock_quic_data.AddWrite(SYNCHRONOUS,
4585 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304586
bnc359ed2a2016-04-29 20:43:454587 // Second request.
alyssar2adf3ac2016-05-03 17:12:584588 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234589 SYNCHRONOUS,
4590 ConstructClientRequestHeadersPacket(
4591 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4592 true, GetRequestHeaders("GET", "https", "/"),
4593 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434594 mock_quic_data.AddRead(
4595 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334596 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024597 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434598 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334599 ASYNC, ConstructServerDataPacket(
4600 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174601 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434602 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234603 SYNCHRONOUS,
4604 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304605 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4606 mock_quic_data.AddRead(ASYNC, 0); // EOF
4607
4608 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454609
4610 AddHangingNonAlternateProtocolSocketData();
4611 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304612
rch3f4b8452016-02-23 16:59:324613 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564614 QuicStreamFactoryPeer::SetAlarmFactory(
4615 session_->quic_stream_factory(),
4616 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224617 context_.clock()));
zhongyi32569c62016-01-08 02:54:304618
bnc359ed2a2016-04-29 20:43:454619 const char destination1[] = "first.example.com";
4620 const char destination2[] = "second.example.com";
4621
4622 // Set up alternative service entry to destination1.
4623 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214624 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454625 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494626 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074627 server, NetworkIsolationKey(), alternative_service, expiration,
4628 supported_versions_);
bnc359ed2a2016-04-29 20:43:454629 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524630 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454631 SendRequestAndExpectQuicResponse("hello!");
4632
4633 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214634 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494635 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074636 server, NetworkIsolationKey(), alternative_service, expiration,
4637 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524638 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454639 // even though alternative service destination is different.
4640 SendRequestAndExpectQuicResponse("hello!");
4641}
4642
4643// Pool to existing session with matching destination and matching certificate
4644// even if origin is different, and even if the alternative service with
4645// matching destination is not the first one on the list.
4646TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384647 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454648 GURL origin1 = request_.url;
4649 GURL origin2("https://www.example.org/");
4650 ASSERT_NE(origin1.host(), origin2.host());
4651
Ryan Hamiltonabad59e2019-06-06 04:02:594652 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454653
Renjie Tangaadb84b2019-08-31 01:00:234654 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254655 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234656 mock_quic_data.AddWrite(SYNCHRONOUS,
4657 ConstructInitialSettingsPacket(packet_num++));
4658 }
bnc359ed2a2016-04-29 20:43:454659 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434660 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234661 SYNCHRONOUS,
4662 ConstructClientRequestHeadersPacket(
4663 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4664 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434665 mock_quic_data.AddRead(
4666 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334667 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024668 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434669 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434670 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334671 ASYNC, ConstructServerDataPacket(
4672 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174673 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234674 mock_quic_data.AddWrite(SYNCHRONOUS,
4675 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454676
4677 // Second request.
Yixin Wang079ad542018-01-11 04:06:054678 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224679 version_,
4680 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4681 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054682 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174683 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224684 version_,
4685 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4686 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584687 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434688 SYNCHRONOUS,
4689 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234690 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4691 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024692 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434693 mock_quic_data.AddRead(
4694 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334695 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024696 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434697 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334698 ASYNC, ConstructServerDataPacket(
4699 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174700 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434701 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234702 SYNCHRONOUS,
4703 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454704 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4705 mock_quic_data.AddRead(ASYNC, 0); // EOF
4706
4707 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4708
4709 AddHangingNonAlternateProtocolSocketData();
4710 AddHangingNonAlternateProtocolSocketData();
4711
4712 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564713 QuicStreamFactoryPeer::SetAlarmFactory(
4714 session_->quic_stream_factory(),
4715 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224716 context_.clock()));
bnc359ed2a2016-04-29 20:43:454717
4718 const char destination1[] = "first.example.com";
4719 const char destination2[] = "second.example.com";
4720
4721 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214722 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454723 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494724 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074725 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4726 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454727
4728 // Set up multiple alternative service entries for |origin2|,
4729 // the first one with a different destination as for |origin1|,
4730 // the second one with the same. The second one should be used,
4731 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214732 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454733 AlternativeServiceInfoVector alternative_services;
4734 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214735 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4736 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384737 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454738 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214739 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4740 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384741 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494742 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4743 NetworkIsolationKey(),
4744 alternative_services);
bnc359ed2a2016-04-29 20:43:454745 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524746 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454747 SendRequestAndExpectQuicResponse("hello!");
4748
4749 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524750 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454751 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584752
bnc359ed2a2016-04-29 20:43:454753 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304754}
4755
4756// Multiple origins have listed the same alternative services. When there's a
4757// existing QUIC session opened by a request to other origin,
4758// if the cert is valid, should select this QUIC session to make the request
4759// if this is also the first existing QUIC session.
4760TEST_P(QuicNetworkTransactionTest,
4761 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Victor Vasilieva1e66d72019-12-05 17:55:384762 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294763 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304764
rch9ae5b3b2016-02-11 00:36:294765 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304766 MockRead http_reads[] = {
4767 MockRead("HTTP/1.1 200 OK\r\n"),
4768 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294769 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304770 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4771 MockRead(ASYNC, OK)};
4772
Ryan Sleevib8d7ea02018-05-07 20:01:014773 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304774 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084775 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304776 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4777
4778 // HTTP data for request to mail.example.org.
4779 MockRead http_reads2[] = {
4780 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294781 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304782 MockRead("hello world from mail.example.org"),
4783 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4784 MockRead(ASYNC, OK)};
4785
Ryan Sleevib8d7ea02018-05-07 20:01:014786 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304787 socket_factory_.AddSocketDataProvider(&http_data2);
4788 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4789
Yixin Wang079ad542018-01-11 04:06:054790 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224791 version_,
4792 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4793 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054794 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584795 server_maker_.set_hostname("www.example.org");
4796 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594797 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234798 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254799 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234800 mock_quic_data.AddWrite(SYNCHRONOUS,
4801 ConstructInitialSettingsPacket(packet_num++));
4802 }
zhongyi32569c62016-01-08 02:54:304803 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584804 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234805 SYNCHRONOUS,
4806 ConstructClientRequestHeadersPacket(
4807 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4808 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434809
4810 mock_quic_data.AddRead(
4811 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334812 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024813 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434814 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334815 mock_quic_data.AddRead(
4816 ASYNC, ConstructServerDataPacket(
4817 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174818 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234819 mock_quic_data.AddWrite(SYNCHRONOUS,
4820 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434821 // Second QUIC request data.
4822 mock_quic_data.AddWrite(
4823 SYNCHRONOUS,
4824 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234825 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4826 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024827 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434828 mock_quic_data.AddRead(
4829 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334830 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024831 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334832 mock_quic_data.AddRead(
4833 ASYNC, ConstructServerDataPacket(
4834 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174835 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434836 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234837 SYNCHRONOUS,
4838 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304839 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4840 mock_quic_data.AddRead(ASYNC, 0); // EOF
4841
4842 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304843
rtennetib8e80fb2016-05-16 00:12:094844 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324845 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564846 QuicStreamFactoryPeer::SetAlarmFactory(
4847 session_->quic_stream_factory(),
4848 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224849 context_.clock()));
zhongyi32569c62016-01-08 02:54:304850
4851 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294852 request_.url = GURL("https://www.example.org/");
4853 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304854 request_.url = GURL("https://mail.example.org/");
4855 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4856
rch9ae5b3b2016-02-11 00:36:294857 // Open a QUIC session to mail.example.org:443 when making request
4858 // to mail.example.org.
4859 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454860 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304861
rch9ae5b3b2016-02-11 00:36:294862 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304863 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454864 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524865}
4866
4867TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524868 MockRead http_reads[] = {
4869 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564870 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524871 MockRead("hello world"),
4872 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4873 MockRead(ASYNC, OK)};
4874
Ryan Sleevib8d7ea02018-05-07 20:01:014875 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524876 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084877 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564878 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524879
rtennetib8e80fb2016-05-16 00:12:094880 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324881 CreateSession();
bncc958faa2015-07-31 18:14:524882
4883 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454884
4885 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344886 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494887 http_server_properties_->GetAlternativeServiceInfos(
4888 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344889 ASSERT_EQ(1u, alternative_service_info_vector.size());
4890 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544891 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344892 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4893 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4894 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524895}
4896
4897TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524898 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564899 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4900 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524901 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4902 MockRead(ASYNC, OK)};
4903
Ryan Sleevib8d7ea02018-05-07 20:01:014904 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524905 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084906 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564907 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524908
Ryan Hamiltonabad59e2019-06-06 04:02:594909 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234910 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254911 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234912 mock_quic_data.AddWrite(SYNCHRONOUS,
4913 ConstructInitialSettingsPacket(packet_num++));
4914 }
rch5cb522462017-04-25 20:18:364915 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234916 SYNCHRONOUS,
4917 ConstructClientRequestHeadersPacket(
4918 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4919 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434920 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334921 ASYNC, ConstructServerResponseHeadersPacket(
4922 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4923 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434924 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334925 mock_quic_data.AddRead(
4926 ASYNC, ConstructServerDataPacket(
4927 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174928 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234929 mock_quic_data.AddWrite(SYNCHRONOUS,
4930 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524931 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4932 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524933
4934 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4935
rtennetib8e80fb2016-05-16 00:12:094936 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324937 CreateSession();
bncc958faa2015-07-31 18:14:524938
bnc3472afd2016-11-17 15:27:214939 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524940 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494941 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054942 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494943 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054944 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524945
4946 SendRequestAndExpectHttpResponse("hello world");
4947 SendRequestAndExpectQuicResponse("hello!");
4948
mmenkee24011922015-12-17 22:12:594949 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524950
Matt Menke3233d8f22019-08-20 21:01:494951 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054952 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444953 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4954 url::SchemeHostPort("https", request_.url.host(), 443),
4955 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524956}
4957
Matt Menkeb32ba5122019-09-10 19:17:054958TEST_P(QuicNetworkTransactionTest,
4959 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4960 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4961 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4962 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4963 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4964
4965 base::test::ScopedFeatureList feature_list;
4966 feature_list.InitWithFeatures(
4967 // enabled_features
4968 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4969 features::kPartitionConnectionsByNetworkIsolationKey},
4970 // disabled_features
4971 {});
4972 // Since HttpServerProperties caches the feature value, have to create a new
4973 // one.
4974 http_server_properties_ = std::make_unique<HttpServerProperties>();
4975
4976 MockRead http_reads[] = {
4977 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4978 MockRead("hello world"),
4979 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4980 MockRead(ASYNC, OK)};
4981
4982 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4983 socket_factory_.AddSocketDataProvider(&http_data);
4984 AddCertificate(&ssl_data_);
4985 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4986
4987 MockQuicData mock_quic_data(version_);
4988 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254989 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054990 mock_quic_data.AddWrite(SYNCHRONOUS,
4991 ConstructInitialSettingsPacket(packet_num++));
4992 }
4993 mock_quic_data.AddWrite(
4994 SYNCHRONOUS,
4995 ConstructClientRequestHeadersPacket(
4996 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4997 true, GetRequestHeaders("GET", "https", "/")));
4998 mock_quic_data.AddRead(
4999 ASYNC, ConstructServerResponseHeadersPacket(
5000 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5001 GetResponseHeaders("200 OK")));
5002 std::string header = ConstructDataHeader(6);
5003 mock_quic_data.AddRead(
5004 ASYNC, ConstructServerDataPacket(
5005 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5006 header + "hello!"));
5007 mock_quic_data.AddWrite(SYNCHRONOUS,
5008 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5009 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5010 mock_quic_data.AddRead(ASYNC, 0); // EOF
5011
5012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5013
5014 CreateSession();
5015
5016 AlternativeService alternative_service(kProtoQUIC,
5017 HostPortPair::FromURL(request_.url));
5018 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5019 alternative_service, kNetworkIsolationKey1);
5020 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5021 alternative_service, kNetworkIsolationKey2);
5022 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5023 alternative_service, kNetworkIsolationKey1));
5024 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5025 alternative_service, kNetworkIsolationKey2));
5026
5027 request_.network_isolation_key = kNetworkIsolationKey1;
5028 SendRequestAndExpectHttpResponse("hello world");
5029 SendRequestAndExpectQuicResponse("hello!");
5030
5031 mock_quic_data.Resume();
5032
5033 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5034 alternative_service, kNetworkIsolationKey1));
5035 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
5036 url::SchemeHostPort("https", request_.url.host(), 443),
5037 kNetworkIsolationKey1));
5038 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5039 alternative_service, kNetworkIsolationKey2));
5040 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5041 url::SchemeHostPort("https", request_.url.host(), 443),
5042 kNetworkIsolationKey2));
5043}
5044
bncc958faa2015-07-31 18:14:525045TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:525046 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565047 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5048 MockRead("hello world"),
bncc958faa2015-07-31 18:14:525049 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5050 MockRead(ASYNC, OK)};
5051
Ryan Sleevib8d7ea02018-05-07 20:01:015052 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:525053 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565054 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:525055
Ryan Hamiltonabad59e2019-06-06 04:02:595056 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235057 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255058 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235059 mock_quic_data.AddWrite(SYNCHRONOUS,
5060 ConstructInitialSettingsPacket(packet_num++));
5061 }
rch5cb522462017-04-25 20:18:365062 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235063 SYNCHRONOUS,
5064 ConstructClientRequestHeadersPacket(
5065 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5066 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435067 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335068 ASYNC, ConstructServerResponseHeadersPacket(
5069 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5070 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435071 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335072 mock_quic_data.AddRead(
5073 ASYNC, ConstructServerDataPacket(
5074 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175075 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235076 mock_quic_data.AddWrite(SYNCHRONOUS,
5077 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:525078 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
5079
5080 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5081
5082 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325083 CreateSession();
bncc958faa2015-07-31 18:14:525084
5085 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
5086 SendRequestAndExpectHttpResponse("hello world");
5087}
5088
tbansalc3308d72016-08-27 10:25:045089// Tests that the connection to an HTTPS proxy is raced with an available
5090// alternative proxy server.
5091TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:275092 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595093 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495094 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045095
Ryan Hamiltonabad59e2019-06-06 04:02:595096 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235097 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255098 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235099 mock_quic_data.AddWrite(SYNCHRONOUS,
5100 ConstructInitialSettingsPacket(packet_num++));
5101 }
rch5cb522462017-04-25 20:18:365102 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235103 SYNCHRONOUS,
5104 ConstructClientRequestHeadersPacket(
5105 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5106 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435107 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335108 ASYNC, ConstructServerResponseHeadersPacket(
5109 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5110 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435111 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335112 mock_quic_data.AddRead(
5113 ASYNC, ConstructServerDataPacket(
5114 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175115 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235116 mock_quic_data.AddWrite(SYNCHRONOUS,
5117 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:045118 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5119 mock_quic_data.AddRead(ASYNC, 0); // EOF
5120
5121 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5122
5123 // There is no need to set up main job, because no attempt will be made to
5124 // speak to the proxy over TCP.
5125 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:045126 TestProxyDelegate test_proxy_delegate;
5127 const HostPortPair host_port_pair("mail.example.org", 443);
5128
5129 test_proxy_delegate.set_alternative_proxy_server(
5130 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525131 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045132 CreateSession();
5133 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5134
5135 // The main job needs to hang in order to guarantee that the alternative
5136 // proxy server job will "win".
5137 AddHangingNonAlternateProtocolSocketData();
5138
5139 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
5140
5141 // Verify that the alternative proxy server is not marked as broken.
5142 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5143
5144 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595145 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275146
5147 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5148 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5149 1);
tbansalc3308d72016-08-27 10:25:045150}
5151
bnc1c196c6e2016-05-28 13:51:485152TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:305153 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275154 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:305155
5156 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:565157 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:295158 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565159 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:305160
5161 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565162 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485163 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565164 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:305165
Ryan Sleevib8d7ea02018-05-07 20:01:015166 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505167 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:085168 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:505169 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305170
5171 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:455172 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:305173 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:455174 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:305175 };
Ryan Sleevib8d7ea02018-05-07 20:01:015176 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:505177 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:305178
5179 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:015180 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505181 socket_factory_.AddSocketDataProvider(&http_data2);
5182 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305183
bnc912a04b2016-04-20 14:19:505184 CreateSession();
[email protected]dda75ab2013-06-22 22:43:305185
5186 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:305187 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:175188 ASSERT_TRUE(http_data.AllReadDataConsumed());
5189 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305190
5191 // Now run the second request in which the QUIC socket hangs,
5192 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:305193 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455194 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305195
rch37de576c2015-05-17 20:28:175196 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5197 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455198 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305199}
5200
[email protected]1e960032013-12-20 19:00:205201TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435202 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5203 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5204 return;
5205 }
5206
Ryan Hamiltonabad59e2019-06-06 04:02:595207 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035208 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495209 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255210 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495211 mock_quic_data.AddWrite(SYNCHRONOUS,
5212 ConstructInitialSettingsPacket(packet_num++));
5213 }
Zhongyi Shi32f2fd02018-04-16 18:23:435214 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495215 SYNCHRONOUS,
5216 ConstructClientRequestHeadersPacket(
5217 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5218 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435219 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335220 ASYNC, ConstructServerResponseHeadersPacket(
5221 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5222 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435223 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335224 mock_quic_data.AddRead(
5225 ASYNC, ConstructServerDataPacket(
5226 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175227 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495228 mock_quic_data.AddWrite(SYNCHRONOUS,
5229 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505230 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595231 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485232
rcha5399e02015-04-21 19:32:045233 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485234
rtennetib8e80fb2016-05-16 00:12:095235 // The non-alternate protocol job needs to hang in order to guarantee that
5236 // the alternate-protocol job will "win".
5237 AddHangingNonAlternateProtocolSocketData();
5238
rch3f4b8452016-02-23 16:59:325239 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275240 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195241 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305242
Matt Menke19475f72019-08-21 18:57:445243 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5244 url::SchemeHostPort("https", request_.url.host(), 443),
5245 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485246}
5247
[email protected]1e960032013-12-20 19:00:205248TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435249 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5250 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5251 return;
5252 }
5253
Ryan Hamiltonabad59e2019-06-06 04:02:595254 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035255 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495256 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255257 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495258 mock_quic_data.AddWrite(
5259 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5260 }
Fan Yang32c5a112018-12-10 20:06:335261 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495262 SYNCHRONOUS,
5263 ConstructClientRequestHeadersPacket(
5264 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5265 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435266 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335267 ASYNC, ConstructServerResponseHeadersPacket(
5268 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5269 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435270 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335271 mock_quic_data.AddRead(
5272 ASYNC, ConstructServerDataPacket(
5273 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175274 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495275 mock_quic_data.AddWrite(SYNCHRONOUS,
5276 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505277 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595278 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045279 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275280
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]3a120a6b2013-06-25 01:08:275287
rtennetib8e80fb2016-05-16 00:12:095288 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325289 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275290 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275291 SendRequestAndExpectQuicResponse("hello!");
5292}
5293
[email protected]0fc924b2014-03-31 04:34:155294TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495295 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5296 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155297
5298 // Since we are using a proxy, the QUIC job will not succeed.
5299 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295300 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5301 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565302 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155303
5304 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565305 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485306 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565307 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155308
Ryan Sleevib8d7ea02018-05-07 20:01:015309 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155310 socket_factory_.AddSocketDataProvider(&http_data);
5311
5312 // In order for a new QUIC session to be established via alternate-protocol
5313 // without racing an HTTP connection, we need the host resolution to happen
5314 // synchronously.
5315 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295316 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565317 "");
[email protected]0fc924b2014-03-31 04:34:155318
rch9ae5b3b2016-02-11 00:36:295319 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325320 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275321 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155322 SendRequestAndExpectHttpResponse("hello world");
5323}
5324
[email protected]1e960032013-12-20 19:00:205325TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435326 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5327 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5328 return;
5329 }
5330
Ryan Hamiltonabad59e2019-06-06 04:02:595331 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235332 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495333 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255334 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235335 mock_quic_data.AddWrite(SYNCHRONOUS,
5336 ConstructInitialSettingsPacket(packet_num++));
5337 }
Nick Harper057264a82019-09-12 23:33:495338 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365339 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235340 SYNCHRONOUS,
5341 ConstructClientRequestHeadersPacket(
5342 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5343 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435344 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335345 ASYNC, ConstructServerResponseHeadersPacket(
5346 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5347 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435348 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335349 mock_quic_data.AddRead(
5350 ASYNC, ConstructServerDataPacket(
5351 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175352 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235353 mock_quic_data.AddWrite(SYNCHRONOUS,
5354 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595355 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045356 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125357
rtennetib8e80fb2016-05-16 00:12:095358 // The non-alternate protocol job needs to hang in order to guarantee that
5359 // the alternate-protocol job will "win".
5360 AddHangingNonAlternateProtocolSocketData();
5361
[email protected]11c05872013-08-20 02:04:125362 // In order for a new QUIC session to be established via alternate-protocol
5363 // without racing an HTTP connection, we need the host resolution to happen
5364 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5365 // connection to the the server, in this test we require confirmation
5366 // before encrypting so the HTTP job will still start.
5367 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295368 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565369 "");
[email protected]11c05872013-08-20 02:04:125370
rch3f4b8452016-02-23 16:59:325371 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435372 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5373 false);
Ryan Hamilton9835e662018-08-02 05:36:275374 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125375
bnc691fda62016-08-12 00:43:165376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125377 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365378 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125380
5381 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525382 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015383 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505384
bnc691fda62016-08-12 00:43:165385 CheckWasQuicResponse(&trans);
5386 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125387}
5388
Steven Valdez58097ec32018-07-16 18:29:045389TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435390 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5391 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5392 return;
5393 }
5394
Ryan Hamilton3cc2c152019-07-09 19:36:015395 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595396 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035397 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255398 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495399 mock_quic_data.AddWrite(
5400 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5401 }
Steven Valdez58097ec32018-07-16 18:29:045402 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015403 SYNCHRONOUS,
5404 ConstructClientRequestHeadersPacket(
5405 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5406 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335407 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025408 ASYNC, ConstructServerResponseHeadersPacket(
5409 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5410 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075411 if (VersionUsesHttp3(version_.transport_version)) {
5412 mock_quic_data.AddWrite(
5413 SYNCHRONOUS,
5414 ConstructClientAckAndDataPacket(
5415 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5416 StreamCancellationQpackDecoderInstruction(0)));
5417 mock_quic_data.AddWrite(SYNCHRONOUS,
5418 client_maker_.MakeRstPacket(
5419 packet_number++, false,
5420 GetNthClientInitiatedBidirectionalStreamId(0),
5421 quic::QUIC_STREAM_CANCELLED));
5422 } else {
5423 mock_quic_data.AddWrite(
5424 SYNCHRONOUS,
5425 ConstructClientAckAndRstPacket(
5426 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5427 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5428 }
Steven Valdez58097ec32018-07-16 18:29:045429
5430 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5431
Steven Valdez58097ec32018-07-16 18:29:045432 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015433 SYNCHRONOUS,
5434 ConstructClientRequestHeadersPacket(
5435 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5436 true, GetRequestHeaders("GET", "https", "/"),
5437 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045438 mock_quic_data.AddRead(
5439 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335440 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025441 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435442 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045443 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335444 ASYNC, ConstructServerDataPacket(
5445 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175446 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045447 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015448 SYNCHRONOUS,
5449 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045450 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5451 mock_quic_data.AddRead(ASYNC, 0); // EOF
5452
5453 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5454
5455 // In order for a new QUIC session to be established via alternate-protocol
5456 // without racing an HTTP connection, we need the host resolution to happen
5457 // synchronously.
5458 host_resolver_.set_synchronous_mode(true);
5459 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5460 "");
Steven Valdez58097ec32018-07-16 18:29:045461
5462 AddHangingNonAlternateProtocolSocketData();
5463 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275464 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565465 QuicStreamFactoryPeer::SetAlarmFactory(
5466 session_->quic_stream_factory(),
5467 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225468 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045469
5470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5471 TestCompletionCallback callback;
5472 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5474
5475 // Confirm the handshake after the 425 Too Early.
5476 base::RunLoop().RunUntilIdle();
5477
5478 // The handshake hasn't been confirmed yet, so the retry should not have
5479 // succeeded.
5480 EXPECT_FALSE(callback.have_result());
5481
5482 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5483 quic::QuicSession::HANDSHAKE_CONFIRMED);
5484
5485 EXPECT_THAT(callback.WaitForResult(), IsOk());
5486 CheckWasQuicResponse(&trans);
5487 CheckResponseData(&trans, "hello!");
5488}
5489
5490TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435491 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5492 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5493 return;
5494 }
5495
Ryan Hamilton3cc2c152019-07-09 19:36:015496 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595497 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035498 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255499 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495500 mock_quic_data.AddWrite(
5501 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5502 }
Steven Valdez58097ec32018-07-16 18:29:045503 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015504 SYNCHRONOUS,
5505 ConstructClientRequestHeadersPacket(
5506 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5507 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335508 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025509 ASYNC, ConstructServerResponseHeadersPacket(
5510 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5511 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075512 if (VersionUsesHttp3(version_.transport_version)) {
5513 mock_quic_data.AddWrite(
5514 SYNCHRONOUS,
5515 ConstructClientAckAndDataPacket(
5516 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5517 StreamCancellationQpackDecoderInstruction(0)));
5518 mock_quic_data.AddWrite(SYNCHRONOUS,
5519 client_maker_.MakeRstPacket(
5520 packet_number++, false,
5521 GetNthClientInitiatedBidirectionalStreamId(0),
5522 quic::QUIC_STREAM_CANCELLED));
5523 } else {
5524 mock_quic_data.AddWrite(
5525 SYNCHRONOUS,
5526 ConstructClientAckAndRstPacket(
5527 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5528 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5529 }
Steven Valdez58097ec32018-07-16 18:29:045530
5531 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5532
Steven Valdez58097ec32018-07-16 18:29:045533 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015534 SYNCHRONOUS,
5535 ConstructClientRequestHeadersPacket(
5536 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5537 true, GetRequestHeaders("GET", "https", "/"),
5538 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335539 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025540 ASYNC, ConstructServerResponseHeadersPacket(
5541 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5542 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075543 if (VersionUsesHttp3(version_.transport_version)) {
5544 mock_quic_data.AddWrite(
5545 SYNCHRONOUS,
5546 ConstructClientAckAndDataPacket(
5547 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
5548 StreamCancellationQpackDecoderInstruction(1)));
5549 mock_quic_data.AddWrite(SYNCHRONOUS,
5550 client_maker_.MakeRstPacket(
5551 packet_number++, false,
5552 GetNthClientInitiatedBidirectionalStreamId(1),
5553 quic::QUIC_STREAM_CANCELLED));
5554 } else {
5555 mock_quic_data.AddWrite(
5556 SYNCHRONOUS,
5557 ConstructClientAckAndRstPacket(
5558 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5559 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
5560 }
Steven Valdez58097ec32018-07-16 18:29:045561 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5562 mock_quic_data.AddRead(ASYNC, 0); // EOF
5563
5564 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5565
5566 // In order for a new QUIC session to be established via alternate-protocol
5567 // without racing an HTTP connection, we need the host resolution to happen
5568 // synchronously.
5569 host_resolver_.set_synchronous_mode(true);
5570 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5571 "");
Steven Valdez58097ec32018-07-16 18:29:045572
5573 AddHangingNonAlternateProtocolSocketData();
5574 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275575 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565576 QuicStreamFactoryPeer::SetAlarmFactory(
5577 session_->quic_stream_factory(),
5578 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225579 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045580
5581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5582 TestCompletionCallback callback;
5583 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5585
5586 // Confirm the handshake after the 425 Too Early.
5587 base::RunLoop().RunUntilIdle();
5588
5589 // The handshake hasn't been confirmed yet, so the retry should not have
5590 // succeeded.
5591 EXPECT_FALSE(callback.have_result());
5592
5593 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5594 quic::QuicSession::HANDSHAKE_CONFIRMED);
5595
5596 EXPECT_THAT(callback.WaitForResult(), IsOk());
5597 const HttpResponseInfo* response = trans.GetResponseInfo();
5598 ASSERT_TRUE(response != nullptr);
5599 ASSERT_TRUE(response->headers.get() != nullptr);
5600 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5601 EXPECT_TRUE(response->was_fetched_via_spdy);
5602 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085603 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5604 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045605}
5606
zhongyica364fbb2015-12-12 03:39:125607TEST_P(QuicNetworkTransactionTest,
5608 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435609 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5610 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5611 return;
5612 }
5613
Victor Vasilieva1e66d72019-12-05 17:55:385614 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595615 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235616 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495617 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255618 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235619 mock_quic_data.AddWrite(SYNCHRONOUS,
5620 ConstructInitialSettingsPacket(packet_num++));
5621 }
Nick Harper057264a82019-09-12 23:33:495622 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365623 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235624 SYNCHRONOUS,
5625 ConstructClientRequestHeadersPacket(
5626 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5627 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125628 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525629 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435630 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125631 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5632
5633 // The non-alternate protocol job needs to hang in order to guarantee that
5634 // the alternate-protocol job will "win".
5635 AddHangingNonAlternateProtocolSocketData();
5636
5637 // In order for a new QUIC session to be established via alternate-protocol
5638 // without racing an HTTP connection, we need the host resolution to happen
5639 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5640 // connection to the the server, in this test we require confirmation
5641 // before encrypting so the HTTP job will still start.
5642 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295643 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125644 "");
zhongyica364fbb2015-12-12 03:39:125645
rch3f4b8452016-02-23 16:59:325646 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435647 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5648 false);
Ryan Hamilton9835e662018-08-02 05:36:275649 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125650
bnc691fda62016-08-12 00:43:165651 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125652 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365653 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015654 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125655
5656 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525657 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015658 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125659
5660 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);
zhongyica364fbb2015-12-12 03:39:125664 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525665 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5666 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125667}
5668
5669TEST_P(QuicNetworkTransactionTest,
5670 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435671 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5672 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5673 return;
5674 }
5675
Victor Vasilieva1e66d72019-12-05 17:55:385676 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595677 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235678 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495679 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255680 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235681 mock_quic_data.AddWrite(SYNCHRONOUS,
5682 ConstructInitialSettingsPacket(packet_num++));
5683 }
Nick Harper057264a82019-09-12 23:33:495684 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365685 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235686 SYNCHRONOUS,
5687 ConstructClientRequestHeadersPacket(
5688 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5689 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215690 // Peer sending data from an non-existing stream causes this end to raise
5691 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335692 mock_quic_data.AddRead(
5693 ASYNC, ConstructServerRstPacket(
5694 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5695 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215696 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375697 mock_quic_data.AddWrite(
5698 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5699 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5700 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
5701 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125702 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5703
5704 // The non-alternate protocol job needs to hang in order to guarantee that
5705 // the alternate-protocol job will "win".
5706 AddHangingNonAlternateProtocolSocketData();
5707
5708 // In order for a new QUIC session to be established via alternate-protocol
5709 // without racing an HTTP connection, we need the host resolution to happen
5710 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5711 // connection to the the server, in this test we require confirmation
5712 // before encrypting so the HTTP job will still start.
5713 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295714 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125715 "");
zhongyica364fbb2015-12-12 03:39:125716
rch3f4b8452016-02-23 16:59:325717 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435718 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5719 false);
Ryan Hamilton9835e662018-08-02 05:36:275720 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125721
bnc691fda62016-08-12 00:43:165722 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125723 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365724 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125726
5727 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525728 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015729 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125730 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525731 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125732
bnc691fda62016-08-12 00:43:165733 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525734 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125735}
5736
Nick Harper057264a82019-09-12 23:33:495737TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435738 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5739 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5740 return;
5741 }
5742
Ryan Hamiltonabad59e2019-06-06 04:02:595743 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235744 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495745 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255746 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235747 mock_quic_data.AddWrite(SYNCHRONOUS,
5748 ConstructInitialSettingsPacket(packet_num++));
5749 }
Nick Harper057264a82019-09-12 23:33:495750 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365751 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235752 SYNCHRONOUS,
5753 ConstructClientRequestHeadersPacket(
5754 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5755 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485756 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335757 mock_quic_data.AddRead(
5758 ASYNC, ConstructServerResponseHeadersPacket(
5759 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5760 GetResponseHeaders("200 OK")));
5761 mock_quic_data.AddRead(
5762 ASYNC, ConstructServerRstPacket(
5763 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5764 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075765
5766 if (VersionUsesHttp3(version_.transport_version)) {
5767 mock_quic_data.AddWrite(
5768 SYNCHRONOUS,
5769 ConstructClientAckAndDataPacket(
5770 packet_num++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
5771 StreamCancellationQpackDecoderInstruction(0)));
5772 } else {
5773 mock_quic_data.AddWrite(SYNCHRONOUS,
5774 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5775 }
rchcd5f1c62016-06-23 02:43:485776 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5777 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5778
5779 // The non-alternate protocol job needs to hang in order to guarantee that
5780 // the alternate-protocol job will "win".
5781 AddHangingNonAlternateProtocolSocketData();
5782
5783 // In order for a new QUIC session to be established via alternate-protocol
5784 // without racing an HTTP connection, we need the host resolution to happen
5785 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5786 // connection to the the server, in this test we require confirmation
5787 // before encrypting so the HTTP job will still start.
5788 host_resolver_.set_synchronous_mode(true);
5789 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5790 "");
rchcd5f1c62016-06-23 02:43:485791
5792 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435793 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5794 false);
Ryan Hamilton9835e662018-08-02 05:36:275795 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485796
bnc691fda62016-08-12 00:43:165797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485798 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365799 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485801
5802 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525803 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485804 // Read the headers.
robpercival214763f2016-07-01 23:27:015805 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485806
bnc691fda62016-08-12 00:43:165807 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485808 ASSERT_TRUE(response != nullptr);
5809 ASSERT_TRUE(response->headers.get() != nullptr);
5810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5811 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525812 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085813 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5814 response->connection_info);
rchcd5f1c62016-06-23 02:43:485815
5816 std::string response_data;
bnc691fda62016-08-12 00:43:165817 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485818}
5819
Nick Harper057264a82019-09-12 23:33:495820TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435821 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5822 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5823 return;
5824 }
5825
Victor Vasilieva1e66d72019-12-05 17:55:385826 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595827 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235828 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495829 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255830 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235831 mock_quic_data.AddWrite(SYNCHRONOUS,
5832 ConstructInitialSettingsPacket(packet_num++));
5833 }
Nick Harper057264a82019-09-12 23:33:495834 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365835 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235836 SYNCHRONOUS,
5837 ConstructClientRequestHeadersPacket(
5838 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5839 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335840 mock_quic_data.AddRead(
5841 ASYNC, ConstructServerRstPacket(
5842 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5843 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075844
5845 if (VersionUsesHttp3(version_.transport_version)) {
5846 mock_quic_data.AddWrite(
5847 SYNCHRONOUS, ConstructClientDataPacket(
5848 packet_num++, GetQpackDecoderStreamId(), true, false,
5849 StreamCancellationQpackDecoderInstruction(0)));
5850 }
5851
rchcd5f1c62016-06-23 02:43:485852 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5853 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5854
5855 // The non-alternate protocol job needs to hang in order to guarantee that
5856 // the alternate-protocol job will "win".
5857 AddHangingNonAlternateProtocolSocketData();
5858
5859 // In order for a new QUIC session to be established via alternate-protocol
5860 // without racing an HTTP connection, we need the host resolution to happen
5861 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5862 // connection to the the server, in this test we require confirmation
5863 // before encrypting so the HTTP job will still start.
5864 host_resolver_.set_synchronous_mode(true);
5865 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5866 "");
rchcd5f1c62016-06-23 02:43:485867
5868 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435869 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5870 false);
Ryan Hamilton9835e662018-08-02 05:36:275871 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485872
bnc691fda62016-08-12 00:43:165873 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485874 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365875 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015876 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485877
5878 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525879 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485880 // Read the headers.
robpercival214763f2016-07-01 23:27:015881 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485882}
5883
[email protected]1e960032013-12-20 19:00:205884TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305885 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525886 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585887 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305888 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505889 MockRead(ASYNC, close->data(), close->length()),
5890 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5891 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305892 };
Ryan Sleevib8d7ea02018-05-07 20:01:015893 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305894 socket_factory_.AddSocketDataProvider(&quic_data);
5895
5896 // Main job which will succeed even though the alternate job fails.
5897 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025898 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5900 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305901
Ryan Sleevib8d7ea02018-05-07 20:01:015902 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305903 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565904 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305905
rch3f4b8452016-02-23 16:59:325906 CreateSession();
David Schinazic8281052019-01-24 06:14:175907 AddQuicAlternateProtocolMapping(
5908 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195909 SendRequestAndExpectHttpResponse("hello from http");
5910 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305911}
5912
Matt Menkeb32ba5122019-09-10 19:17:055913TEST_P(QuicNetworkTransactionTest,
5914 BrokenAlternateProtocolWithNetworkIsolationKey) {
5915 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5916 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5917 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5918 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5919
5920 base::test::ScopedFeatureList feature_list;
5921 feature_list.InitWithFeatures(
5922 // enabled_features
5923 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5924 features::kPartitionConnectionsByNetworkIsolationKey},
5925 // disabled_features
5926 {});
5927 // Since HttpServerProperties caches the feature value, have to create a new
5928 // one.
5929 http_server_properties_ = std::make_unique<HttpServerProperties>();
5930
5931 // Alternate-protocol job
5932 std::unique_ptr<quic::QuicEncryptedPacket> close(
5933 ConstructServerConnectionClosePacket(1));
5934 MockRead quic_reads[] = {
5935 MockRead(ASYNC, close->data(), close->length()),
5936 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5937 MockRead(ASYNC, OK), // EOF
5938 };
5939 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5940 socket_factory_.AddSocketDataProvider(&quic_data);
5941
5942 // Main job which will succeed even though the alternate job fails.
5943 MockRead http_reads[] = {
5944 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5945 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5946 MockRead(ASYNC, OK)};
5947
5948 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5949 socket_factory_.AddSocketDataProvider(&http_data);
5950 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5951
5952 CreateSession();
5953 AddQuicAlternateProtocolMapping(
5954 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5955 AddQuicAlternateProtocolMapping(
5956 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5957 request_.network_isolation_key = kNetworkIsolationKey1;
5958 SendRequestAndExpectHttpResponse("hello from http");
5959
5960 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5961 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5962}
5963
[email protected]1e960032013-12-20 19:00:205964TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595965 // Alternate-protocol job
5966 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025967 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595968 };
Ryan Sleevib8d7ea02018-05-07 20:01:015969 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595970 socket_factory_.AddSocketDataProvider(&quic_data);
5971
5972 // Main job which will succeed even though the alternate job fails.
5973 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025974 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5975 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5976 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595977
Ryan Sleevib8d7ea02018-05-07 20:01:015978 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595979 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565980 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595981
rch3f4b8452016-02-23 16:59:325982 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595983
Ryan Hamilton9835e662018-08-02 05:36:275984 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195985 SendRequestAndExpectHttpResponse("hello from http");
5986 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595987}
5988
[email protected]00c159f2014-05-21 22:38:165989TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535990 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165991 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025992 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165993 };
Ryan Sleevib8d7ea02018-05-07 20:01:015994 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165995 socket_factory_.AddSocketDataProvider(&quic_data);
5996
[email protected]eb71ab62014-05-23 07:57:535997 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165998 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025999 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:166000 };
6001
Ryan Sleevib8d7ea02018-05-07 20:01:016002 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:166003 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6004 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566005 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:166006
rtennetib8e80fb2016-05-16 00:12:096007 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326008 CreateSession();
[email protected]00c159f2014-05-21 22:38:166009
Ryan Hamilton9835e662018-08-02 05:36:276010 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:166011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:166012 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166013 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6015 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:166016 ExpectQuicAlternateProtocolMapping();
6017}
6018
Zhongyi Shia0cef1082017-08-25 01:49:506019TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436020 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6021 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6022 return;
6023 }
6024
Zhongyi Shia0cef1082017-08-25 01:49:506025 // Tests that TCP job is delayed and QUIC job does not require confirmation
6026 // if QUIC was recently supported on the same IP on start.
6027
6028 // Set QUIC support on the last IP address, which is same with the local IP
6029 // address. Require confirmation mode will be turned off immediately when
6030 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436031 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6032 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:506033
Ryan Hamiltonabad59e2019-06-06 04:02:596034 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:036035 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:496036 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256037 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:496038 mock_quic_data.AddWrite(SYNCHRONOUS,
6039 ConstructInitialSettingsPacket(packet_number++));
6040 }
Zhongyi Shi32f2fd02018-04-16 18:23:436041 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:496042 SYNCHRONOUS,
6043 ConstructClientRequestHeadersPacket(
6044 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6045 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436046 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336047 ASYNC, ConstructServerResponseHeadersPacket(
6048 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6049 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436050 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336051 mock_quic_data.AddRead(
6052 ASYNC, ConstructServerDataPacket(
6053 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176054 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:496055 mock_quic_data.AddWrite(SYNCHRONOUS,
6056 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506057 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6058 mock_quic_data.AddRead(ASYNC, 0); // EOF
6059
6060 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6061 // No HTTP data is mocked as TCP job never starts in this case.
6062
6063 CreateSession();
6064 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:436065 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6066 false);
Zhongyi Shia0cef1082017-08-25 01:49:506067
Ryan Hamilton9835e662018-08-02 05:36:276068 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506069
6070 // Stall host resolution so that QUIC job will not succeed synchronously.
6071 // Socket will not be configured immediately and QUIC support is not sorted
6072 // out, TCP job will still be delayed as server properties indicates QUIC
6073 // support on last IP address.
6074 host_resolver_.set_synchronous_mode(false);
6075
6076 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6077 TestCompletionCallback callback;
6078 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6079 IsError(ERR_IO_PENDING));
6080 // Complete host resolution in next message loop so that QUIC job could
6081 // proceed.
6082 base::RunLoop().RunUntilIdle();
6083 EXPECT_THAT(callback.WaitForResult(), IsOk());
6084
6085 CheckWasQuicResponse(&trans);
6086 CheckResponseData(&trans, "hello!");
6087}
6088
6089TEST_P(QuicNetworkTransactionTest,
6090 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436091 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6092 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6093 return;
6094 }
6095
Zhongyi Shia0cef1082017-08-25 01:49:506096 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
6097 // was recently supported on a different IP address on start.
6098
6099 // Set QUIC support on the last IP address, which is different with the local
6100 // IP address. Require confirmation mode will remain when local IP address is
6101 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436102 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6103 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:506104
Ryan Hamiltonabad59e2019-06-06 04:02:596105 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236106 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:496107 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:256108 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236109 mock_quic_data.AddWrite(SYNCHRONOUS,
6110 ConstructInitialSettingsPacket(packet_num++));
6111 }
Nick Harper057264a82019-09-12 23:33:496112 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:506113 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236114 SYNCHRONOUS,
6115 ConstructClientRequestHeadersPacket(
6116 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6117 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436118 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336119 ASYNC, ConstructServerResponseHeadersPacket(
6120 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6121 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436122 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336123 mock_quic_data.AddRead(
6124 ASYNC, ConstructServerDataPacket(
6125 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176126 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236127 mock_quic_data.AddWrite(SYNCHRONOUS,
6128 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506129 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6130 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6131 // No HTTP data is mocked as TCP job will be delayed and never starts.
6132
6133 CreateSession();
Matt Menkeb566c392019-09-11 23:22:436134 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6135 false);
Ryan Hamilton9835e662018-08-02 05:36:276136 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506137
6138 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
6139 // Socket will not be configured immediately and QUIC support is not sorted
6140 // out, TCP job will still be delayed as server properties indicates QUIC
6141 // support on last IP address.
6142 host_resolver_.set_synchronous_mode(false);
6143
6144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6145 TestCompletionCallback callback;
6146 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6147 IsError(ERR_IO_PENDING));
6148
6149 // Complete host resolution in next message loop so that QUIC job could
6150 // proceed.
6151 base::RunLoop().RunUntilIdle();
6152 // Explicitly confirm the handshake so that QUIC job could succeed.
6153 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526154 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:506155 EXPECT_THAT(callback.WaitForResult(), IsOk());
6156
6157 CheckWasQuicResponse(&trans);
6158 CheckResponseData(&trans, "hello!");
6159}
6160
Ryan Hamilton75f197262017-08-17 14:00:076161TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
6162 // Test that NetErrorDetails is correctly populated, even if the
6163 // handshake has not yet been confirmed and no stream has been created.
6164
6165 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:596166 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:076167 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6168 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
6169 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6170
6171 // Main job will also fail.
6172 MockRead http_reads[] = {
6173 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6174 };
6175
Ryan Sleevib8d7ea02018-05-07 20:01:016176 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:076177 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6178 socket_factory_.AddSocketDataProvider(&http_data);
6179 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6180
6181 AddHangingNonAlternateProtocolSocketData();
6182 CreateSession();
6183 // Require handshake confirmation to ensure that no QUIC streams are
6184 // created, and to ensure that the TCP job does not wait for the QUIC
6185 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:436186 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6187 false);
Ryan Hamilton75f197262017-08-17 14:00:076188
Ryan Hamilton9835e662018-08-02 05:36:276189 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:076190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6191 TestCompletionCallback callback;
6192 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6193 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6194 // Allow the TCP job to fail.
6195 base::RunLoop().RunUntilIdle();
6196 // Now let the QUIC job fail.
6197 mock_quic_data.Resume();
6198 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6199 ExpectQuicAlternateProtocolMapping();
6200 NetErrorDetails details;
6201 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526202 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:076203}
6204
[email protected]1e960032013-12-20 19:00:206205TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:456206 // Alternate-protocol job
6207 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:026208 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:456209 };
Ryan Sleevib8d7ea02018-05-07 20:01:016210 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:456211 socket_factory_.AddSocketDataProvider(&quic_data);
6212
[email protected]c92c1b52014-05-31 04:16:066213 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:016214 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:066215 socket_factory_.AddSocketDataProvider(&quic_data2);
6216
[email protected]4d283b32013-10-17 12:57:276217 // Final job that will proceed when the QUIC job fails.
6218 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026219 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6220 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6221 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:276222
Ryan Sleevib8d7ea02018-05-07 20:01:016223 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:276224 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566225 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:276226
rch3f4b8452016-02-23 16:59:326227 CreateSession();
[email protected]77c6c162013-08-17 02:57:456228
Ryan Hamilton9835e662018-08-02 05:36:276229 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:456230
[email protected]4d283b32013-10-17 12:57:276231 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:456232
6233 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:276234
rch37de576c2015-05-17 20:28:176235 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6236 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:456237}
6238
Matt Menkeb32ba5122019-09-10 19:17:056239TEST_P(QuicNetworkTransactionTest,
6240 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436241 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6242 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6243 return;
6244 }
6245
Matt Menkeb32ba5122019-09-10 19:17:056246 base::test::ScopedFeatureList feature_list;
6247 feature_list.InitWithFeatures(
6248 // enabled_features
6249 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
6250 features::kPartitionConnectionsByNetworkIsolationKey},
6251 // disabled_features
6252 {});
6253 // Since HttpServerProperties caches the feature value, have to create a new
6254 // one.
6255 http_server_properties_ = std::make_unique<HttpServerProperties>();
6256
6257 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
6258 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
6259 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
6260 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
6261
6262 // Alternate-protocol job
6263 MockRead quic_reads[] = {
6264 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6265 };
6266 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
6267 socket_factory_.AddSocketDataProvider(&quic_data);
6268
6269 // Second Alternate-protocol job which will race with the TCP job.
6270 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
6271 socket_factory_.AddSocketDataProvider(&quic_data2);
6272
6273 // Final job that will proceed when the QUIC job fails.
6274 MockRead http_reads[] = {
6275 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6276 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6277 MockRead(ASYNC, OK)};
6278
6279 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6280 socket_factory_.AddSocketDataProvider(&http_data);
6281 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6282
6283 CreateSession();
6284
6285 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6286 kNetworkIsolationKey1);
6287 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6288 kNetworkIsolationKey2);
6289
6290 request_.network_isolation_key = kNetworkIsolationKey1;
6291 SendRequestAndExpectHttpResponse("hello from http");
6292 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6293 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6294
6295 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6296 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6297
6298 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6299 AddHttpDataAndRunRequest();
6300 // Requests using other NetworkIsolationKeys can still use QUIC.
6301 request_.network_isolation_key = kNetworkIsolationKey2;
6302 AddQuicDataAndRunRequest();
6303
6304 // The last two requests should not have changed the alternative service
6305 // mappings.
6306 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6307 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6308}
6309
[email protected]93b31772014-06-19 08:03:356310TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036311 // Alternate-protocol job
6312 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596313 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036314 };
Ryan Sleevib8d7ea02018-05-07 20:01:016315 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036316 socket_factory_.AddSocketDataProvider(&quic_data);
6317
6318 // Main job that will proceed when the QUIC job fails.
6319 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026320 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6321 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6322 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036323
Ryan Sleevib8d7ea02018-05-07 20:01:016324 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036325 socket_factory_.AddSocketDataProvider(&http_data);
6326
rtennetib8e80fb2016-05-16 00:12:096327 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326328 CreateSession();
[email protected]65768442014-06-06 23:37:036329
Ryan Hamilton9835e662018-08-02 05:36:276330 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036331
6332 SendRequestAndExpectHttpResponse("hello from http");
6333}
6334
[email protected]eb71ab62014-05-23 07:57:536335TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336336 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016337 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496338 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336339 socket_factory_.AddSocketDataProvider(&quic_data);
6340
6341 // Main job which will succeed even though the alternate job fails.
6342 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026343 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6344 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6345 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336346
Ryan Sleevib8d7ea02018-05-07 20:01:016347 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336348 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566349 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336350
rch3f4b8452016-02-23 16:59:326351 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276352 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336353 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536354
6355 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336356}
6357
[email protected]4fee9672014-01-08 14:47:156358TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:596359 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176360 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6361 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046362 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156363
6364 // When the QUIC connection fails, we will try the request again over HTTP.
6365 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486366 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566367 MockRead("hello world"),
6368 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6369 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156370
Ryan Sleevib8d7ea02018-05-07 20:01:016371 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156372 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566373 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156374
6375 // In order for a new QUIC session to be established via alternate-protocol
6376 // without racing an HTTP connection, we need the host resolution to happen
6377 // synchronously.
6378 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296379 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566380 "");
[email protected]4fee9672014-01-08 14:47:156381
rch3f4b8452016-02-23 16:59:326382 CreateSession();
David Schinazic8281052019-01-24 06:14:176383 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6384 AddQuicAlternateProtocolMapping(
6385 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156386 SendRequestAndExpectHttpResponse("hello world");
6387}
6388
tbansalc3308d72016-08-27 10:25:046389// For an alternative proxy that supports QUIC, test that the request is
6390// successfully fetched by the main job when the alternate proxy job encounters
6391// an error.
6392TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6393 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6394}
6395TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6396 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6397}
6398TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6399 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6400}
6401TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6402 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6403}
6404TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6405 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6406}
6407TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6408 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6409}
6410TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6411 TestAlternativeProxy(ERR_IO_PENDING);
6412}
6413TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6414 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6415}
6416
6417TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596418 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176419 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6420 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336421 mock_quic_data.AddWrite(
6422 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6423 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6424 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436425 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046426 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6427
6428 // When the QUIC connection fails, we will try the request again over HTTP.
6429 MockRead http_reads[] = {
6430 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6431 MockRead("hello world"),
6432 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6433 MockRead(ASYNC, OK)};
6434
Ryan Sleevib8d7ea02018-05-07 20:01:016435 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046436 socket_factory_.AddSocketDataProvider(&http_data);
6437 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6438
6439 TestProxyDelegate test_proxy_delegate;
6440 const HostPortPair host_port_pair("myproxy.org", 443);
6441 test_proxy_delegate.set_alternative_proxy_server(
6442 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6443 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6444
Ramin Halavatica8d5252018-03-12 05:33:496445 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6446 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526447 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046448 request_.url = GURL("http://mail.example.org/");
6449
6450 // In order for a new QUIC session to be established via alternate-protocol
6451 // without racing an HTTP connection, we need the host resolution to happen
6452 // synchronously.
6453 host_resolver_.set_synchronous_mode(true);
6454 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046455
6456 CreateSession();
David Schinazic8281052019-01-24 06:14:176457 crypto_client_stream_factory_.set_handshake_mode(
6458 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046459 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596460 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166461 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046462}
6463
bnc508835902015-05-12 20:10:296464TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586465 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386466 EXPECT_FALSE(
6467 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596468 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236469 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256470 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236471 mock_quic_data.AddWrite(SYNCHRONOUS,
6472 ConstructInitialSettingsPacket(packet_num++));
6473 }
rch5cb522462017-04-25 20:18:366474 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236475 SYNCHRONOUS,
6476 ConstructClientRequestHeadersPacket(
6477 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6478 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436479 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336480 ASYNC, ConstructServerResponseHeadersPacket(
6481 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6482 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436483 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336484 mock_quic_data.AddRead(
6485 ASYNC, ConstructServerDataPacket(
6486 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176487 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236488 mock_quic_data.AddWrite(SYNCHRONOUS,
6489 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506490 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296491 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6492
bncb07c05532015-05-14 19:07:206493 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096494 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326495 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276496 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296497 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386498 EXPECT_TRUE(
6499 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296500}
6501
zhongyi363c91c2017-03-23 23:16:086502// TODO(zhongyi): disabled this broken test as it was not testing the correct
6503// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6504TEST_P(QuicNetworkTransactionTest,
6505 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276506 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596507 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496508 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046509
6510 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046511
6512 test_proxy_delegate.set_alternative_proxy_server(
6513 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526514 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046515
6516 request_.url = GURL("http://mail.example.org/");
6517
6518 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6519 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016520 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046521 socket_factory_.AddSocketDataProvider(&socket_data);
6522
6523 // The non-alternate protocol job needs to hang in order to guarantee that
6524 // the alternate-protocol job will "win".
6525 AddHangingNonAlternateProtocolSocketData();
6526
6527 CreateSession();
6528 request_.method = "POST";
6529 ChunkedUploadDataStream upload_data(0);
6530 upload_data.AppendData("1", 1, true);
6531
6532 request_.upload_data_stream = &upload_data;
6533
6534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6535 TestCompletionCallback callback;
6536 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6538 EXPECT_NE(OK, callback.WaitForResult());
6539
6540 // Verify that the alternative proxy server is not marked as broken.
6541 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6542
6543 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596544 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276545
6546 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6547 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6548 1);
tbansalc3308d72016-08-27 10:25:046549}
6550
rtenneti56977812016-01-15 19:26:566551TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386552 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576553 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566554
Renjie Tangaadb84b2019-08-31 01:00:236555 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256556 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236557 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6558 else
6559 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6560 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6561 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6562
6563 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6564 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6565 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016566 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236567 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566568
rtennetib8e80fb2016-05-16 00:12:096569 // The non-alternate protocol job needs to hang in order to guarantee that
6570 // the alternate-protocol job will "win".
6571 AddHangingNonAlternateProtocolSocketData();
6572
rtenneti56977812016-01-15 19:26:566573 CreateSession();
6574 request_.method = "POST";
6575 ChunkedUploadDataStream upload_data(0);
6576 upload_data.AppendData("1", 1, true);
6577
6578 request_.upload_data_stream = &upload_data;
6579
bnc691fda62016-08-12 00:43:166580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566581 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166582 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566584 EXPECT_NE(OK, callback.WaitForResult());
6585}
6586
rche11300ef2016-09-02 01:44:286587TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386588 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286589 ScopedMockNetworkChangeNotifier network_change_notifier;
6590 MockNetworkChangeNotifier* mock_ncn =
6591 network_change_notifier.mock_network_change_notifier();
6592 mock_ncn->ForceNetworkHandlesSupported();
6593 mock_ncn->SetConnectedNetworksList(
6594 {kDefaultNetworkForTests, kNewNetworkForTests});
6595
Victor Vasilieva1e66d72019-12-05 17:55:386596 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286597 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386598 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286599
Ryan Hamiltonabad59e2019-06-06 04:02:596600 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286601 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236602 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256603 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236604 socket_data.AddWrite(SYNCHRONOUS,
6605 ConstructInitialSettingsPacket(packet_num++));
6606 }
Fan Yang32c5a112018-12-10 20:06:336607 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236608 SYNCHRONOUS,
6609 ConstructClientRequestHeadersPacket(
6610 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6611 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286612 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6613 socket_data.AddSocketDataToFactory(&socket_factory_);
6614
Ryan Hamiltonabad59e2019-06-06 04:02:596615 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286616 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6617 socket_data2.AddSocketDataToFactory(&socket_factory_);
6618
6619 // The non-alternate protocol job needs to hang in order to guarantee that
6620 // the alternate-protocol job will "win".
6621 AddHangingNonAlternateProtocolSocketData();
6622
6623 CreateSession();
6624 request_.method = "POST";
6625 ChunkedUploadDataStream upload_data(0);
6626
6627 request_.upload_data_stream = &upload_data;
6628
rdsmith1d343be52016-10-21 20:37:506629 std::unique_ptr<HttpNetworkTransaction> trans(
6630 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286631 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506632 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6634
6635 base::RunLoop().RunUntilIdle();
6636 upload_data.AppendData("1", 1, true);
6637 base::RunLoop().RunUntilIdle();
6638
6639 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506640 trans.reset();
rche11300ef2016-09-02 01:44:286641 session_.reset();
6642}
6643
Ryan Hamilton4b3574532017-10-30 20:17:256644TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386645 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256646 HostPortPair::FromString("mail.example.org:443"));
6647
Ryan Hamiltonabad59e2019-06-06 04:02:596648 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236649 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256650 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236651 socket_data.AddWrite(SYNCHRONOUS,
6652 ConstructInitialSettingsPacket(packet_num++));
6653 }
Ryan Hamilton4b3574532017-10-30 20:17:256654 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336655 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236656 SYNCHRONOUS,
6657 ConstructClientRequestHeadersPacket(
6658 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6659 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436660 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336661 ASYNC, ConstructServerResponseHeadersPacket(
6662 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6663 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436664 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336665 socket_data.AddRead(
6666 ASYNC, ConstructServerDataPacket(
6667 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176668 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236669 socket_data.AddWrite(SYNCHRONOUS,
6670 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256671 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436672 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6673 // TLS1.3 supports multiple packet number space, so the ack is no longer
6674 // sent.
6675 socket_data.AddWrite(
6676 SYNCHRONOUS,
6677 client_maker_.MakeConnectionClosePacket(
6678 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6679 } else {
6680 socket_data.AddWrite(
6681 SYNCHRONOUS,
6682 client_maker_.MakeAckAndConnectionClosePacket(
6683 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6684 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6685 }
Ryan Hamilton4b3574532017-10-30 20:17:256686
6687 socket_data.AddSocketDataToFactory(&socket_factory_);
6688
6689 CreateSession();
6690
6691 SendRequestAndExpectQuicResponse("hello!");
6692 session_.reset();
6693}
6694
6695TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386696 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256697 HostPortPair::FromString("mail.example.org:443"));
6698
Ryan Hamiltonabad59e2019-06-06 04:02:596699 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236700 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256701 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236702 socket_data.AddWrite(SYNCHRONOUS,
6703 ConstructInitialSettingsPacket(packet_num++));
6704 }
Ryan Hamilton4b3574532017-10-30 20:17:256705 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336706 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236707 SYNCHRONOUS,
6708 ConstructClientRequestHeadersPacket(
6709 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6710 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436711 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336712 ASYNC, ConstructServerResponseHeadersPacket(
6713 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6714 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436715 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336716 socket_data.AddRead(
6717 ASYNC, ConstructServerDataPacket(
6718 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176719 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236720 socket_data.AddWrite(SYNCHRONOUS,
6721 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256722 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436723 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6724 // TLS1.3 supports multiple packet number space, so the ack is no longer
6725 // sent.
6726 socket_data.AddWrite(
6727 SYNCHRONOUS,
6728 client_maker_.MakeConnectionClosePacket(
6729 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6730 } else {
6731 socket_data.AddWrite(
6732 SYNCHRONOUS,
6733 client_maker_.MakeAckAndConnectionClosePacket(
6734 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6735 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6736 }
Ryan Hamilton4b3574532017-10-30 20:17:256737
6738 socket_data.AddSocketDataToFactory(&socket_factory_);
6739
6740 CreateSession();
6741
6742 SendRequestAndExpectQuicResponse("hello!");
6743 session_.reset();
6744}
6745
Ryan Hamilton9edcf1a2017-11-22 05:55:176746TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386747 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6748 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256749 HostPortPair::FromString("mail.example.org:443"));
6750
Ryan Hamiltonabad59e2019-06-06 04:02:596751 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256752 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256753 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236754 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176755 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256756 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6757 }
6758 socket_data.AddSocketDataToFactory(&socket_factory_);
6759
6760 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176761 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176762 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6763 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256764
Victor Vasiliev7752898d2019-11-14 21:30:226765 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6767 TestCompletionCallback callback;
6768 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176770 while (!callback.have_result()) {
6771 base::RunLoop().RunUntilIdle();
6772 quic_task_runner_->RunUntilIdle();
6773 }
6774 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256775 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176776 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6777 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6778 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226779 EXPECT_TRUE(context_.clock()->Now() - start >
6780 quic::QuicTime::Delta::FromSeconds(4));
6781 EXPECT_TRUE(context_.clock()->Now() - start <
6782 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256783}
6784
Ryan Hamilton9edcf1a2017-11-22 05:55:176785TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386786 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6787 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256788 HostPortPair::FromString("mail.example.org:443"));
6789
Ryan Hamiltonabad59e2019-06-06 04:02:596790 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256791 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256792 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236793 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176794 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256795 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6796 }
6797 socket_data.AddSocketDataToFactory(&socket_factory_);
6798
6799 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176800 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176801 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6802 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256803
Victor Vasiliev7752898d2019-11-14 21:30:226804 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256805 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6806 TestCompletionCallback callback;
6807 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176809 while (!callback.have_result()) {
6810 base::RunLoop().RunUntilIdle();
6811 quic_task_runner_->RunUntilIdle();
6812 }
6813 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256814 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176815 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6816 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6817 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226818 EXPECT_TRUE(context_.clock()->Now() - start >
6819 quic::QuicTime::Delta::FromSeconds(4));
6820 EXPECT_TRUE(context_.clock()->Now() - start <
6821 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256822}
6823
Cherie Shi7596de632018-02-22 07:28:186824TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386825 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6826 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186827 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436828 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526829 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6830 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186831
Ryan Hamiltonabad59e2019-06-06 04:02:596832 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186833 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236834 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256835 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236836 socket_data.AddWrite(SYNCHRONOUS,
6837 ConstructInitialSettingsPacket(packet_num++));
6838 }
Cherie Shi7596de632018-02-22 07:28:186839 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6840 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526841 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236842 SYNCHRONOUS,
6843 client_maker_.MakeConnectionClosePacket(
6844 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186845 socket_data.AddSocketDataToFactory(&socket_factory_);
6846
6847 CreateSession();
6848
6849 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6850 TestCompletionCallback callback;
6851 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6852 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6853 base::RunLoop().RunUntilIdle();
6854 ASSERT_TRUE(callback.have_result());
6855 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6856 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6857 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6858}
6859
ckrasic769733c2016-06-30 00:42:136860// Adds coverage to catch regression such as https://crbug.com/622043
6861TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Ryan Hamilton6c6493102019-12-05 21:36:506862 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6863 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386864 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136865 HostPortPair::FromString("mail.example.org:443"));
6866
Ryan Hamiltonabad59e2019-06-06 04:02:596867 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236868 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256869 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236870 mock_quic_data.AddWrite(
6871 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6872 }
Zhongyi Shi32f2fd02018-04-16 18:23:436873 mock_quic_data.AddWrite(
6874 SYNCHRONOUS,
6875 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336876 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026877 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436878 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026879 ASYNC,
6880 ConstructServerPushPromisePacket(
6881 1, GetNthClientInitiatedBidirectionalStreamId(0),
6882 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6883 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316884 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426885 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256886 !VersionUsesHttp3(version_.transport_version)) ||
6887 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426888 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026889 mock_quic_data.AddWrite(
6890 SYNCHRONOUS,
6891 ConstructClientPriorityPacket(
6892 client_packet_number++, false,
6893 GetNthServerInitiatedUnidirectionalStreamId(0),
6894 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576895 }
Zhongyi Shi32f2fd02018-04-16 18:23:436896 mock_quic_data.AddRead(
6897 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336898 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026899 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576900 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436901 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6902 mock_quic_data.AddRead(
6903 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336904 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026905 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436906 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436907 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336908 ASYNC, ConstructServerDataPacket(
6909 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176910 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576911 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436912 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436913 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436914 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336915 ASYNC, ConstructServerDataPacket(
6916 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176917 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336918 mock_quic_data.AddWrite(SYNCHRONOUS,
6919 ConstructClientAckAndRstPacket(
6920 client_packet_number++,
6921 GetNthServerInitiatedUnidirectionalStreamId(0),
6922 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136923 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6924 mock_quic_data.AddRead(ASYNC, 0); // EOF
6925 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6926
6927 // The non-alternate protocol job needs to hang in order to guarantee that
6928 // the alternate-protocol job will "win".
6929 AddHangingNonAlternateProtocolSocketData();
6930
6931 CreateSession();
6932
6933 // PUSH_PROMISE handling in the http layer gets exercised here.
6934 SendRequestAndExpectQuicResponse("hello!");
6935
6936 request_.url = GURL("https://mail.example.org/pushed.jpg");
6937 SendRequestAndExpectQuicResponse("and hello!");
6938
6939 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546940 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136941 EXPECT_LT(0u, entries.size());
6942
6943 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6944 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006945 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6946 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136947 EXPECT_LT(0, pos);
6948}
6949
rch56ec40a2017-06-23 14:48:446950// Regression test for http://crbug.com/719461 in which a promised stream
6951// is closed before the pushed headers arrive, but after the connection
6952// is closed and before the callbacks are executed.
6953TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamilton6c6493102019-12-05 21:36:506954 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6955 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386956 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6957 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446958 HostPortPair::FromString("mail.example.org:443"));
6959
Ryan Hamiltonabad59e2019-06-06 04:02:596960 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236961 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446962 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256963 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236964 mock_quic_data.AddWrite(
6965 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6966 }
rch56ec40a2017-06-23 14:48:446967 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436968 mock_quic_data.AddWrite(
6969 SYNCHRONOUS,
6970 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336971 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026972 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446973 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436974 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026975 ASYNC,
6976 ConstructServerPushPromisePacket(
6977 1, GetNthClientInitiatedBidirectionalStreamId(0),
6978 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6979 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316980 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426981 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256982 !VersionUsesHttp3(version_.transport_version)) ||
6983 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426984 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026985 mock_quic_data.AddWrite(
6986 SYNCHRONOUS,
6987 ConstructClientPriorityPacket(
6988 client_packet_number++, false,
6989 GetNthServerInitiatedUnidirectionalStreamId(0),
6990 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576991 }
rch56ec40a2017-06-23 14:48:446992 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436993 mock_quic_data.AddRead(
6994 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336995 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026996 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:446997 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576998 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436999 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:447000 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:437001 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437002 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337003 ASYNC, ConstructServerDataPacket(
7004 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177005 header + "hello!"));
rch56ec40a2017-06-23 14:48:447006 // Write error for the third request.
7007 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
7008 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7009 mock_quic_data.AddRead(ASYNC, 0); // EOF
7010 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7011
7012 CreateSession();
7013
7014 // Send a request which triggers a push promise from the server.
7015 SendRequestAndExpectQuicResponse("hello!");
7016
7017 // Start a push transaction that will be cancelled after the connection
7018 // is closed, but before the callback is executed.
7019 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:197020 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:447021 session_.get());
7022 TestCompletionCallback callback2;
7023 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
7024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7025 base::RunLoop().RunUntilIdle();
7026
7027 // Cause the connection to close on a write error.
7028 HttpRequestInfo request3;
7029 request3.method = "GET";
7030 request3.url = GURL("https://mail.example.org/");
7031 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107032 request3.traffic_annotation =
7033 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:447034 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
7035 TestCompletionCallback callback3;
7036 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
7037 IsError(ERR_IO_PENDING));
7038
7039 base::RunLoop().RunUntilIdle();
7040
7041 // When |trans2| is destroyed, the underlying stream will be closed.
7042 EXPECT_FALSE(callback2.have_result());
7043 trans2 = nullptr;
7044
7045 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
7046}
7047
ckrasicda193a82016-07-09 00:39:367048TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:387049 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:367050 HostPortPair::FromString("mail.example.org:443"));
7051
Ryan Hamiltonabad59e2019-06-06 04:02:597052 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:367053
Renjief49758b2019-01-11 23:32:417054 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257055 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237056 mock_quic_data.AddWrite(
7057 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7058 }
ckrasicda193a82016-07-09 00:39:367059
Victor Vasiliev076657c2019-03-12 02:46:437060 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567061 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417062 mock_quic_data.AddWrite(
7063 SYNCHRONOUS,
7064 ConstructClientRequestHeadersAndDataFramesPacket(
7065 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7066 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027067 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:417068 } else {
7069 mock_quic_data.AddWrite(
7070 SYNCHRONOUS,
7071 ConstructClientRequestHeadersAndDataFramesPacket(
7072 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7073 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027074 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:417075 {header, "1"}));
7076 }
ckrasicda193a82016-07-09 00:39:367077
Zhongyi Shi32f2fd02018-04-16 18:23:437078 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337079 ASYNC, ConstructServerResponseHeadersPacket(
7080 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7081 GetResponseHeaders("200 OK")));
7082
Victor Vasiliev076657c2019-03-12 02:46:437083 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337084 mock_quic_data.AddRead(
7085 ASYNC, ConstructServerDataPacket(
7086 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177087 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:367088
Renjief49758b2019-01-11 23:32:417089 mock_quic_data.AddWrite(
7090 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:367091
7092 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7093 mock_quic_data.AddRead(ASYNC, 0); // EOF
7094 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7095
7096 // The non-alternate protocol job needs to hang in order to guarantee that
7097 // the alternate-protocol job will "win".
7098 AddHangingNonAlternateProtocolSocketData();
7099
7100 CreateSession();
7101 request_.method = "POST";
7102 ChunkedUploadDataStream upload_data(0);
7103 upload_data.AppendData("1", 1, true);
7104
7105 request_.upload_data_stream = &upload_data;
7106
7107 SendRequestAndExpectQuicResponse("hello!");
7108}
7109
allada71b2efb2016-09-09 04:57:487110class QuicURLRequestContext : public URLRequestContext {
7111 public:
7112 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
7113 MockClientSocketFactory* socket_factory)
7114 : storage_(this) {
7115 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:077116 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:047117 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:487118 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:047119 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:597120 storage_.set_proxy_resolution_service(
7121 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:077122 storage_.set_ssl_config_service(
7123 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:487124 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:117125 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:487126 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:267127 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:047128 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:487129 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:047130 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
7131 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
7132 false));
allada71b2efb2016-09-09 04:57:487133 }
7134
7135 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
7136
7137 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
7138
7139 private:
7140 MockClientSocketFactory* socket_factory_;
7141 URLRequestContextStorage storage_;
7142};
7143
7144TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Victor Vasilieva1e66d72019-12-05 17:55:387145 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487146 HostPortPair::FromString("mail.example.org:443"));
7147
Ryan Hamiltonabad59e2019-06-06 04:02:597148 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237149 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257150 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237151 mock_quic_data.AddWrite(SYNCHRONOUS,
7152 ConstructInitialSettingsPacket(packet_num++));
7153 }
Ryan Hamilton0239aac2018-05-19 00:03:137154 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487155 headers["user-agent"] = "";
7156 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:337157 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237158 SYNCHRONOUS,
7159 ConstructClientRequestHeadersPacket(
7160 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7161 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487162
Fan Yang32c5a112018-12-10 20:06:337163 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027164 ASYNC, ConstructServerResponseHeadersPacket(
7165 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7166 GetResponseHeaders("200 OK")));
7167 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457168 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257169 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457170 ? GetNthClientInitiatedBidirectionalStreamId(0)
7171 : quic::QuicUtils::GetHeadersStreamId(
7172 version_.transport_version));
allada71b2efb2016-09-09 04:57:487173
Victor Vasiliev076657c2019-03-12 02:46:437174 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367175 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337176 ASYNC, ConstructServerDataPacket(
7177 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177178 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:237179 mock_quic_data.AddWrite(SYNCHRONOUS,
7180 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487181
7182 mock_quic_data.AddRead(ASYNC, 0); // EOF
7183
7184 CreateSession();
7185
7186 TestDelegate delegate;
7187 QuicURLRequestContext quic_url_request_context(std::move(session_),
7188 &socket_factory_);
7189
7190 mock_quic_data.AddSocketDataToFactory(
7191 &quic_url_request_context.socket_factory());
7192 TestNetworkDelegate network_delegate;
7193 quic_url_request_context.set_network_delegate(&network_delegate);
7194
7195 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297196 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7197 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487198 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7199 &ssl_data_);
7200
7201 request->Start();
Wez2a31b222018-06-07 22:07:157202 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487203
7204 EXPECT_LT(0, request->GetTotalSentBytes());
7205 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:487206 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
7207 request->raw_header_size());
Wez0e717112018-06-18 23:09:227208
7209 // Pump the message loop to allow all data to be consumed.
7210 base::RunLoop().RunUntilIdle();
7211
allada71b2efb2016-09-09 04:57:487212 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7213 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7214}
7215
7216TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Ryan Hamilton6c6493102019-12-05 21:36:507217 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7218 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387219 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487220 HostPortPair::FromString("mail.example.org:443"));
7221
Ryan Hamiltonabad59e2019-06-06 04:02:597222 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237223 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257224 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237225 mock_quic_data.AddWrite(
7226 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7227 }
Ryan Hamilton0239aac2018-05-19 00:03:137228 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487229 headers["user-agent"] = "";
7230 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:437231 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337232 SYNCHRONOUS,
7233 ConstructClientRequestHeadersPacket(
7234 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027235 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487236
Fan Yang2330d182019-08-05 14:50:507237 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
7238 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:437239 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027240 ASYNC,
7241 ConstructServerPushPromisePacket(
7242 1, GetNthClientInitiatedBidirectionalStreamId(0),
7243 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7244 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:507245 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:257246 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:507247 push_promise_offset = server_maker_.stream_offset(
7248 GetNthClientInitiatedBidirectionalStreamId(0)) -
7249 initial;
7250 }
allada71b2efb2016-09-09 04:57:487251
Renjie Tang703fea92019-07-23 21:08:317252 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427253 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:257254 !VersionUsesHttp3(version_.transport_version)) ||
7255 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:427256 (FLAGS_quic_allow_http3_priority))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027257 mock_quic_data.AddWrite(
7258 SYNCHRONOUS,
7259 ConstructClientPriorityPacket(
7260 client_packet_number++, false,
7261 GetNthServerInitiatedUnidirectionalStreamId(0),
7262 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577263 }
7264
Ryan Hamiltone940bd12019-06-30 02:46:457265 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257266 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457267 ? GetNthClientInitiatedBidirectionalStreamId(0)
7268 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:437269 mock_quic_data.AddRead(
7270 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337271 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027272 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:457273 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257274 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457275 ? GetNthClientInitiatedBidirectionalStreamId(0)
7276 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:027277 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457278 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:487279
Yixin Wangb470bc882018-02-15 18:43:577280 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437281 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487282
ckrasicbf2f59c2017-05-04 23:54:367283 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437284 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337285 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027286 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437287 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:437288 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337289 ASYNC, ConstructServerDataPacket(
7290 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177291 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:487292
Yixin Wangb470bc882018-02-15 18:43:577293 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437294 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:437295 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367296 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337297 ASYNC, ConstructServerDataPacket(
7298 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177299 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:487300
Zhongyi Shi32f2fd02018-04-16 18:23:437301 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:487302
7303 CreateSession();
7304
7305 TestDelegate delegate;
7306 QuicURLRequestContext quic_url_request_context(std::move(session_),
7307 &socket_factory_);
7308
7309 mock_quic_data.AddSocketDataToFactory(
7310 &quic_url_request_context.socket_factory());
7311 TestNetworkDelegate network_delegate;
7312 quic_url_request_context.set_network_delegate(&network_delegate);
7313
7314 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297315 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7316 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487317 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7318 &ssl_data_);
7319
7320 request->Start();
Wez2a31b222018-06-07 22:07:157321 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487322
7323 EXPECT_LT(0, request->GetTotalSentBytes());
7324 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:507325 EXPECT_EQ(
7326 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
7327 request->raw_header_size());
Wez0e717112018-06-18 23:09:227328
7329 // Pump the message loop to allow all data to be consumed.
7330 base::RunLoop().RunUntilIdle();
7331
allada71b2efb2016-09-09 04:57:487332 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7333 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7334}
7335
Ryan Sleevia9d6aa62019-07-26 13:32:187336TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
7337 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:207338
7339 MockRead http_reads[] = {
7340 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7341 MockRead("hello world"),
7342 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7343 MockRead(ASYNC, OK)};
7344
Ryan Sleevib8d7ea02018-05-07 20:01:017345 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207346 socket_factory_.AddSocketDataProvider(&http_data);
7347 AddCertificate(&ssl_data_);
7348 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7349
Ryan Hamiltonabad59e2019-06-06 04:02:597350 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237351 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257352 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237353 mock_quic_data.AddWrite(SYNCHRONOUS,
7354 ConstructInitialSettingsPacket(packet_num++));
7355 }
Yixin Wang10f477ed2017-11-21 04:20:207356 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237357 SYNCHRONOUS,
7358 ConstructClientRequestHeadersPacket(
7359 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7360 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437361 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337362 ASYNC, ConstructServerResponseHeadersPacket(
7363 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7364 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437365 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337366 mock_quic_data.AddRead(
7367 ASYNC, ConstructServerDataPacket(
7368 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177369 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237370 mock_quic_data.AddWrite(SYNCHRONOUS,
7371 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207372 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7373 mock_quic_data.AddRead(ASYNC, 0); // EOF
7374
7375 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7376
7377 AddHangingNonAlternateProtocolSocketData();
7378 CreateSession();
7379
7380 SendRequestAndExpectHttpResponse("hello world");
7381 SendRequestAndExpectQuicResponse("hello!");
7382}
7383
Ryan Sleevia9d6aa62019-07-26 13:32:187384TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7385 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207386
7387 MockRead http_reads[] = {
7388 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7389 MockRead("hello world"),
7390 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7391 MockRead(ASYNC, OK)};
7392
Ryan Sleevib8d7ea02018-05-07 20:01:017393 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207394 socket_factory_.AddSocketDataProvider(&http_data);
7395 AddCertificate(&ssl_data_);
7396 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7397 socket_factory_.AddSocketDataProvider(&http_data);
7398 AddCertificate(&ssl_data_);
7399 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7400
7401 AddHangingNonAlternateProtocolSocketData();
7402 CreateSession();
7403
7404 SendRequestAndExpectHttpResponse("hello world");
7405 SendRequestAndExpectHttpResponse("hello world");
7406}
7407
bnc359ed2a2016-04-29 20:43:457408class QuicNetworkTransactionWithDestinationTest
7409 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017410 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057411 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457412 protected:
7413 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557414 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057415 client_headers_include_h2_stream_dependency_(
7416 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567417 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457418 destination_type_(GetParam().destination_type),
7419 cert_transparency_verifier_(new MultiLogCTVerifier()),
7420 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:597421 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117422 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:457423 ssl_data_(ASYNC, OK) {}
7424
7425 void SetUp() override {
7426 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557427 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457428
mmenke6ddfbea2017-05-31 21:48:417429 HttpNetworkSession::Params session_params;
7430 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387431 context_.params()->allow_remote_alt_svc = true;
7432 context_.params()->supported_versions = supported_versions_;
7433 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057434 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417435
7436 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457437
Victor Vasiliev7752898d2019-11-14 21:30:227438 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457439
7440 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277441 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417442 session_context.quic_crypto_client_stream_factory =
7443 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457444
Victor Vasiliev7752898d2019-11-14 21:30:227445 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417446 session_context.client_socket_factory = &socket_factory_;
7447 session_context.host_resolver = &host_resolver_;
7448 session_context.cert_verifier = &cert_verifier_;
7449 session_context.transport_security_state = &transport_security_state_;
7450 session_context.cert_transparency_verifier =
7451 cert_transparency_verifier_.get();
7452 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7453 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457454 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417455 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597456 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417457 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7458 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457459
mmenke6ddfbea2017-05-31 21:48:417460 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437461 session_->quic_stream_factory()
7462 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457463 }
7464
7465 void TearDown() override {
7466 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7467 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557468 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457469 PlatformTest::TearDown();
7470 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557471 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407472 session_.reset();
bnc359ed2a2016-04-29 20:43:457473 }
7474
zhongyie537a002017-06-27 16:48:217475 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457476 HostPortPair destination;
7477 switch (destination_type_) {
7478 case SAME_AS_FIRST:
7479 destination = HostPortPair(origin1_, 443);
7480 break;
7481 case SAME_AS_SECOND:
7482 destination = HostPortPair(origin2_, 443);
7483 break;
7484 case DIFFERENT:
7485 destination = HostPortPair(kDifferentHostname, 443);
7486 break;
7487 }
bnc3472afd2016-11-17 15:27:217488 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457489 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217490 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077491 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7492 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457493 }
7494
Ryan Hamilton8d9ee76e2018-05-29 23:52:527495 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237496 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527497 quic::QuicStreamId stream_id,
7498 bool should_include_version,
7499 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527500 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137501 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457502 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137503 spdy::SpdyHeaderBlock headers(
7504 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027505 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457506 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027507 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457508 }
7509
Ryan Hamilton8d9ee76e2018-05-29 23:52:527510 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237511 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527512 quic::QuicStreamId stream_id,
7513 bool should_include_version,
7514 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587515 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027516 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457517 }
7518
Ryan Hamilton8d9ee76e2018-05-29 23:52:527519 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237520 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527521 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527522 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137523 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027524 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7525 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457526 }
7527
Ryan Hamilton8d9ee76e2018-05-29 23:52:527528 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237529 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527530 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457531 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437532 std::string header = "";
Nick Harper23290b82019-05-02 00:02:567533 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417534 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:577535 auto header_length =
7536 quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437537 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417538 }
Ryan Hamilton7505eb92019-06-08 00:22:177539 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417540 header + "hello");
bnc359ed2a2016-04-29 20:43:457541 }
7542
Ryan Hamilton8d9ee76e2018-05-29 23:52:527543 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237544 uint64_t packet_number,
7545 uint64_t largest_received,
7546 uint64_t smallest_received,
7547 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457548 QuicTestPacketMaker* maker) {
7549 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497550 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457551 }
7552
Ryan Hamilton8d9ee76e2018-05-29 23:52:527553 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237554 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377555 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027556 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377557 }
7558
bnc359ed2a2016-04-29 20:43:457559 void AddRefusedSocketData() {
7560 std::unique_ptr<StaticSocketDataProvider> refused_data(
7561 new StaticSocketDataProvider());
7562 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7563 refused_data->set_connect_data(refused_connect);
7564 socket_factory_.AddSocketDataProvider(refused_data.get());
7565 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7566 }
7567
7568 void AddHangingSocketData() {
7569 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7570 new StaticSocketDataProvider());
7571 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7572 hanging_data->set_connect_data(hanging_connect);
7573 socket_factory_.AddSocketDataProvider(hanging_data.get());
7574 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7575 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7576 }
7577
7578 bool AllDataConsumed() {
7579 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7580 if (!socket_data_ptr->AllReadDataConsumed() ||
7581 !socket_data_ptr->AllWriteDataConsumed()) {
7582 return false;
7583 }
7584 }
7585 return true;
7586 }
7587
7588 void SendRequestAndExpectQuicResponse(const std::string& host) {
7589 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7590 HttpRequestInfo request;
7591 std::string url("https://");
7592 url.append(host);
7593 request.url = GURL(url);
7594 request.load_flags = 0;
7595 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107596 request.traffic_annotation =
7597 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457598 TestCompletionCallback callback;
7599 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017600 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457601
7602 std::string response_data;
robpercival214763f2016-07-01 23:27:017603 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457604 EXPECT_EQ("hello", response_data);
7605
7606 const HttpResponseInfo* response = trans.GetResponseInfo();
7607 ASSERT_TRUE(response != nullptr);
7608 ASSERT_TRUE(response->headers.get() != nullptr);
7609 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7610 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527611 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087612 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457613 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377614 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457615 }
7616
Fan Yang32c5a112018-12-10 20:06:337617 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567618 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7619 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367620 }
7621
Nick Harper23290b82019-05-02 00:02:567622 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057623 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567624 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457625 DestinationType destination_type_;
7626 std::string origin1_;
7627 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227628 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457629 std::unique_ptr<HttpNetworkSession> session_;
7630 MockClientSocketFactory socket_factory_;
7631 MockHostResolver host_resolver_;
7632 MockCertVerifier cert_verifier_;
7633 TransportSecurityState transport_security_state_;
7634 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237635 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457636 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077637 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597638 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457639 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267640 HttpServerProperties http_server_properties_;
Matt Muellerd9342e3a2019-11-26 01:41:147641 RecordingBoundTestNetLog net_log_;
bnc359ed2a2016-04-29 20:43:457642 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7643 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7644 static_socket_data_provider_vector_;
7645 SSLSocketDataProvider ssl_data_;
7646};
7647
Victor Costane635086f2019-01-27 05:20:307648INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7649 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577650 ::testing::ValuesIn(GetPoolingTestParams()),
7651 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457652
7653// A single QUIC request fails because the certificate does not match the origin
7654// hostname, regardless of whether it matches the alternative service hostname.
7655TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7656 if (destination_type_ == DIFFERENT)
7657 return;
7658
7659 GURL url("https://mail.example.com/");
7660 origin1_ = url.host();
7661
7662 // Not used for requests, but this provides a test case where the certificate
7663 // is valid for the hostname of the alternative service.
7664 origin2_ = "mail.example.org";
7665
zhongyie537a002017-06-27 16:48:217666 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457667
7668 scoped_refptr<X509Certificate> cert(
7669 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247670 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7671 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457672
7673 ProofVerifyDetailsChromium verify_details;
7674 verify_details.cert_verify_result.verified_cert = cert;
7675 verify_details.cert_verify_result.is_issued_by_known_root = true;
7676 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7677
Ryan Hamiltonabad59e2019-06-06 04:02:597678 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457679 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7680 mock_quic_data.AddRead(ASYNC, 0);
7681
7682 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7683
7684 AddRefusedSocketData();
7685
7686 HttpRequestInfo request;
7687 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107688 request.traffic_annotation =
7689 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457690
7691 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7692 TestCompletionCallback callback;
7693 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017694 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457695
7696 EXPECT_TRUE(AllDataConsumed());
7697}
7698
7699// First request opens QUIC session to alternative service. Second request
7700// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527701// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457702TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7703 origin1_ = "mail.example.org";
7704 origin2_ = "news.example.org";
7705
zhongyie537a002017-06-27 16:48:217706 SetQuicAlternativeService(origin1_);
7707 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457708
7709 scoped_refptr<X509Certificate> cert(
7710 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247711 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7712 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7713 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457714
7715 ProofVerifyDetailsChromium verify_details;
7716 verify_details.cert_verify_result.verified_cert = cert;
7717 verify_details.cert_verify_result.is_issued_by_known_root = true;
7718 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7719
Yixin Wang079ad542018-01-11 04:06:057720 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227721 version_,
7722 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7723 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057724 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177725 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227726 version_,
7727 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7728 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457729
Ryan Hamiltonabad59e2019-06-06 04:02:597730 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237731 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257732 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237733 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7734 packet_num++, &client_maker));
7735 }
Fan Yang32c5a112018-12-10 20:06:337736 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237737 SYNCHRONOUS,
7738 ConstructClientRequestHeadersPacket(
7739 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7740 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027741 mock_quic_data.AddRead(
7742 ASYNC,
7743 ConstructServerResponseHeadersPacket(
7744 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437745 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337746 ASYNC,
7747 ConstructServerDataPacket(
7748 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237749 mock_quic_data.AddWrite(
7750 SYNCHRONOUS,
7751 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457752
Yixin Wang079ad542018-01-11 04:06:057753 client_maker.set_hostname(origin2_);
7754 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457755
Zhongyi Shi32f2fd02018-04-16 18:23:437756 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027757 SYNCHRONOUS,
7758 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237759 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027760 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7761 mock_quic_data.AddRead(
7762 ASYNC,
7763 ConstructServerResponseHeadersPacket(
7764 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437765 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337766 ASYNC,
7767 ConstructServerDataPacket(
7768 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237769 mock_quic_data.AddWrite(
7770 SYNCHRONOUS,
7771 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457772 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7773 mock_quic_data.AddRead(ASYNC, 0); // EOF
7774
7775 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7776
7777 AddHangingSocketData();
7778 AddHangingSocketData();
7779
Victor Vasiliev7752898d2019-11-14 21:30:227780 scoped_refptr<TestTaskRunner> quic_task_runner(
7781 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567782 QuicStreamFactoryPeer::SetAlarmFactory(
7783 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097784 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227785 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567786
bnc359ed2a2016-04-29 20:43:457787 SendRequestAndExpectQuicResponse(origin1_);
7788 SendRequestAndExpectQuicResponse(origin2_);
7789
7790 EXPECT_TRUE(AllDataConsumed());
7791}
7792
7793// First request opens QUIC session to alternative service. Second request does
7794// not pool to it, even though destination matches, because certificate is not
7795// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527796// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457797TEST_P(QuicNetworkTransactionWithDestinationTest,
7798 DoNotPoolIfCertificateInvalid) {
7799 origin1_ = "news.example.org";
7800 origin2_ = "mail.example.com";
7801
zhongyie537a002017-06-27 16:48:217802 SetQuicAlternativeService(origin1_);
7803 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457804
7805 scoped_refptr<X509Certificate> cert1(
7806 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247807 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7808 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7809 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457810
7811 scoped_refptr<X509Certificate> cert2(
7812 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247813 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7814 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457815
7816 ProofVerifyDetailsChromium verify_details1;
7817 verify_details1.cert_verify_result.verified_cert = cert1;
7818 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7819 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7820
7821 ProofVerifyDetailsChromium verify_details2;
7822 verify_details2.cert_verify_result.verified_cert = cert2;
7823 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7824 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7825
Yixin Wang079ad542018-01-11 04:06:057826 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227827 version_,
7828 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7829 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057830 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177831 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227832 version_,
7833 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7834 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457835
Ryan Hamiltonabad59e2019-06-06 04:02:597836 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237837 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257838 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237839 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7840 packet_num++, &client_maker1));
7841 }
Fan Yang32c5a112018-12-10 20:06:337842 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237843 SYNCHRONOUS,
7844 ConstructClientRequestHeadersPacket(
7845 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7846 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437847 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337848 ASYNC,
7849 ConstructServerResponseHeadersPacket(
7850 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437851 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337852 ASYNC,
7853 ConstructServerDataPacket(
7854 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437855 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237856 SYNCHRONOUS,
7857 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457858 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7859 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7860
7861 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7862
Yixin Wang079ad542018-01-11 04:06:057863 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227864 version_,
7865 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7866 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057867 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177868 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227869 version_,
7870 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7871 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457872
Ryan Hamiltonabad59e2019-06-06 04:02:597873 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237874 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257875 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237876 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7877 packet_num2++, &client_maker2));
7878 }
Fan Yang32c5a112018-12-10 20:06:337879 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237880 SYNCHRONOUS,
7881 ConstructClientRequestHeadersPacket(
7882 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7883 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437884 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337885 ASYNC,
7886 ConstructServerResponseHeadersPacket(
7887 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437888 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337889 ASYNC,
7890 ConstructServerDataPacket(
7891 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437892 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237893 SYNCHRONOUS,
7894 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457895 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7896 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7897
7898 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7899
bnc359ed2a2016-04-29 20:43:457900 SendRequestAndExpectQuicResponse(origin1_);
7901 SendRequestAndExpectQuicResponse(origin2_);
7902
7903 EXPECT_TRUE(AllDataConsumed());
7904}
7905
ckrasicdee37572017-04-06 22:42:277906// crbug.com/705109 - this confirms that matching request with a body
7907// triggers a crash (pre-fix).
7908TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Ryan Hamilton6c6493102019-12-05 21:36:507909 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7910 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387911 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277912 HostPortPair::FromString("mail.example.org:443"));
7913
Ryan Hamiltonabad59e2019-06-06 04:02:597914 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237915 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257916 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237917 mock_quic_data.AddWrite(
7918 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7919 }
Zhongyi Shi32f2fd02018-04-16 18:23:437920 mock_quic_data.AddWrite(
7921 SYNCHRONOUS,
7922 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337923 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027924 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437925 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027926 ASYNC,
7927 ConstructServerPushPromisePacket(
7928 1, GetNthClientInitiatedBidirectionalStreamId(0),
7929 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7930 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317931
7932 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427933 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:257934 !VersionUsesHttp3(version_.transport_version)) ||
7935 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:427936 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027937 mock_quic_data.AddWrite(
7938 SYNCHRONOUS,
7939 ConstructClientPriorityPacket(
7940 client_packet_number++, false,
7941 GetNthServerInitiatedUnidirectionalStreamId(0),
7942 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577943 }
Zhongyi Shi32f2fd02018-04-16 18:23:437944 mock_quic_data.AddRead(
7945 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337946 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027947 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577948 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437949 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7950 mock_quic_data.AddRead(
7951 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337952 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027953 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437954 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437955 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337956 ASYNC, ConstructServerDataPacket(
7957 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177958 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577959 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437960 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417961
Victor Vasiliev076657c2019-03-12 02:46:437962 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437963 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337964 ASYNC, ConstructServerDataPacket(
7965 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177966 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277967
7968 // Because the matching request has a body, we will see the push
7969 // stream get cancelled, and the matching request go out on the
7970 // wire.
Fan Yang32c5a112018-12-10 20:06:337971 mock_quic_data.AddWrite(SYNCHRONOUS,
7972 ConstructClientAckAndRstPacket(
7973 client_packet_number++,
7974 GetNthServerInitiatedUnidirectionalStreamId(0),
7975 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277976 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437977 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567978 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417979 mock_quic_data.AddWrite(
7980 SYNCHRONOUS,
7981 ConstructClientRequestHeadersAndDataFramesPacket(
7982 client_packet_number++,
7983 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7984 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027985 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417986 } else {
7987 mock_quic_data.AddWrite(
7988 SYNCHRONOUS,
7989 ConstructClientRequestHeadersAndDataFramesPacket(
7990 client_packet_number++,
7991 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7992 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027993 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7994 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417995 }
ckrasicdee37572017-04-06 22:42:277996
7997 // We see the same response as for the earlier pushed and cancelled
7998 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437999 mock_quic_data.AddRead(
8000 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338001 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028002 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:438003 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338004 ASYNC, ConstructServerDataPacket(
8005 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:178006 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:278007
Yixin Wangb470bc882018-02-15 18:43:578008 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438009 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:278010 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8011 mock_quic_data.AddRead(ASYNC, 0); // EOF
8012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8013
8014 // The non-alternate protocol job needs to hang in order to guarantee that
8015 // the alternate-protocol job will "win".
8016 AddHangingNonAlternateProtocolSocketData();
8017
8018 CreateSession();
8019
8020 // PUSH_PROMISE handling in the http layer gets exercised here.
8021 SendRequestAndExpectQuicResponse("hello!");
8022
8023 request_.url = GURL("https://mail.example.org/pushed.jpg");
8024 ChunkedUploadDataStream upload_data(0);
8025 upload_data.AppendData("1", 1, true);
8026 request_.upload_data_stream = &upload_data;
8027 SendRequestAndExpectQuicResponse("and hello!");
8028}
8029
Bence Béky7538a952018-02-01 16:59:528030// Regression test for https://crbug.com/797825: If pushed headers describe a
8031// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
8032// not be called (otherwise a DCHECK fails).
8033TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton6c6493102019-12-05 21:36:508034 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
8035 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
8036
Ryan Hamilton0239aac2018-05-19 00:03:138037 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:528038 pushed_request_headers[":authority"] = "";
8039 pushed_request_headers[":method"] = "GET";
8040 pushed_request_headers[":path"] = "/";
8041 pushed_request_headers[":scheme"] = "nosuchscheme";
8042
Victor Vasilieva1e66d72019-12-05 17:55:388043 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:528044 HostPortPair::FromString("mail.example.org:443"));
8045
Ryan Hamiltonabad59e2019-06-06 04:02:598046 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:528047
Renjie Tangaadb84b2019-08-31 01:00:238048 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258049 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238050 mock_quic_data.AddWrite(SYNCHRONOUS,
8051 ConstructInitialSettingsPacket(packet_num++));
8052 }
Bence Béky7538a952018-02-01 16:59:528053 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238054 SYNCHRONOUS,
8055 ConstructClientRequestHeadersPacket(
8056 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8057 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:528058
Fan Yang32c5a112018-12-10 20:06:338059 mock_quic_data.AddRead(
8060 ASYNC, ConstructServerPushPromisePacket(
8061 1, GetNthClientInitiatedBidirectionalStreamId(0),
8062 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028063 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:238064 mock_quic_data.AddWrite(
8065 SYNCHRONOUS,
8066 ConstructClientRstPacket(packet_num++,
8067 GetNthServerInitiatedUnidirectionalStreamId(0),
8068 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:528069
Zhongyi Shi32f2fd02018-04-16 18:23:438070 mock_quic_data.AddRead(
8071 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338072 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028073 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238074 mock_quic_data.AddWrite(SYNCHRONOUS,
8075 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:528076
Zhongyi Shi32f2fd02018-04-16 18:23:438077 mock_quic_data.AddRead(
8078 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338079 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028080 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:438081 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:438082 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338083 ASYNC, ConstructServerDataPacket(
8084 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:178085 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:238086 mock_quic_data.AddWrite(SYNCHRONOUS,
8087 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:528088
8089 mock_quic_data.AddRead(ASYNC, 0);
8090 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8091
8092 // The non-alternate protocol job needs to hang in order to guarantee that
8093 // the alternate-protocol job will "win".
8094 AddHangingNonAlternateProtocolSocketData();
8095
8096 CreateSession();
8097
8098 // PUSH_PROMISE handling in the http layer gets exercised here.
8099 SendRequestAndExpectQuicResponse("hello!");
8100
8101 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8102 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8103}
8104
Yixin Wang46a273ec302018-01-23 17:59:568105// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148106TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:568107 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148108 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568109 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498110 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568111
Ryan Hamiltonabad59e2019-06-06 04:02:598112 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238113 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258114 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238115 mock_quic_data.AddWrite(SYNCHRONOUS,
8116 ConstructInitialSettingsPacket(packet_num++));
8117 }
Fan Yang32c5a112018-12-10 20:06:338118 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238119 SYNCHRONOUS,
8120 ConstructClientRequestHeadersPacket(
8121 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8122 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8123 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338124 mock_quic_data.AddRead(
8125 ASYNC, ConstructServerResponseHeadersPacket(
8126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8127 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568128
8129 const char get_request[] =
8130 "GET / HTTP/1.1\r\n"
8131 "Host: mail.example.org\r\n"
8132 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438133 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568134 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418135 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358136 SYNCHRONOUS,
8137 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238138 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8139 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418140 } else {
8141 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418142 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288143 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238144 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288145 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418146 }
8147
Yixin Wang46a273ec302018-01-23 17:59:568148 const char get_response[] =
8149 "HTTP/1.1 200 OK\r\n"
8150 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438151 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438152 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338153 ASYNC, ConstructServerDataPacket(
8154 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178155 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438156 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338157 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418158 SYNCHRONOUS, ConstructServerDataPacket(
8159 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178160 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238161 mock_quic_data.AddWrite(SYNCHRONOUS,
8162 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568163 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8164
Bence Béky6e243aa2019-12-13 19:01:078165 if (VersionUsesHttp3(version_.transport_version)) {
8166 mock_quic_data.AddWrite(
8167 SYNCHRONOUS, ConstructClientDataPacket(
8168 packet_num++, GetQpackDecoderStreamId(), true, false,
8169 StreamCancellationQpackDecoderInstruction(0)));
8170 }
8171
Yixin Wang46a273ec302018-01-23 17:59:568172 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418173 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238174 ConstructClientRstPacket(packet_num++,
8175 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418176 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568177
8178 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8179
8180 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8181
8182 CreateSession();
8183
8184 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:098185 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:568186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8187 HeadersHandler headers_handler;
8188 trans.SetBeforeHeadersSentCallback(
8189 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8190 base::Unretained(&headers_handler)));
8191 RunTransaction(&trans);
8192 CheckWasHttpResponse(&trans);
8193 CheckResponsePort(&trans, 70);
8194 CheckResponseData(&trans, "0123456789");
8195 EXPECT_TRUE(headers_handler.was_proxied());
8196 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8197
8198 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8199 // proxy socket to disconnect.
8200 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8201
8202 base::RunLoop().RunUntilIdle();
8203 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8204 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8205}
8206
8207// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148208TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:568209 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148210 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568211 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498212 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568213
Ryan Hamiltonabad59e2019-06-06 04:02:598214 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238215 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258216 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238217 mock_quic_data.AddWrite(SYNCHRONOUS,
8218 ConstructInitialSettingsPacket(packet_num++));
8219 }
Fan Yang32c5a112018-12-10 20:06:338220 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238221 SYNCHRONOUS,
8222 ConstructClientRequestHeadersPacket(
8223 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8224 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8225 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338226 mock_quic_data.AddRead(
8227 ASYNC, ConstructServerResponseHeadersPacket(
8228 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8229 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568230
8231 SpdyTestUtil spdy_util;
8232
Ryan Hamilton0239aac2018-05-19 00:03:138233 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568234 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438235 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568236 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418237 mock_quic_data.AddWrite(
8238 SYNCHRONOUS,
8239 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238240 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8241 1, 1, 1, false,
8242 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418243 } else {
8244 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418245 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288246 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238247 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8248 1, 1, 1, false,
Renjie Tangd5133972019-12-06 00:20:288249 {header + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418250 }
Ryan Hamilton0239aac2018-05-19 00:03:138251 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568252 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438253 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438254 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178255 ASYNC, ConstructServerDataPacket(
8256 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8257 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568258
Ryan Hamilton0239aac2018-05-19 00:03:138259 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198260 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:438261 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438262 mock_quic_data.AddRead(
8263 SYNCHRONOUS,
8264 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:338265 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438266 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:238267 mock_quic_data.AddWrite(SYNCHRONOUS,
8268 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568269 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8270
Bence Béky6e243aa2019-12-13 19:01:078271 if (VersionUsesHttp3(version_.transport_version)) {
8272 mock_quic_data.AddWrite(
8273 SYNCHRONOUS, ConstructClientDataPacket(
8274 packet_num++, GetQpackDecoderStreamId(), true, false,
8275 StreamCancellationQpackDecoderInstruction(0)));
8276 }
8277
Yixin Wang46a273ec302018-01-23 17:59:568278 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438279 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238280 ConstructClientRstPacket(packet_num++,
8281 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418282 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568283
8284 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8285
8286 SSLSocketDataProvider ssl_data(ASYNC, OK);
8287 ssl_data.next_proto = kProtoHTTP2;
8288 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8289
8290 CreateSession();
8291
8292 request_.url = GURL("https://mail.example.org/");
8293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8294 HeadersHandler headers_handler;
8295 trans.SetBeforeHeadersSentCallback(
8296 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8297 base::Unretained(&headers_handler)));
8298 RunTransaction(&trans);
8299 CheckWasSpdyResponse(&trans);
8300 CheckResponsePort(&trans, 70);
8301 CheckResponseData(&trans, "0123456789");
8302 EXPECT_TRUE(headers_handler.was_proxied());
8303 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8304
Wez0e717112018-06-18 23:09:228305 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
8306 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:568307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8308
8309 base::RunLoop().RunUntilIdle();
8310 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8311 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8312}
8313
8314// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
8315// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148316TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:568317 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148318 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568319 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498320 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568321
Ryan Hamiltonabad59e2019-06-06 04:02:598322 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:418323 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:258324 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238325 mock_quic_data.AddWrite(
8326 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
8327 }
Fan Yang32c5a112018-12-10 20:06:338328 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418329 SYNCHRONOUS,
8330 ConstructClientRequestHeadersPacket(
8331 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:048332 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028333 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338334 mock_quic_data.AddRead(
8335 ASYNC, ConstructServerResponseHeadersPacket(
8336 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8337 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568338
Ryan Hamilton8d9ee76e2018-05-29 23:52:528339 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568340 const char get_request_1[] =
8341 "GET / HTTP/1.1\r\n"
8342 "Host: mail.example.org\r\n"
8343 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438344 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:568345 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418346 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178347 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8348 write_packet_index++, false,
8349 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
8350 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:418351 } else {
8352 mock_quic_data.AddWrite(
Renjie Tangd5133972019-12-06 00:20:288353 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Ryan Hamilton7505eb92019-06-08 00:22:178354 write_packet_index++, false,
8355 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Renjie Tangd5133972019-12-06 00:20:288356 false, {header + std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:418357 }
8358
Yixin Wang46a273ec302018-01-23 17:59:568359 const char get_response_1[] =
8360 "HTTP/1.1 200 OK\r\n"
8361 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438362 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:438363 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438364 ASYNC, ConstructServerDataPacket(
8365 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178366 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418367 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568368
Victor Vasiliev076657c2019-03-12 02:46:438369 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338370 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178371 SYNCHRONOUS, ConstructServerDataPacket(
8372 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8373 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418374 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568375
Renjief49758b2019-01-11 23:32:418376 mock_quic_data.AddWrite(
8377 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568378
8379 const char get_request_2[] =
8380 "GET /2 HTTP/1.1\r\n"
8381 "Host: mail.example.org\r\n"
8382 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438383 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:568384 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418385 mock_quic_data.AddWrite(
8386 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288387 ConstructClientDataPacket(
Renjied172e812019-01-16 05:12:358388 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288389 false, false, {header4 + std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358390 } else {
8391 mock_quic_data.AddWrite(
8392 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178393 ConstructClientDataPacket(
8394 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8395 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418396 }
Yixin Wang46a273ec302018-01-23 17:59:568397
8398 const char get_response_2[] =
8399 "HTTP/1.1 200 OK\r\n"
8400 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438401 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438402 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438403 ASYNC, ConstructServerDataPacket(
8404 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178405 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418406 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568407
Victor Vasiliev076657c2019-03-12 02:46:438408 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528409 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178410 SYNCHRONOUS, ConstructServerDataPacket(
8411 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8412 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418413 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568414
Renjief49758b2019-01-11 23:32:418415 mock_quic_data.AddWrite(
8416 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568417 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8418
Bence Béky6e243aa2019-12-13 19:01:078419 if (VersionUsesHttp3(version_.transport_version)) {
8420 mock_quic_data.AddWrite(
8421 SYNCHRONOUS, ConstructClientDataPacket(
8422 write_packet_index++, GetQpackDecoderStreamId(), true,
8423 false, StreamCancellationQpackDecoderInstruction(0)));
8424 }
8425
Renjief49758b2019-01-11 23:32:418426 mock_quic_data.AddWrite(
8427 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418428 ConstructClientRstPacket(write_packet_index++,
8429 GetNthClientInitiatedBidirectionalStreamId(0),
8430 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568431
8432 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8433
8434 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8435
8436 CreateSession();
8437
8438 request_.url = GURL("https://mail.example.org/");
8439 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8440 HeadersHandler headers_handler_1;
8441 trans_1.SetBeforeHeadersSentCallback(
8442 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8443 base::Unretained(&headers_handler_1)));
8444 RunTransaction(&trans_1);
8445 CheckWasHttpResponse(&trans_1);
8446 CheckResponsePort(&trans_1, 70);
8447 CheckResponseData(&trans_1, "0123456789");
8448 EXPECT_TRUE(headers_handler_1.was_proxied());
8449 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8450
8451 request_.url = GURL("https://mail.example.org/2");
8452 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8453 HeadersHandler headers_handler_2;
8454 trans_2.SetBeforeHeadersSentCallback(
8455 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8456 base::Unretained(&headers_handler_2)));
8457 RunTransaction(&trans_2);
8458 CheckWasHttpResponse(&trans_2);
8459 CheckResponsePort(&trans_2, 70);
8460 CheckResponseData(&trans_2, "0123456");
8461 EXPECT_TRUE(headers_handler_2.was_proxied());
8462 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8463
8464 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8465 // proxy socket to disconnect.
8466 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8467
8468 base::RunLoop().RunUntilIdle();
8469 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8470 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8471}
8472
8473// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8474// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8475// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148476TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568477 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148478 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568479 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498480 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568481
Ryan Hamiltonabad59e2019-06-06 04:02:598482 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238483 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258484 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238485 mock_quic_data.AddWrite(SYNCHRONOUS,
8486 ConstructInitialSettingsPacket(packet_num++));
8487 }
Yixin Wang46a273ec302018-01-23 17:59:568488
8489 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338490 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238491 SYNCHRONOUS,
8492 ConstructClientRequestHeadersPacket(
8493 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8494 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8495 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438496 mock_quic_data.AddRead(
8497 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338498 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028499 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568500
8501 // GET request, response, and data over QUIC tunnel for first request
8502 const char get_request[] =
8503 "GET / HTTP/1.1\r\n"
8504 "Host: mail.example.org\r\n"
8505 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438506 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568507 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418508 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358509 SYNCHRONOUS,
8510 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238511 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8512 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418513 } else {
8514 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418515 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288516 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238517 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288518 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418519 }
8520
Yixin Wang46a273ec302018-01-23 17:59:568521 const char get_response[] =
8522 "HTTP/1.1 200 OK\r\n"
8523 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438524 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568525 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338526 ASYNC, ConstructServerDataPacket(
8527 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178528 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438529 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338530 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418531 SYNCHRONOUS, ConstructServerDataPacket(
8532 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178533 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238534 mock_quic_data.AddWrite(SYNCHRONOUS,
8535 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568536
8537 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438538 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238539 SYNCHRONOUS,
8540 ConstructClientRequestHeadersPacket(
8541 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8542 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8543 ConnectRequestHeaders("different.example.org:443"),
8544 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438545 mock_quic_data.AddRead(
8546 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338547 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028548 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568549
8550 // GET request, response, and data over QUIC tunnel for second request
8551 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138552 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568553 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438554 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568555 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418556 mock_quic_data.AddWrite(
8557 SYNCHRONOUS,
8558 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238559 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8560 4, 4, 1, false,
8561 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418562 } else {
8563 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418564 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288565 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238566 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8567 4, 4, 1, false,
Renjie Tangd5133972019-12-06 00:20:288568 {header4 + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418569 }
Yixin Wang46a273ec302018-01-23 17:59:568570
Ryan Hamilton0239aac2018-05-19 00:03:138571 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568572 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438573 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438574 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178575 ASYNC, ConstructServerDataPacket(
8576 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8577 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568578
Ryan Hamilton0239aac2018-05-19 00:03:138579 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198580 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438581 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438582 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438583 ASYNC, ConstructServerDataPacket(
8584 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438585 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568586
Renjie Tangaadb84b2019-08-31 01:00:238587 mock_quic_data.AddWrite(SYNCHRONOUS,
8588 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568589 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8590
Bence Béky6e243aa2019-12-13 19:01:078591 if (VersionUsesHttp3(version_.transport_version)) {
8592 mock_quic_data.AddWrite(
8593 SYNCHRONOUS, ConstructClientDataPacket(
8594 packet_num++, GetQpackDecoderStreamId(), true, false,
8595 StreamCancellationQpackDecoderInstruction(0)));
8596 }
8597
Yixin Wang46a273ec302018-01-23 17:59:568598 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418599 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238600 ConstructClientRstPacket(packet_num++,
8601 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418602 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078603
8604 if (VersionUsesHttp3(version_.transport_version)) {
8605 mock_quic_data.AddWrite(
8606 SYNCHRONOUS, ConstructClientDataPacket(
8607 packet_num++, GetQpackDecoderStreamId(), true, false,
8608 StreamCancellationQpackDecoderInstruction(1)));
8609 }
8610
Yixin Wang46a273ec302018-01-23 17:59:568611 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438612 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238613 ConstructClientRstPacket(packet_num++,
8614 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418615 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568616
8617 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8618
8619 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8620
8621 SSLSocketDataProvider ssl_data(ASYNC, OK);
8622 ssl_data.next_proto = kProtoHTTP2;
8623 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8624
8625 CreateSession();
8626
8627 request_.url = GURL("https://mail.example.org/");
8628 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8629 HeadersHandler headers_handler_1;
8630 trans_1.SetBeforeHeadersSentCallback(
8631 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8632 base::Unretained(&headers_handler_1)));
8633 RunTransaction(&trans_1);
8634 CheckWasHttpResponse(&trans_1);
8635 CheckResponsePort(&trans_1, 70);
8636 CheckResponseData(&trans_1, "0123456789");
8637 EXPECT_TRUE(headers_handler_1.was_proxied());
8638 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8639
8640 request_.url = GURL("https://different.example.org/");
8641 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8642 HeadersHandler headers_handler_2;
8643 trans_2.SetBeforeHeadersSentCallback(
8644 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8645 base::Unretained(&headers_handler_2)));
8646 RunTransaction(&trans_2);
8647 CheckWasSpdyResponse(&trans_2);
8648 CheckResponsePort(&trans_2, 70);
8649 CheckResponseData(&trans_2, "0123456");
8650 EXPECT_TRUE(headers_handler_2.was_proxied());
8651 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8652
8653 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8654 // proxy socket to disconnect.
8655 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8656
8657 base::RunLoop().RunUntilIdle();
8658 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8659 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8660}
8661
8662// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148663TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568664 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148665 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568666 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498667 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568668
Ryan Hamiltonabad59e2019-06-06 04:02:598669 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238670 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258671 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238672 mock_quic_data.AddWrite(SYNCHRONOUS,
8673 ConstructInitialSettingsPacket(packet_num++));
8674 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528675 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238676 SYNCHRONOUS,
8677 ConstructClientRequestHeadersPacket(
8678 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8679 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8680 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338681 mock_quic_data.AddRead(
8682 ASYNC, ConstructServerResponseHeadersPacket(
8683 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8684 GetResponseHeaders("500")));
8685 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238686 mock_quic_data.AddWrite(
8687 SYNCHRONOUS,
8688 ConstructClientAckAndRstPacket(
8689 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8690 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568691
8692 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8693
8694 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8695
8696 CreateSession();
8697
8698 request_.url = GURL("https://mail.example.org/");
8699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8700 HeadersHandler headers_handler;
8701 trans.SetBeforeHeadersSentCallback(
8702 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8703 base::Unretained(&headers_handler)));
8704 TestCompletionCallback callback;
8705 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8706 EXPECT_EQ(ERR_IO_PENDING, rv);
8707 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8708 EXPECT_EQ(false, headers_handler.was_proxied());
8709
8710 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8711 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8712}
8713
8714// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148715TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568716 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148717 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568718 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498719 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568720
Ryan Hamiltonabad59e2019-06-06 04:02:598721 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238722 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258723 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238724 mock_quic_data.AddWrite(SYNCHRONOUS,
8725 ConstructInitialSettingsPacket(packet_num++));
8726 }
Fan Yang32c5a112018-12-10 20:06:338727 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238728 SYNCHRONOUS,
8729 ConstructClientRequestHeadersPacket(
8730 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8731 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8732 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568733 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8734
8735 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8736
8737 CreateSession();
8738
8739 request_.url = GURL("https://mail.example.org/");
8740 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8741 HeadersHandler headers_handler;
8742 trans.SetBeforeHeadersSentCallback(
8743 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8744 base::Unretained(&headers_handler)));
8745 TestCompletionCallback callback;
8746 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8747 EXPECT_EQ(ERR_IO_PENDING, rv);
8748 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8749
8750 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8751 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8752}
8753
8754// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8755// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148756TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568757 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148758 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568759 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498760 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568761
Ryan Hamiltonabad59e2019-06-06 04:02:598762 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238763 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258764 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238765 mock_quic_data.AddWrite(SYNCHRONOUS,
8766 ConstructInitialSettingsPacket(packet_num++));
8767 }
Fan Yang32c5a112018-12-10 20:06:338768 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238769 SYNCHRONOUS,
8770 ConstructClientRequestHeadersPacket(
8771 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8772 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8773 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438774 mock_quic_data.AddRead(
8775 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338776 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028777 GetResponseHeaders("200 OK")));
Bence Béky6e243aa2019-12-13 19:01:078778 if (VersionUsesHttp3(version_.transport_version)) {
8779 mock_quic_data.AddWrite(
8780 SYNCHRONOUS,
8781 ConstructClientAckAndDataPacket(
8782 packet_num++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
8783 StreamCancellationQpackDecoderInstruction(0)));
8784 mock_quic_data.AddWrite(
8785 SYNCHRONOUS,
8786 ConstructClientRstPacket(packet_num++,
8787 GetNthClientInitiatedBidirectionalStreamId(0),
8788 quic::QUIC_STREAM_CANCELLED));
8789 } else {
8790 mock_quic_data.AddWrite(
8791 SYNCHRONOUS,
8792 ConstructClientAckAndRstPacket(
8793 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8794 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
8795 }
Yixin Wang46a273ec302018-01-23 17:59:568796
Zhongyi Shi32f2fd02018-04-16 18:23:438797 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238798 SYNCHRONOUS,
8799 ConstructClientRequestHeadersPacket(
8800 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8801 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8802 ConnectRequestHeaders("mail.example.org:443"),
8803 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438804 mock_quic_data.AddRead(
8805 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338806 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028807 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568808
8809 const char get_request[] =
8810 "GET / HTTP/1.1\r\n"
8811 "Host: mail.example.org\r\n"
8812 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438813 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568814 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418815 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358816 SYNCHRONOUS,
8817 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238818 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8819 2, 2, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418820 } else {
8821 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418822 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288823 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238824 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangd5133972019-12-06 00:20:288825 2, 2, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418826 }
Yixin Wang46a273ec302018-01-23 17:59:568827 const char get_response[] =
8828 "HTTP/1.1 200 OK\r\n"
8829 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438830 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438831 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338832 ASYNC, ConstructServerDataPacket(
8833 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178834 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528835
Victor Vasiliev076657c2019-03-12 02:46:438836 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338837 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418838 SYNCHRONOUS, ConstructServerDataPacket(
8839 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178840 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238841 mock_quic_data.AddWrite(SYNCHRONOUS,
8842 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568843 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8844
Bence Béky6e243aa2019-12-13 19:01:078845 if (VersionUsesHttp3(version_.transport_version)) {
8846 mock_quic_data.AddWrite(
8847 SYNCHRONOUS, ConstructClientDataPacket(
8848 packet_num++, GetQpackDecoderStreamId(), true, false,
8849 StreamCancellationQpackDecoderInstruction(1)));
8850 }
Yixin Wang46a273ec302018-01-23 17:59:568851 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418852 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238853 ConstructClientRstPacket(packet_num++,
8854 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418855 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568856
8857 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8858
8859 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8860 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8861
8862 SSLSocketDataProvider ssl_data(ASYNC, OK);
8863 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8864
8865 CreateSession();
8866
8867 request_.url = GURL("https://mail.example.org/");
8868 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8869 HeadersHandler headers_handler;
8870 trans.SetBeforeHeadersSentCallback(
8871 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8872 base::Unretained(&headers_handler)));
8873 TestCompletionCallback callback;
8874 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8875 EXPECT_EQ(ERR_IO_PENDING, rv);
8876 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8877
8878 rv = trans.RestartIgnoringLastError(callback.callback());
8879 EXPECT_EQ(ERR_IO_PENDING, rv);
8880 EXPECT_EQ(OK, callback.WaitForResult());
8881
8882 CheckWasHttpResponse(&trans);
8883 CheckResponsePort(&trans, 70);
8884 CheckResponseData(&trans, "0123456789");
8885 EXPECT_EQ(true, headers_handler.was_proxied());
8886 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8887
8888 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8889 // proxy socket to disconnect.
8890 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8891
8892 base::RunLoop().RunUntilIdle();
8893 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8894 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8895}
8896
8897// Checks if a request's specified "user-agent" header shows up correctly in the
8898// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148899TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008900 const char kConfiguredUserAgent[] = "Configured User-Agent";
8901 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568902 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148903 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568904 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498905 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568906
Ryan Hamiltonabad59e2019-06-06 04:02:598907 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238908 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258909 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238910 mock_quic_data.AddWrite(SYNCHRONOUS,
8911 ConstructInitialSettingsPacket(packet_num++));
8912 }
Yixin Wang46a273ec302018-01-23 17:59:568913
Ryan Hamilton0239aac2018-05-19 00:03:138914 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008915 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338916 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028917 SYNCHRONOUS,
8918 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238919 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8920 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
8921 0));
Yixin Wang46a273ec302018-01-23 17:59:568922 // Return an error, so the transaction stops here (this test isn't interested
8923 // in the rest).
8924 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8925
8926 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8927
Matt Menked732ea42019-03-08 12:05:008928 StaticHttpUserAgentSettings http_user_agent_settings(
8929 std::string() /* accept_language */, kConfiguredUserAgent);
8930 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568931 CreateSession();
8932
8933 request_.url = GURL("https://mail.example.org/");
8934 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008935 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568936 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8937 HeadersHandler headers_handler;
8938 trans.SetBeforeHeadersSentCallback(
8939 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8940 base::Unretained(&headers_handler)));
8941 TestCompletionCallback callback;
8942 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8943 EXPECT_EQ(ERR_IO_PENDING, rv);
8944 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8945
8946 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8947 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8948}
8949
Yixin Wang00fc44c2018-01-23 21:12:208950// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8951// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148952TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208953 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148954 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208955 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498956 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208957
8958 const RequestPriority request_priority = MEDIUM;
8959
Ryan Hamiltonabad59e2019-06-06 04:02:598960 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238961 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258962 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238963 mock_quic_data.AddWrite(SYNCHRONOUS,
8964 ConstructInitialSettingsPacket(packet_num++));
8965 }
Zhongyi Shi32f2fd02018-04-16 18:23:438966 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238967 SYNCHRONOUS,
8968 ConstructClientRequestHeadersPacket(
8969 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8970 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8971 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208972 // Return an error, so the transaction stops here (this test isn't interested
8973 // in the rest).
8974 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8975
8976 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8977
8978 CreateSession();
8979
8980 request_.url = GURL("https://mail.example.org/");
8981 HttpNetworkTransaction trans(request_priority, session_.get());
8982 TestCompletionCallback callback;
8983 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8984 EXPECT_EQ(ERR_IO_PENDING, rv);
8985 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8986
8987 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8988 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8989}
8990
Matt Menkeedaf3b82019-03-14 21:39:448991// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8992// HTTP/2 stream dependency and weights given the request priority.
8993TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8994 session_params_.enable_quic = true;
8995 session_params_.enable_quic_proxies_for_https_urls = true;
8996 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8997 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8998
8999 const RequestPriority kRequestPriority = MEDIUM;
9000 const RequestPriority kRequestPriority2 = LOWEST;
9001
Ryan Hamiltonabad59e2019-06-06 04:02:599002 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:259003 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239004 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
9005 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9006 } else {
9007 mock_quic_data.AddWrite(
9008 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9009 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
9010 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
9011 ConnectRequestHeaders("mail.example.org:443"), 0));
9012 }
Matt Menkeedaf3b82019-03-14 21:39:449013 // This should never be reached.
9014 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
9015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9016
9017 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:599018 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:449019 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
9020 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9021
9022 int original_max_sockets_per_group =
9023 ClientSocketPoolManager::max_sockets_per_group(
9024 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
9025 ClientSocketPoolManager::set_max_sockets_per_group(
9026 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
9027 int original_max_sockets_per_pool =
9028 ClientSocketPoolManager::max_sockets_per_pool(
9029 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
9030 ClientSocketPoolManager::set_max_sockets_per_pool(
9031 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
9032 CreateSession();
9033
9034 request_.url = GURL("https://mail.example.org/");
9035 HttpNetworkTransaction trans(kRequestPriority, session_.get());
9036 TestCompletionCallback callback;
9037 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9038 EXPECT_EQ(ERR_IO_PENDING, rv);
9039
9040 HttpRequestInfo request2;
9041 request2.url = GURL("https://mail.example.org/some/other/path/");
9042 request2.traffic_annotation =
9043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9044
9045 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
9046 TestCompletionCallback callback2;
9047 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
9048 EXPECT_EQ(ERR_IO_PENDING, rv2);
9049
9050 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
9051 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9052
9053 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
9054
9055 ClientSocketPoolManager::set_max_sockets_per_pool(
9056 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
9057 original_max_sockets_per_pool);
9058 ClientSocketPoolManager::set_max_sockets_per_group(
9059 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
9060 original_max_sockets_per_group);
9061}
9062
Yixin Wang46a273ec302018-01-23 17:59:569063// Test the request-challenge-retry sequence for basic auth, over a QUIC
9064// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:149065TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:569066 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
9067 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:569068
Yixin Wang46a273ec302018-01-23 17:59:569069 // On the second pass, the body read of the auth challenge is synchronous, so
9070 // IsConnectedAndIdle returns false. The socket should still be drained and
9071 // reused. See http://crbug.com/544255.
9072 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:079073 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229074 version_,
9075 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9076 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:079077 client_headers_include_h2_stream_dependency_);
9078 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229079 version_,
9080 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9081 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:079082 false);
Yixin Wang46a273ec302018-01-23 17:59:569083
9084 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:149085 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:569086 proxy_resolution_service_ =
9087 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:499088 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:569089
Ryan Hamiltonabad59e2019-06-06 04:02:599090 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529091 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:569092
Renjie Tangaadb84b2019-08-31 01:00:239093 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259094 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239095 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:079096 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangaadb84b2019-08-31 01:00:239097 }
Yixin Wang46a273ec302018-01-23 17:59:569098
9099 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439100 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079101 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239102 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9103 false,
Matt Menke6e879bd2019-03-18 17:26:049104 ConvertRequestPriorityToQuicPriority(
9105 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:079106 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029107 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569108
Ryan Hamilton0239aac2018-05-19 00:03:139109 spdy::SpdyHeaderBlock headers =
Bence Béky6e243aa2019-12-13 19:01:079110 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569111 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9112 headers["content-length"] = "10";
9113 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079114 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339115 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029116 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569117
9118 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:439119 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079120 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339121 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179122 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569123 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:439124 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079125 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339126 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:179127 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569128 }
9129 server_data_offset += 10;
9130
Renjie Tangaadb84b2019-08-31 01:00:239131 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:079132 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 2, 1, 1, true));
9133
9134 if (VersionUsesHttp3(version_.transport_version)) {
9135 mock_quic_data.AddWrite(
9136 SYNCHRONOUS,
9137 client_maker.MakeDataPacket(
9138 packet_num++, GetQpackDecoderStreamId(),
9139 /* should_include_version = */ true,
9140 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
9141 }
Yixin Wang46a273ec302018-01-23 17:59:569142
9143 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339144 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079145 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:239146 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:419147 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:189148 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:569149
Bence Béky6e243aa2019-12-13 19:01:079150 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:569151 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
9152 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:049153 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079154 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239155 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
9156 false,
Matt Menke6e879bd2019-03-18 17:26:049157 ConvertRequestPriorityToQuicPriority(
9158 HttpProxyConnectJob::kH2QuicTunnelPriority),
9159 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:029160 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569161
9162 // Response to wrong password
9163 headers =
Bence Béky6e243aa2019-12-13 19:01:079164 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569165 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9166 headers["content-length"] = "10";
9167 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079168 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339169 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029170 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569171 mock_quic_data.AddRead(SYNCHRONOUS,
9172 ERR_IO_PENDING); // No more data to read
9173
Bence Béky6e243aa2019-12-13 19:01:079174 if (VersionUsesHttp3(version_.transport_version)) {
9175 mock_quic_data.AddWrite(
9176 SYNCHRONOUS,
9177 client_maker.MakeAckAndDataPacket(
9178 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, 1, false,
9179 StreamCancellationQpackDecoderInstruction(1)));
9180 mock_quic_data.AddWrite(SYNCHRONOUS,
9181 client_maker.MakeRstPacket(
9182 packet_num++, false,
9183 GetNthClientInitiatedBidirectionalStreamId(1),
9184 quic::QUIC_STREAM_CANCELLED));
9185 } else {
9186 mock_quic_data.AddWrite(SYNCHRONOUS,
9187 client_maker.MakeAckAndRstPacket(
9188 packet_num++, false,
9189 GetNthClientInitiatedBidirectionalStreamId(1),
9190 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
9191 }
Yixin Wang46a273ec302018-01-23 17:59:569192
9193 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9194 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
9195
9196 CreateSession();
9197
9198 request_.url = GURL("https://mail.example.org/");
9199 // Ensure that proxy authentication is attempted even
9200 // when the no authentication data flag is set.
9201 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
9202 {
9203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9204 HeadersHandler headers_handler;
9205 trans.SetBeforeHeadersSentCallback(
9206 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
9207 base::Unretained(&headers_handler)));
9208 RunTransaction(&trans);
9209
9210 const HttpResponseInfo* response = trans.GetResponseInfo();
9211 ASSERT_TRUE(response != nullptr);
9212 ASSERT_TRUE(response->headers.get() != nullptr);
9213 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9214 response->headers->GetStatusLine());
9215 EXPECT_TRUE(response->headers->IsKeepAlive());
9216 EXPECT_EQ(407, response->headers->response_code());
9217 EXPECT_EQ(10, response->headers->GetContentLength());
9218 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589219 base::Optional<AuthChallengeInfo> auth_challenge =
9220 response->auth_challenge;
9221 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569222 EXPECT_TRUE(auth_challenge->is_proxy);
9223 EXPECT_EQ("https://proxy.example.org:70",
9224 auth_challenge->challenger.Serialize());
9225 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9226 EXPECT_EQ("basic", auth_challenge->scheme);
9227
9228 TestCompletionCallback callback;
9229 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
9230 callback.callback());
9231 EXPECT_EQ(ERR_IO_PENDING, rv);
9232 EXPECT_EQ(OK, callback.WaitForResult());
9233
9234 response = trans.GetResponseInfo();
9235 ASSERT_TRUE(response != nullptr);
9236 ASSERT_TRUE(response->headers.get() != nullptr);
9237 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9238 response->headers->GetStatusLine());
9239 EXPECT_TRUE(response->headers->IsKeepAlive());
9240 EXPECT_EQ(407, response->headers->response_code());
9241 EXPECT_EQ(10, response->headers->GetContentLength());
9242 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589243 auth_challenge = response->auth_challenge;
9244 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569245 EXPECT_TRUE(auth_challenge->is_proxy);
9246 EXPECT_EQ("https://proxy.example.org:70",
9247 auth_challenge->challenger.Serialize());
9248 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9249 EXPECT_EQ("basic", auth_challenge->scheme);
9250 }
9251 // HttpNetworkTransaction is torn down now that it's out of scope, causing
9252 // the QUIC stream to be cleaned up (since the proxy socket cannot be
9253 // reused because it's not connected).
9254 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9255 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9256 }
9257}
9258
Yixin Wang385652a2018-02-16 02:37:239259TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
Ryan Hamilton6c6493102019-12-05 21:36:509260 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
9261 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
9262
Yixin Wang385652a2018-02-16 02:37:239263 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
9264 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:569265 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:239266 !client_headers_include_h2_stream_dependency_) {
9267 return;
9268 }
9269
Victor Vasiliev7da08172019-10-14 06:04:259270 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:289271 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:459272 return;
9273 }
9274
Victor Vasilieva1e66d72019-12-05 17:55:389275 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:239276 HostPortPair::FromString("mail.example.org:443"));
9277
Fan Yang32c5a112018-12-10 20:06:339278 const quic::QuicStreamId client_stream_0 =
9279 GetNthClientInitiatedBidirectionalStreamId(0);
9280 const quic::QuicStreamId client_stream_1 =
9281 GetNthClientInitiatedBidirectionalStreamId(1);
9282 const quic::QuicStreamId client_stream_2 =
9283 GetNthClientInitiatedBidirectionalStreamId(2);
9284 const quic::QuicStreamId push_stream_0 =
9285 GetNthServerInitiatedUnidirectionalStreamId(0);
9286 const quic::QuicStreamId push_stream_1 =
9287 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:239288
Ryan Hamiltonabad59e2019-06-06 04:02:599289 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239290 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259291 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239292 mock_quic_data.AddWrite(SYNCHRONOUS,
9293 ConstructInitialSettingsPacket(packet_num++));
9294 }
Yixin Wang385652a2018-02-16 02:37:239295
9296 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:239297 mock_quic_data.AddWrite(
9298 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9299 packet_num++, client_stream_0, true, true, HIGHEST,
9300 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:029301 mock_quic_data.AddWrite(
9302 SYNCHRONOUS,
9303 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239304 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029305 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
9306 mock_quic_data.AddWrite(
9307 SYNCHRONOUS,
9308 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239309 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029310 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:239311
9312 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:029313 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9314 1, client_stream_0, false, false,
9315 GetResponseHeaders("200 OK")));
9316 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9317 2, client_stream_1, false, false,
9318 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239319 mock_quic_data.AddWrite(SYNCHRONOUS,
9320 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:029321 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9322 3, client_stream_2, false, false,
9323 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239324
9325 // Server sends two push promises associated with |client_stream_0|; client
9326 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
9327 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:029328 mock_quic_data.AddRead(
9329 ASYNC,
9330 ConstructServerPushPromisePacket(
9331 4, client_stream_0, push_stream_0, false,
9332 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:239333 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439334 SYNCHRONOUS,
9335 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239336 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439337 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:029338 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
9339 mock_quic_data.AddRead(
9340 ASYNC,
9341 ConstructServerPushPromisePacket(
9342 5, client_stream_0, push_stream_1, false,
9343 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
9344 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:239345 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:029346 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:239347
9348 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:439349 mock_quic_data.AddRead(
9350 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029351 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239352 mock_quic_data.AddWrite(SYNCHRONOUS,
9353 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439354 mock_quic_data.AddRead(
9355 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029356 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239357
9358 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
9359 // priority updates to match the request's priority. Client sends PRIORITY
9360 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:439361 mock_quic_data.AddWrite(
9362 SYNCHRONOUS,
9363 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239364 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439365 {{push_stream_1, client_stream_2,
9366 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
9367 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029368 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:239369
9370 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:439371 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:439372 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179373 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419374 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:439375 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179376 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419377 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:239378 mock_quic_data.AddWrite(SYNCHRONOUS,
9379 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439380 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179381 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:419382 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:439383 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:439384 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179385 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419386 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:239387 mock_quic_data.AddWrite(SYNCHRONOUS,
9388 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439389 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179390 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419391 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:239392
Yixin Wang385652a2018-02-16 02:37:239393 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9394 mock_quic_data.AddRead(ASYNC, 0); // EOF
9395 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9396
9397 // The non-alternate protocol job needs to hang in order to guarantee that
9398 // the alternate-protocol job will "win".
9399 AddHangingNonAlternateProtocolSocketData();
9400
9401 CreateSession();
9402
9403 request_.url = GURL("https://mail.example.org/0.jpg");
9404 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
9405 TestCompletionCallback callback_0;
9406 EXPECT_EQ(ERR_IO_PENDING,
9407 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
9408 base::RunLoop().RunUntilIdle();
9409
9410 request_.url = GURL("https://mail.example.org/1.jpg");
9411 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
9412 TestCompletionCallback callback_1;
9413 EXPECT_EQ(ERR_IO_PENDING,
9414 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
9415 base::RunLoop().RunUntilIdle();
9416
9417 request_.url = GURL("https://mail.example.org/2.jpg");
9418 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
9419 TestCompletionCallback callback_2;
9420 EXPECT_EQ(ERR_IO_PENDING,
9421 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
9422 base::RunLoop().RunUntilIdle();
9423
9424 // Client makes request that matches resource pushed in |pushed_stream_0|.
9425 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
9426 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
9427 TestCompletionCallback callback_3;
9428 EXPECT_EQ(ERR_IO_PENDING,
9429 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9430 base::RunLoop().RunUntilIdle();
9431
9432 EXPECT_TRUE(callback_0.have_result());
9433 EXPECT_EQ(OK, callback_0.WaitForResult());
9434 EXPECT_TRUE(callback_1.have_result());
9435 EXPECT_EQ(OK, callback_1.WaitForResult());
9436 EXPECT_TRUE(callback_2.have_result());
9437 EXPECT_EQ(OK, callback_2.WaitForResult());
9438
9439 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9440 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9441 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9442 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9443
9444 mock_quic_data.Resume();
9445 base::RunLoop().RunUntilIdle();
9446 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9447 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9448}
9449
Matt Menke26e41542019-06-05 01:09:519450// Test that NetworkIsolationKey is respected by QUIC connections, when
9451// kPartitionConnectionsByNetworkIsolationKey is enabled.
9452TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279453 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9454 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9455 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9456 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519457
Victor Vasilieva1e66d72019-12-05 17:55:389458 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519459 HostPortPair::FromString("mail.example.org:443"));
9460
9461 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9462 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9463 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9464 // the same way as the HTTP over H2 proxy case.
9465 for (bool use_proxy : {false, true}) {
9466 SCOPED_TRACE(use_proxy);
9467
9468 if (use_proxy) {
9469 proxy_resolution_service_ =
9470 ProxyResolutionService::CreateFixedFromPacResult(
9471 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9472 } else {
9473 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
9474 }
9475
9476 GURL url1;
9477 GURL url2;
9478 GURL url3;
9479 if (use_proxy) {
9480 url1 = GURL("http://mail.example.org/1");
9481 url2 = GURL("http://mail.example.org/2");
9482 url3 = GURL("http://mail.example.org/3");
9483 } else {
9484 url1 = GURL("https://mail.example.org/1");
9485 url2 = GURL("https://mail.example.org/2");
9486 url3 = GURL("https://mail.example.org/3");
9487 }
9488
9489 for (bool partition_connections : {false, true}) {
9490 SCOPED_TRACE(partition_connections);
9491
9492 base::test::ScopedFeatureList feature_list;
9493 if (partition_connections) {
9494 feature_list.InitAndEnableFeature(
9495 features::kPartitionConnectionsByNetworkIsolationKey);
9496 } else {
9497 feature_list.InitAndDisableFeature(
9498 features::kPartitionConnectionsByNetworkIsolationKey);
9499 }
9500
9501 // Reads and writes for the unpartitioned case, where only one socket is
9502 // used.
9503
Victor Vasilieva1e66d72019-12-05 17:55:389504 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519505 HostPortPair::FromString("mail.example.org:443"));
9506
Ryan Hamiltonabad59e2019-06-06 04:02:599507 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519508 QuicTestPacketMaker client_maker1(
9509 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229510 quic::QuicUtils::CreateRandomConnectionId(
9511 context_.random_generator()),
9512 context_.clock(), kDefaultServerHostName,
9513 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519514 client_headers_include_h2_stream_dependency_);
9515 QuicTestPacketMaker server_maker1(
9516 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229517 quic::QuicUtils::CreateRandomConnectionId(
9518 context_.random_generator()),
9519 context_.clock(), kDefaultServerHostName,
9520 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519521
Renjie Tangaadb84b2019-08-31 01:00:239522 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259523 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239524 unpartitioned_mock_quic_data.AddWrite(
9525 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9526 }
Matt Menke26e41542019-06-05 01:09:519527
9528 unpartitioned_mock_quic_data.AddWrite(
9529 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029530 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239531 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9532 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029533 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519534 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029535 ASYNC, server_maker1.MakeResponseHeadersPacket(
9536 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9537 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519538 unpartitioned_mock_quic_data.AddRead(
9539 ASYNC, server_maker1.MakeDataPacket(
9540 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179541 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519542 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239543 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519544
9545 unpartitioned_mock_quic_data.AddWrite(
9546 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029547 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239548 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9549 false, true,
Matt Menke26e41542019-06-05 01:09:519550 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029551 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519552 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029553 ASYNC, server_maker1.MakeResponseHeadersPacket(
9554 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9555 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519556 unpartitioned_mock_quic_data.AddRead(
9557 ASYNC, server_maker1.MakeDataPacket(
9558 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179559 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519560 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239561 SYNCHRONOUS,
9562 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519563
9564 unpartitioned_mock_quic_data.AddWrite(
9565 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029566 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239567 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9568 false, true,
Matt Menke26e41542019-06-05 01:09:519569 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029570 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519571 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029572 ASYNC, server_maker1.MakeResponseHeadersPacket(
9573 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9574 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519575 unpartitioned_mock_quic_data.AddRead(
9576 ASYNC, server_maker1.MakeDataPacket(
9577 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179578 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519579 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239580 SYNCHRONOUS,
9581 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519582
9583 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9584
9585 // Reads and writes for the partitioned case, where two sockets are used.
9586
Ryan Hamiltonabad59e2019-06-06 04:02:599587 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519588 QuicTestPacketMaker client_maker2(
9589 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229590 quic::QuicUtils::CreateRandomConnectionId(
9591 context_.random_generator()),
9592 context_.clock(), kDefaultServerHostName,
9593 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519594 client_headers_include_h2_stream_dependency_);
9595 QuicTestPacketMaker server_maker2(
9596 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229597 quic::QuicUtils::CreateRandomConnectionId(
9598 context_.random_generator()),
9599 context_.clock(), kDefaultServerHostName,
9600 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519601
Renjie Tangaadb84b2019-08-31 01:00:239602 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259603 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239604 partitioned_mock_quic_data1.AddWrite(
9605 SYNCHRONOUS,
9606 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9607 }
Matt Menke26e41542019-06-05 01:09:519608
9609 partitioned_mock_quic_data1.AddWrite(
9610 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029611 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239612 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9613 true, true,
Matt Menke26e41542019-06-05 01:09:519614 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029615 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519616 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029617 ASYNC, server_maker2.MakeResponseHeadersPacket(
9618 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9619 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519620 partitioned_mock_quic_data1.AddRead(
9621 ASYNC, server_maker2.MakeDataPacket(
9622 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179623 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519624 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239625 SYNCHRONOUS,
9626 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519627
9628 partitioned_mock_quic_data1.AddWrite(
9629 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029630 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239631 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9632 false, true,
Matt Menke26e41542019-06-05 01:09:519633 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029634 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519635 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029636 ASYNC, server_maker2.MakeResponseHeadersPacket(
9637 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9638 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519639 partitioned_mock_quic_data1.AddRead(
9640 ASYNC, server_maker2.MakeDataPacket(
9641 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179642 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519643 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239644 SYNCHRONOUS,
9645 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:519646
9647 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9648
Ryan Hamiltonabad59e2019-06-06 04:02:599649 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519650 QuicTestPacketMaker client_maker3(
9651 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229652 quic::QuicUtils::CreateRandomConnectionId(
9653 context_.random_generator()),
9654 context_.clock(), kDefaultServerHostName,
9655 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519656 client_headers_include_h2_stream_dependency_);
9657 QuicTestPacketMaker server_maker3(
9658 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229659 quic::QuicUtils::CreateRandomConnectionId(
9660 context_.random_generator()),
9661 context_.clock(), kDefaultServerHostName,
9662 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519663
Renjie Tangaadb84b2019-08-31 01:00:239664 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259665 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239666 partitioned_mock_quic_data2.AddWrite(
9667 SYNCHRONOUS,
9668 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9669 }
Matt Menke26e41542019-06-05 01:09:519670
9671 partitioned_mock_quic_data2.AddWrite(
9672 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029673 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239674 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9675 true, true,
Matt Menke26e41542019-06-05 01:09:519676 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029677 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519678 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029679 ASYNC, server_maker3.MakeResponseHeadersPacket(
9680 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9681 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519682 partitioned_mock_quic_data2.AddRead(
9683 ASYNC, server_maker3.MakeDataPacket(
9684 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179685 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519686 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239687 SYNCHRONOUS,
9688 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519689
9690 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9691
9692 if (partition_connections) {
9693 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9694 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9695 } else {
9696 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9697 }
9698
9699 CreateSession();
9700
9701 TestCompletionCallback callback;
9702 HttpRequestInfo request1;
9703 request1.method = "GET";
9704 request1.url = GURL(url1);
9705 request1.traffic_annotation =
9706 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9707 request1.network_isolation_key = network_isolation_key1;
9708 HttpNetworkTransaction trans1(LOWEST, session_.get());
9709 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9710 EXPECT_THAT(callback.GetResult(rv), IsOk());
9711 std::string response_data1;
9712 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9713 EXPECT_EQ("1", response_data1);
9714
9715 HttpRequestInfo request2;
9716 request2.method = "GET";
9717 request2.url = GURL(url2);
9718 request2.traffic_annotation =
9719 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9720 request2.network_isolation_key = network_isolation_key2;
9721 HttpNetworkTransaction trans2(LOWEST, session_.get());
9722 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9723 EXPECT_THAT(callback.GetResult(rv), IsOk());
9724 std::string response_data2;
9725 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9726 EXPECT_EQ("2", response_data2);
9727
9728 HttpRequestInfo request3;
9729 request3.method = "GET";
9730 request3.url = GURL(url3);
9731 request3.traffic_annotation =
9732 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9733 request3.network_isolation_key = network_isolation_key1;
9734 HttpNetworkTransaction trans3(LOWEST, session_.get());
9735 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9736 EXPECT_THAT(callback.GetResult(rv), IsOk());
9737 std::string response_data3;
9738 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9739 EXPECT_EQ("3", response_data3);
9740
9741 if (partition_connections) {
9742 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9743 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9744 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9745 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9746 } else {
9747 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9748 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9749 }
9750 }
9751 }
9752}
9753
9754// Test that two requests to the same origin over QUIC tunnels use different
9755// QUIC sessions if their NetworkIsolationKeys don't match, and
9756// kPartitionConnectionsByNetworkIsolationKey is enabled.
9757TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9758 base::test::ScopedFeatureList feature_list;
9759 feature_list.InitAndEnableFeature(
9760 features::kPartitionConnectionsByNetworkIsolationKey);
9761
9762 session_params_.enable_quic = true;
9763 session_params_.enable_quic_proxies_for_https_urls = true;
9764 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9765 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9766
9767 const char kGetRequest[] =
9768 "GET / HTTP/1.1\r\n"
9769 "Host: mail.example.org\r\n"
9770 "Connection: keep-alive\r\n\r\n";
9771 const char kGetResponse[] =
9772 "HTTP/1.1 200 OK\r\n"
9773 "Content-Length: 10\r\n\r\n";
9774
Ryan Hamiltonabad59e2019-06-06 04:02:599775 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9776 std::make_unique<MockQuicData>(version_),
9777 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519778
9779 for (int index : {0, 1}) {
9780 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229781 version_,
9782 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9783 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519784 client_headers_include_h2_stream_dependency_);
9785 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229786 version_,
9787 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9788 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9789 false);
Matt Menke26e41542019-06-05 01:09:519790
Renjie Tangaadb84b2019-08-31 01:00:239791 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259792 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239793 mock_quic_data[index]->AddWrite(
9794 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9795 }
Matt Menke26e41542019-06-05 01:09:519796
Ryan Hamiltonabad59e2019-06-06 04:02:599797 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519798 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029799 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239800 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9801 false,
Matt Menke26e41542019-06-05 01:09:519802 ConvertRequestPriorityToQuicPriority(
9803 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029804 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599805 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029806 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519807 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9808 false, GetResponseHeaders("200 OK"), nullptr));
9809
9810 std::string header = ConstructDataHeader(strlen(kGetRequest));
9811 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599812 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239813 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9814 packet_num++, false,
9815 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9816 1, false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519817 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599818 mock_quic_data[index]->AddWrite(
Renjie Tangd5133972019-12-06 00:20:289819 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:239820 packet_num++, false,
9821 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Renjie Tangd5133972019-12-06 00:20:289822 1, false, {header + std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519823 }
9824
9825 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599826 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519827 ASYNC, server_maker.MakeDataPacket(
9828 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179829 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599830 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179831 SYNCHRONOUS,
9832 server_maker.MakeDataPacket(
9833 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9834 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599835 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239836 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599837 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9838 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519839
Ryan Hamiltonabad59e2019-06-06 04:02:599840 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519841 }
9842
9843 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9844 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9845 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9846
9847 CreateSession();
9848
9849 request_.url = GURL("https://mail.example.org/");
9850 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9852 RunTransaction(&trans);
9853 CheckResponseData(&trans, "0123456789");
9854
9855 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279856 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9857 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519858 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9859 RunTransaction(&trans2);
9860 CheckResponseData(&trans2, "0123456789");
9861
Ryan Hamiltonabad59e2019-06-06 04:02:599862 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9863 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9864 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9865 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519866}
9867
[email protected]61a527782013-02-21 03:58:009868} // namespace test
9869} // namespace net