blob: cff1ff4faa2e2b35fb72d1e8b2b02223228e33c7 [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
Renjied172e812019-01-16 05:12:35526 std::unique_ptr<quic::QuicEncryptedPacket>
527 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23528 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35529 quic::QuicStreamId stream_id,
530 bool should_include_version,
531 bool fin,
Renjied172e812019-01-16 05:12:35532 const std::vector<std::string> data_writes) {
Ryan Hamilton7505eb92019-06-08 00:22:17533 return client_maker_.MakeMultipleDataFramesPacket(
534 packet_number, stream_id, should_include_version, fin, data_writes);
Renjied172e812019-01-16 05:12:35535 }
536
Ryan Hamilton8d9ee76e2018-05-29 23:52:52537 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23538 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56539 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52540 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23541 uint64_t largest_received,
542 uint64_t smallest_received,
543 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56544 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52545 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56546 return client_maker_.MakeAckAndDataPacket(
547 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17548 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56549 }
550
Renjied172e812019-01-16 05:12:35551 std::unique_ptr<quic::QuicEncryptedPacket>
552 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23553 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35554 bool include_version,
555 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23556 uint64_t largest_received,
557 uint64_t smallest_received,
558 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35559 bool fin,
Renjied172e812019-01-16 05:12:35560 const std::vector<std::string> data_writes) {
561 return client_maker_.MakeAckAndMultipleDataFramesPacket(
562 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17563 smallest_received, least_unacked, fin, data_writes);
Renjied172e812019-01-16 05:12:35564 }
565
Ryan Hamilton8d9ee76e2018-05-29 23:52:52566 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23567 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52568 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36569 bool should_include_version,
570 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52571 quic::QuicStreamOffset* offset,
572 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36573 return client_maker_.MakeForceHolDataPacket(
574 packet_number, stream_id, should_include_version, fin, offset, data);
575 }
576
Ryan Hamilton8d9ee76e2018-05-29 23:52:52577 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23578 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52579 quic::QuicStreamId stream_id,
580 bool should_include_version,
581 bool fin,
582 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56583 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
584 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02585 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56586 }
587
Ryan Hamilton8d9ee76e2018-05-29 23:52:52588 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23589 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52590 quic::QuicStreamId stream_id,
591 bool should_include_version,
592 bool fin,
593 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02594 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56595 return ConstructClientRequestHeadersPacket(
596 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02597 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30598 }
599
Ryan Hamilton8d9ee76e2018-05-29 23:52:52600 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23601 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52602 quic::QuicStreamId stream_id,
603 bool should_include_version,
604 bool fin,
605 RequestPriority request_priority,
606 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02607 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13608 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56609 ConvertRequestPriorityToQuicPriority(request_priority);
Ryan Hamilton0d65a8c2019-06-07 00:46:02610 return client_maker_.MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56611 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02612 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00613 }
614
Ryan Hamilton8d9ee76e2018-05-29 23:52:52615 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25616 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23617 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52618 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25619 bool should_include_version,
620 bool fin,
621 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13622 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52623 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25624 size_t* spdy_headers_frame_length,
625 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13626 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25627 ConvertRequestPriorityToQuicPriority(request_priority);
628 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
629 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02630 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25631 data_writes);
632 }
633
Ryan Hamilton8d9ee76e2018-05-29 23:52:52634 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23635 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52636 quic::QuicStreamId stream_id,
637 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13638 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13639 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13640 QuicTestPacketMaker* maker) {
641 return maker->MakePushPromisePacket(
642 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02643 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13644 }
645
Ryan Hamilton8d9ee76e2018-05-29 23:52:52646 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23647 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52648 quic::QuicStreamId stream_id,
649 bool should_include_version,
650 bool fin,
651 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02652 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
653 should_include_version, fin,
654 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30655 }
656
Victor Vasiliev076657c2019-03-12 02:46:43657 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56658 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41659 return "";
660 }
Renjief49758b2019-01-11 23:32:41661 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:57662 auto header_length =
663 quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43664 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41665 }
666
Nick Harper23290b82019-05-02 00:02:56667 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41668 session_params_.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:42669 session_params_.quic_params.supported_versions = supported_versions;
Bence Béky1ceba552019-07-19 17:11:05670 session_params_.quic_params.max_allowed_push_id = quic::kMaxQuicStreamId;
Nick Harper72ade192019-07-17 03:30:42671 session_params_.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05672 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00673
Victor Vasiliev7752898d2019-11-14 21:30:22674 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41675 session_context_.client_socket_factory = &socket_factory_;
676 session_context_.quic_crypto_client_stream_factory =
677 &crypto_client_stream_factory_;
678 session_context_.host_resolver = &host_resolver_;
679 session_context_.cert_verifier = &cert_verifier_;
680 session_context_.transport_security_state = &transport_security_state_;
681 session_context_.cert_transparency_verifier =
682 cert_transparency_verifier_.get();
683 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
684 session_context_.socket_performance_watcher_factory =
685 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59686 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41687 session_context_.ssl_config_service = ssl_config_service_.get();
688 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49689 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41690 session_context_.net_log = net_log_.bound().net_log();
691
692 session_.reset(new HttpNetworkSession(session_params_, session_context_));
Matt Menkeb566c392019-09-11 23:22:43693 session_->quic_stream_factory()
694 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56695 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
696 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00697 }
698
zhongyi86838d52017-06-30 01:19:44699 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21700
David Schinazif832cb82019-11-08 22:25:27701 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
702 const std::string& status_line) {
[email protected]aa9b14d2013-05-10 23:45:19703 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42704 ASSERT_TRUE(response != nullptr);
705 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27706 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19707 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52708 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:08709 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19710 response->connection_info);
711 }
712
David Schinazif832cb82019-11-08 22:25:27713 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
714 CheckWasQuicResponse(trans, "HTTP/1.1 200 OK");
715 }
716
bnc691fda62016-08-12 00:43:16717 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41718 const HttpResponseInfo* response = trans->GetResponseInfo();
719 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37720 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41721 }
722
bnc691fda62016-08-12 00:43:16723 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19724 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42725 ASSERT_TRUE(response != nullptr);
726 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19727 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
728 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52729 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52730 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19731 response->connection_info);
732 }
733
Yixin Wang46a273ec302018-01-23 17:59:56734 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
735 const HttpResponseInfo* response = trans->GetResponseInfo();
736 ASSERT_TRUE(response != nullptr);
737 ASSERT_TRUE(response->headers.get() != nullptr);
738 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
739 EXPECT_TRUE(response->was_fetched_via_spdy);
740 EXPECT_TRUE(response->was_alpn_negotiated);
741 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
742 response->connection_info);
743 }
744
bnc691fda62016-08-12 00:43:16745 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19746 const std::string& expected) {
747 std::string response_data;
bnc691fda62016-08-12 00:43:16748 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19749 EXPECT_EQ(expected, response_data);
750 }
751
bnc691fda62016-08-12 00:43:16752 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19753 TestCompletionCallback callback;
754 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01755 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
756 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19757 }
758
759 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
761 RunTransaction(&trans);
762 CheckWasHttpResponse(&trans);
763 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19764 }
765
tbansalc3308d72016-08-27 10:25:04766 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
767 bool used_proxy,
768 uint16_t port) {
769 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
770 HeadersHandler headers_handler;
771 trans.SetBeforeHeadersSentCallback(
772 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
773 base::Unretained(&headers_handler)));
774 RunTransaction(&trans);
775 CheckWasHttpResponse(&trans);
776 CheckResponsePort(&trans, port);
777 CheckResponseData(&trans, expected);
778 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47779 if (used_proxy) {
780 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
781 } else {
782 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
783 }
tbansalc3308d72016-08-27 10:25:04784 }
David Schinazif832cb82019-11-08 22:25:27785 void SendRequestAndExpectQuicResponse(const std::string& expected,
786 const std::string& status_line) {
787 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
788 status_line);
789 }
tbansalc3308d72016-08-27 10:25:04790
[email protected]aa9b14d2013-05-10 23:45:19791 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56792 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12793 }
794
bnc62a44f022015-04-02 15:59:41795 void SendRequestAndExpectQuicResponseFromProxyOnPort(
796 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46797 uint16_t port) {
bnc62a44f022015-04-02 15:59:41798 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19799 }
800
801 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05802 MockCryptoClientStream::HandshakeMode handshake_mode,
803 const NetworkIsolationKey& network_isolation_key =
804 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19805 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46806 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21807 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12808 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49809 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05810 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07811 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19812 }
813
rchbe69cb902016-02-11 01:10:48814 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27815 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48816 const HostPortPair& alternative) {
817 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46818 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21819 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48820 alternative.port());
821 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49822 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07823 server, NetworkIsolationKey(), alternative_service, expiration,
824 supported_versions_);
rchbe69cb902016-02-11 01:10:48825 }
826
Matt Menkeb32ba5122019-09-10 19:17:05827 void ExpectBrokenAlternateProtocolMapping(
828 const NetworkIsolationKey& network_isolation_key =
829 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46830 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34831 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49832 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05833 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34834 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49835 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05836 alternative_service_info_vector[0].alternative_service(),
837 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19838 }
839
Matt Menkeb32ba5122019-09-10 19:17:05840 void ExpectQuicAlternateProtocolMapping(
841 const NetworkIsolationKey& network_isolation_key =
842 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46843 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34844 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49845 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05846 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34847 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54848 EXPECT_EQ(
849 kProtoQUIC,
850 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49851 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05852 alternative_service_info_vector[0].alternative_service(),
853 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33854 }
855
[email protected]aa9b14d2013-05-10 23:45:19856 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42857 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30858 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30859 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30860 hanging_data->set_connect_data(hanging_connect);
861 hanging_data_.push_back(std::move(hanging_data));
862 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56863 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19864 }
865
Zhongyi Shia6b68d112018-09-24 07:49:03866 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Nick Harper72ade192019-07-17 03:30:42867 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
868 session_params_.quic_params.migrate_sessions_early_v2 = true;
869 session_params_.quic_params.retry_on_alternate_network_before_handshake =
870 true;
Zhongyi Shia6b68d112018-09-24 07:49:03871 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
872 MockNetworkChangeNotifier* mock_ncn =
873 scoped_mock_change_notifier_->mock_network_change_notifier();
874 mock_ncn->ForceNetworkHandlesSupported();
875 mock_ncn->SetConnectedNetworksList(
876 {kDefaultNetworkForTests, kNewNetworkForTests});
877 }
878
tbansalc3308d72016-08-27 10:25:04879 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
880 // alternative proxy. Verifies that if the alternative proxy job returns
881 // |error_code|, the request is fetched successfully by the main job.
882 void TestAlternativeProxy(int error_code) {
883 // Use a non-cryptographic scheme for the request URL since this request
884 // will be fetched via proxy with QUIC as the alternative service.
885 request_.url = GURL("http://example.org/");
886 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27887 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04888 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27889 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04890 };
891
Ryan Sleevib8d7ea02018-05-07 20:01:01892 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04893 socket_factory_.AddSocketDataProvider(&quic_data);
894
895 // Main job succeeds and the alternative job fails.
896 // Add data for two requests that will be read by the main job.
897 MockRead http_reads_1[] = {
898 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
900 MockRead(ASYNC, OK)};
901
902 MockRead http_reads_2[] = {
903 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
904 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
905 MockRead(ASYNC, OK)};
906
Ryan Sleevib8d7ea02018-05-07 20:01:01907 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
908 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04909 socket_factory_.AddSocketDataProvider(&http_data_1);
910 socket_factory_.AddSocketDataProvider(&http_data_2);
911 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
912 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
913
914 TestProxyDelegate test_proxy_delegate;
915 // Proxy URL is different from the request URL.
916 test_proxy_delegate.set_alternative_proxy_server(
917 ProxyServer::FromPacString("QUIC myproxy.org:443"));
918
Lily Houghton8c2f97d2018-01-22 05:06:59919 proxy_resolution_service_ =
920 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49921 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52922 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04923
924 CreateSession();
925 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
926
927 // The first request should be fetched via the HTTPS proxy.
928 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
929
Reilly Grant89a7e512018-01-20 01:57:16930 // Since the main job succeeded only the alternative proxy server should be
931 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59932 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16933 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04934
935 // Verify that the second request completes successfully, and the
936 // alternative proxy server job is not started.
937 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
938 }
939
Matt Menkeb32ba5122019-09-10 19:17:05940 // Adds a new socket data provider for an HTTP request, and runs a request,
941 // expecting it to be used.
942 void AddHttpDataAndRunRequest() {
943 MockWrite http_writes[] = {
944 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
945 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
946 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
947
948 MockRead http_reads[] = {
949 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
950 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
951 MockRead(SYNCHRONOUS, 5, "http used"),
952 // Connection closed.
953 MockRead(SYNCHRONOUS, OK, 6)};
954 SequencedSocketData http_data(http_reads, http_writes);
955 socket_factory_.AddSocketDataProvider(&http_data);
956 SSLSocketDataProvider ssl_data(ASYNC, OK);
957 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
958 SendRequestAndExpectHttpResponse("http used");
959 EXPECT_TRUE(http_data.AllWriteDataConsumed());
960 EXPECT_TRUE(http_data.AllReadDataConsumed());
961 }
962
963 // Adds a new socket data provider for a QUIC request, and runs a request,
964 // expecting it to be used. The new QUIC session is not closed.
965 void AddQuicDataAndRunRequest() {
966 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22967 version_,
968 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
969 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05970 client_headers_include_h2_stream_dependency_);
971 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22972 version_,
973 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
974 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
975 false);
Matt Menkeb32ba5122019-09-10 19:17:05976 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56977 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05978 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25979 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56980 quic_data.AddWrite(
981 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
982 }
Matt Menkeb32ba5122019-09-10 19:17:05983 quic_data.AddWrite(
984 SYNCHRONOUS,
985 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56986 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
987 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05988 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
989 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
990 quic_data.AddRead(
991 ASYNC, server_maker.MakeResponseHeadersPacket(
992 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
993 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
994 std::string header = ConstructDataHeader(9);
995 quic_data.AddRead(
996 ASYNC, server_maker.MakeDataPacket(
997 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
998 true, header + "quic used"));
999 // Don't care about the final ack.
1000 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
1001 // No more data to read.
1002 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1003 quic_data.AddSocketDataToFactory(&socket_factory_);
1004 SendRequestAndExpectQuicResponse("quic used");
1005
1006 EXPECT_TRUE(quic_data.AllReadDataConsumed());
1007 }
1008
Fan Yang32c5a112018-12-10 20:06:331009 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:561010 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
1011 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:361012 }
1013
Fan Yang32c5a112018-12-10 20:06:331014 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:561015 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
1016 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:361017 }
1018
Bence Béky230ac612017-08-30 19:17:081019 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:491020 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:081021 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:491022 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:081023 }
1024
Nick Harper23290b82019-05-02 00:02:561025 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:051026 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:561027 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011028 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221029 MockQuicContext context_;
alyssar2adf3ac2016-05-03 17:12:581030 QuicTestPacketMaker client_maker_;
1031 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091032 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421033 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001034 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561035 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051036 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431037 MockHostResolver host_resolver_;
1038 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111039 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421040 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231041 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381042 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071043 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:591044 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421045 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491046 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411047 HttpNetworkSession::Params session_params_;
1048 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191049 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:511050 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421051 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561052 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031053 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121054
1055 private:
1056 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1057 const std::string& expected,
bnc62a44f022015-04-02 15:59:411058 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271059 uint16_t port,
1060 const std::string& status_line) {
bnc691fda62016-08-12 00:43:161061 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091062 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161063 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091064 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1065 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161066 RunTransaction(&trans);
David Schinazif832cb82019-11-08 22:25:271067 CheckWasQuicResponse(&trans, status_line);
bnc691fda62016-08-12 00:43:161068 CheckResponsePort(&trans, port);
1069 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091070 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471071 if (used_proxy) {
1072 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1073 } else {
1074 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1075 }
tbansal7cec3812015-02-05 21:25:121076 }
David Schinazif832cb82019-11-08 22:25:271077
1078 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1079 const std::string& expected,
1080 bool used_proxy,
1081 uint16_t port) {
1082 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1083 "HTTP/1.1 200 OK");
1084 }
[email protected]61a527782013-02-21 03:58:001085};
1086
David Schinazi09e9a6012019-10-03 17:37:571087INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1088 QuicNetworkTransactionTest,
1089 ::testing::ValuesIn(GetTestParams()),
1090 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201091
Shivani Sharma8ae506c2019-07-21 21:08:271092// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1093// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1094
Ryan Hamiltona64a5bcf2017-11-30 07:35:281095TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Nick Harper72ade192019-07-17 03:30:421096 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281097 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421098 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281099 HostPortPair::FromString("mail.example.org:443"));
1100 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271101 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281102
Ryan Hamiltonabad59e2019-06-06 04:02:591103 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251104 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231105 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281106 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1107 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1108 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1109
1110 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1111
1112 CreateSession();
1113
1114 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1115 TestCompletionCallback callback;
1116 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1117 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1118 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1119
1120 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1121 -ERR_INTERNET_DISCONNECTED, 1);
1122 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1123 -ERR_INTERNET_DISCONNECTED, 1);
1124}
1125
1126TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Nick Harper72ade192019-07-17 03:30:421127 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281128 base::HistogramTester histograms;
Nick Harper72ade192019-07-17 03:30:421129 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281130 HostPortPair::FromString("mail.example.org:443"));
1131 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271132 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281133
Ryan Hamiltonabad59e2019-06-06 04:02:591134 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251135 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231136 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281137 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1138 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1139 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1140
1141 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1142
1143 CreateSession();
1144
1145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1146 TestCompletionCallback callback;
1147 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1148 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1149 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1150
1151 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1152 -ERR_INTERNET_DISCONNECTED, 1);
1153 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1154 -ERR_INTERNET_DISCONNECTED, 1);
1155}
1156
tbansal180587c2017-02-16 15:13:231157TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Nick Harper72ade192019-07-17 03:30:421158 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231159 HostPortPair::FromString("mail.example.org:443"));
1160
Ryan Hamiltonabad59e2019-06-06 04:02:591161 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231162 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251163 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231164 mock_quic_data.AddWrite(SYNCHRONOUS,
1165 ConstructInitialSettingsPacket(packet_num++));
1166 }
rch5cb522462017-04-25 20:18:361167 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231168 SYNCHRONOUS,
1169 ConstructClientRequestHeadersPacket(
1170 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1171 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431172 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331173 ASYNC, ConstructServerResponseHeadersPacket(
1174 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1175 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431176 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331177 mock_quic_data.AddRead(
1178 ASYNC, ConstructServerDataPacket(
1179 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171180 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231181 mock_quic_data.AddWrite(SYNCHRONOUS,
1182 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231183 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1184
1185 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1186
1187 CreateSession();
1188 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1189
1190 EXPECT_FALSE(
1191 test_socket_performance_watcher_factory_.rtt_notification_received());
1192 SendRequestAndExpectQuicResponse("hello!");
1193 EXPECT_TRUE(
1194 test_socket_performance_watcher_factory_.rtt_notification_received());
1195}
1196
1197TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Nick Harper72ade192019-07-17 03:30:421198 session_params_.quic_params.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231199 HostPortPair::FromString("mail.example.org:443"));
1200
Ryan Hamiltonabad59e2019-06-06 04:02:591201 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231202 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251203 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231204 mock_quic_data.AddWrite(SYNCHRONOUS,
1205 ConstructInitialSettingsPacket(packet_num++));
1206 }
rch5cb522462017-04-25 20:18:361207 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231208 SYNCHRONOUS,
1209 ConstructClientRequestHeadersPacket(
1210 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1211 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431212 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331213 ASYNC, ConstructServerResponseHeadersPacket(
1214 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1215 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431216 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331217 mock_quic_data.AddRead(
1218 ASYNC, ConstructServerDataPacket(
1219 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171220 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231221 mock_quic_data.AddWrite(SYNCHRONOUS,
1222 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231223 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1224
1225 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1226
1227 CreateSession();
1228 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1229
1230 EXPECT_FALSE(
1231 test_socket_performance_watcher_factory_.rtt_notification_received());
1232 SendRequestAndExpectQuicResponse("hello!");
1233 EXPECT_FALSE(
1234 test_socket_performance_watcher_factory_.rtt_notification_received());
1235}
1236
[email protected]1e960032013-12-20 19:00:201237TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Nick Harper72ade192019-07-17 03:30:421238 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571239 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471240
Ryan Hamiltonabad59e2019-06-06 04:02:591241 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231242 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251243 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231244 mock_quic_data.AddWrite(SYNCHRONOUS,
1245 ConstructInitialSettingsPacket(packet_num++));
1246 }
rch5cb522462017-04-25 20:18:361247 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231248 SYNCHRONOUS,
1249 ConstructClientRequestHeadersPacket(
1250 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1251 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431252 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331253 ASYNC, ConstructServerResponseHeadersPacket(
1254 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1255 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431256 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331257 mock_quic_data.AddRead(
1258 ASYNC, ConstructServerDataPacket(
1259 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171260 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231261 mock_quic_data.AddWrite(SYNCHRONOUS,
1262 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591263 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471264
rcha5399e02015-04-21 19:32:041265 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471266
[email protected]4dca587c2013-03-07 16:54:471267 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471268
[email protected]aa9b14d2013-05-10 23:45:191269 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471270
[email protected]98b20ce2013-05-10 05:55:261271 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541272 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261273 EXPECT_LT(0u, entries.size());
1274
1275 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291276 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001277 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1278 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261279 EXPECT_LT(0, pos);
1280
rchfd527212015-08-25 00:41:261281 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291282 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261283 entries, 0,
mikecirone8b85c432016-09-08 19:11:001284 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1285 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261286 EXPECT_LT(0, pos);
1287
Eric Roman79cc7552019-07-19 02:17:541288 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261289
rchfd527212015-08-25 00:41:261290 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1291 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001292 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1293 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261294 EXPECT_LT(0, pos);
1295
[email protected]98b20ce2013-05-10 05:55:261296 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291297 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001298 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1299 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261300 EXPECT_LT(0, pos);
1301
Eric Roman79cc7552019-07-19 02:17:541302 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251303 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451304 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1305 static_cast<quic::QuicStreamId>(log_stream_id));
1306 } else {
1307 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1308 static_cast<quic::QuicStreamId>(log_stream_id));
1309 }
[email protected]4dca587c2013-03-07 16:54:471310}
1311
rchbd089ab2017-05-26 23:05:041312TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421313 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041314 HostPortPair::FromString("mail.example.org:443"));
1315
Ryan Hamiltonabad59e2019-06-06 04:02:591316 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231317 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251318 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231319 mock_quic_data.AddWrite(SYNCHRONOUS,
1320 ConstructInitialSettingsPacket(packet_num++));
1321 }
rchbd089ab2017-05-26 23:05:041322 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231323 SYNCHRONOUS,
1324 ConstructClientRequestHeadersPacket(
1325 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1326 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131327 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041328 response_headers["key1"] = std::string(30000, 'A');
1329 response_headers["key2"] = std::string(30000, 'A');
1330 response_headers["key3"] = std::string(30000, 'A');
1331 response_headers["key4"] = std::string(30000, 'A');
1332 response_headers["key5"] = std::string(30000, 'A');
1333 response_headers["key6"] = std::string(30000, 'A');
1334 response_headers["key7"] = std::string(30000, 'A');
1335 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451336 quic::QuicStreamId stream_id;
1337 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251338 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451339 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1340 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1341 stream_id, std::move(response_headers), nullptr);
1342 for (const auto& e : encoded) {
1343 response_data += e;
1344 }
1345 } else {
1346 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1347 spdy::SpdyHeadersIR headers_frame(
1348 GetNthClientInitiatedBidirectionalStreamId(0),
1349 std::move(response_headers));
1350 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1351 spdy::SpdySerializedFrame spdy_frame =
1352 response_framer.SerializeFrame(headers_frame);
1353 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1354 }
rchbd089ab2017-05-26 23:05:041355
Fan Yangac867502019-01-28 21:10:231356 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041357 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451358 for (size_t offset = 0; offset < response_data.length();
1359 offset += chunk_size) {
1360 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431361 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451362 ASYNC, ConstructServerDataPacket(
1363 packet_number++, stream_id, false, false,
1364 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041365 }
1366
Victor Vasiliev076657c2019-03-12 02:46:431367 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041368 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331369 ASYNC, ConstructServerDataPacket(
1370 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171371 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041372 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431373 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231374 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1375 mock_quic_data.AddWrite(
1376 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041377
1378 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1379
1380 CreateSession();
1381
1382 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421383 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1384 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041385}
1386
1387TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Nick Harper72ade192019-07-17 03:30:421388 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
1389 session_params_.quic_params.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041390 HostPortPair::FromString("mail.example.org:443"));
1391
Ryan Hamiltonabad59e2019-06-06 04:02:591392 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231393 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251394 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231395 mock_quic_data.AddWrite(SYNCHRONOUS,
1396 ConstructInitialSettingsPacket(packet_num++));
1397 }
rchbd089ab2017-05-26 23:05:041398 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231399 SYNCHRONOUS,
1400 ConstructClientRequestHeadersPacket(
1401 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1402 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451403
Ryan Hamilton0239aac2018-05-19 00:03:131404 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041405 response_headers["key1"] = std::string(30000, 'A');
1406 response_headers["key2"] = std::string(30000, 'A');
1407 response_headers["key3"] = std::string(30000, 'A');
1408 response_headers["key4"] = std::string(30000, 'A');
1409 response_headers["key5"] = std::string(30000, 'A');
1410 response_headers["key6"] = std::string(30000, 'A');
1411 response_headers["key7"] = std::string(30000, 'A');
1412 response_headers["key8"] = std::string(30000, 'A');
1413 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451414
1415 quic::QuicStreamId stream_id;
1416 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251417 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451418 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
1419 std::vector<std::string> encoded = server_maker_.QpackEncodeHeaders(
1420 stream_id, std::move(response_headers), nullptr);
1421 for (const auto& e : encoded) {
1422 response_data += e;
1423 }
1424 } else {
1425 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1426 spdy::SpdyHeadersIR headers_frame(
1427 GetNthClientInitiatedBidirectionalStreamId(0),
1428 std::move(response_headers));
1429 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1430 spdy::SpdySerializedFrame spdy_frame =
1431 response_framer.SerializeFrame(headers_frame);
1432 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1433 }
rchbd089ab2017-05-26 23:05:041434
Fan Yangac867502019-01-28 21:10:231435 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041436 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451437 for (size_t offset = 0; offset < response_data.length();
1438 offset += chunk_size) {
1439 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431440 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451441 ASYNC, ConstructServerDataPacket(
1442 packet_number++, stream_id, false, false,
1443 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041444 }
1445
Victor Vasiliev076657c2019-03-12 02:46:431446 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411447
rchbd089ab2017-05-26 23:05:041448 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331449 ASYNC, ConstructServerDataPacket(
1450 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171451 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041452 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231453 mock_quic_data.AddWrite(ASYNC,
1454 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431455 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331456 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231457 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331458 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041459
1460 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1461
1462 CreateSession();
1463
1464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1465 TestCompletionCallback callback;
1466 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1468 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1469}
1470
rcha2bd44b2016-07-02 00:42:551471TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Nick Harper72ade192019-07-17 03:30:421472 session_params_.quic_params.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551473
Ryan Hamilton9835e662018-08-02 05:36:271474 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551475
Ryan Hamiltonabad59e2019-06-06 04:02:591476 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231477 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251478 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231479 mock_quic_data.AddWrite(SYNCHRONOUS,
1480 ConstructInitialSettingsPacket(packet_num++));
1481 }
rch5cb522462017-04-25 20:18:361482 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231483 SYNCHRONOUS,
1484 ConstructClientRequestHeadersPacket(
1485 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1486 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431487 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331488 ASYNC, ConstructServerResponseHeadersPacket(
1489 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1490 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431491 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331492 mock_quic_data.AddRead(
1493 ASYNC, ConstructServerDataPacket(
1494 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171495 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231496 mock_quic_data.AddWrite(SYNCHRONOUS,
1497 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551498 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1499
1500 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1501
1502 CreateSession();
1503
1504 SendRequestAndExpectQuicResponse("hello!");
1505 EXPECT_TRUE(
1506 test_socket_performance_watcher_factory_.rtt_notification_received());
1507}
1508
David Schinazif832cb82019-11-08 22:25:271509// Regression test for https://crbug.com/695225
1510TEST_P(QuicNetworkTransactionTest, 408Response) {
1511 session_params_.quic_params.origins_to_force_quic_on.insert(HostPortPair());
1512
1513 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1514
1515 MockQuicData mock_quic_data(version_);
1516 int packet_num = 1;
1517 if (VersionUsesHttp3(version_.transport_version)) {
1518 mock_quic_data.AddWrite(SYNCHRONOUS,
1519 ConstructInitialSettingsPacket(packet_num++));
1520 }
1521 mock_quic_data.AddWrite(
1522 SYNCHRONOUS,
1523 ConstructClientRequestHeadersPacket(
1524 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1525 true, GetRequestHeaders("GET", "https", "/")));
1526 mock_quic_data.AddRead(
1527 ASYNC, ConstructServerResponseHeadersPacket(
1528 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1529 GetResponseHeaders("408 Request Timeout")));
1530 std::string header = ConstructDataHeader(6);
1531 mock_quic_data.AddRead(
1532 ASYNC, ConstructServerDataPacket(
1533 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1534 header + "hello!"));
1535 mock_quic_data.AddWrite(SYNCHRONOUS,
1536 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1537 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1538
1539 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1540
1541 CreateSession();
1542
1543 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1544}
1545
[email protected]cf3e3cd62014-02-05 16:16:161546TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411547 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591548 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491549 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161550
Ryan Hamiltonabad59e2019-06-06 04:02:591551 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231552 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251553 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231554 mock_quic_data.AddWrite(SYNCHRONOUS,
1555 ConstructInitialSettingsPacket(packet_num++));
1556 }
rch5cb522462017-04-25 20:18:361557 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231558 SYNCHRONOUS,
1559 ConstructClientRequestHeadersPacket(
1560 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1561 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431562 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331563 ASYNC, ConstructServerResponseHeadersPacket(
1564 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1565 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431566 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331567 mock_quic_data.AddRead(
1568 ASYNC, ConstructServerDataPacket(
1569 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171570 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231571 mock_quic_data.AddWrite(SYNCHRONOUS,
1572 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501573 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591574 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161575
rcha5399e02015-04-21 19:32:041576 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161577
tbansal0f56a39a2016-04-07 22:03:381578 EXPECT_FALSE(
1579 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161580 // There is no need to set up an alternate protocol job, because
1581 // no attempt will be made to speak to the proxy over TCP.
1582
rch9ae5b3b2016-02-11 00:36:291583 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161584 CreateSession();
1585
bnc62a44f022015-04-02 15:59:411586 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381587 EXPECT_TRUE(
1588 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161589}
1590
bnc313ba9c2015-06-11 15:42:311591// Regression test for https://crbug.com/492458. Test that for an HTTP
1592// connection through a QUIC proxy, the certificate exhibited by the proxy is
1593// checked against the proxy hostname, not the origin hostname.
1594TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291595 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311596 const std::string proxy_host = "www.example.org";
1597
mmenke6ddfbea2017-05-31 21:48:411598 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591599 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491600 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311601
alyssar2adf3ac2016-05-03 17:12:581602 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591603 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231604 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251605 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231606 mock_quic_data.AddWrite(SYNCHRONOUS,
1607 ConstructInitialSettingsPacket(packet_num++));
1608 }
rch5cb522462017-04-25 20:18:361609 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231610 SYNCHRONOUS,
1611 ConstructClientRequestHeadersPacket(
1612 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1613 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431614 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331615 ASYNC, ConstructServerResponseHeadersPacket(
1616 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1617 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431618 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331619 mock_quic_data.AddRead(
1620 ASYNC, ConstructServerDataPacket(
1621 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171622 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231623 mock_quic_data.AddWrite(SYNCHRONOUS,
1624 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501625 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591626 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311627 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1628
1629 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291630 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311631 ASSERT_TRUE(cert.get());
1632 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241633 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1634 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311635 ProofVerifyDetailsChromium verify_details;
1636 verify_details.cert_verify_result.verified_cert = cert;
1637 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561638 ProofVerifyDetailsChromium verify_details2;
1639 verify_details2.cert_verify_result.verified_cert = cert;
1640 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311641
1642 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091643 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321644 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271645 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311646 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1647}
1648
rchbe69cb902016-02-11 01:10:481649TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Nick Harper72ade192019-07-17 03:30:421650 session_params_.quic_params.allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481651 HostPortPair origin("www.example.org", 443);
1652 HostPortPair alternative("mail.example.org", 443);
1653
1654 base::FilePath certs_dir = GetTestCertsDirectory();
1655 scoped_refptr<X509Certificate> cert(
1656 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1657 ASSERT_TRUE(cert.get());
1658 // TODO(rch): the connection should be "to" the origin, so if the cert is
1659 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241660 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1661 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481662 ProofVerifyDetailsChromium verify_details;
1663 verify_details.cert_verify_result.verified_cert = cert;
1664 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1665
alyssar2adf3ac2016-05-03 17:12:581666 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591667 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021668
Renjie Tangaadb84b2019-08-31 01:00:231669 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251670 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231671 mock_quic_data.AddWrite(SYNCHRONOUS,
1672 ConstructInitialSettingsPacket(packet_num++));
1673 }
rch5cb522462017-04-25 20:18:361674 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231675 SYNCHRONOUS,
1676 ConstructClientRequestHeadersPacket(
1677 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1678 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431679 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331680 ASYNC, ConstructServerResponseHeadersPacket(
1681 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1682 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431683 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331684 mock_quic_data.AddRead(
1685 ASYNC, ConstructServerDataPacket(
1686 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171687 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231688 mock_quic_data.AddWrite(SYNCHRONOUS,
1689 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481690 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1691 mock_quic_data.AddRead(ASYNC, 0);
1692 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1693
1694 request_.url = GURL("https://" + origin.host());
1695 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271696 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091697 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321698 CreateSession();
rchbe69cb902016-02-11 01:10:481699
1700 SendRequestAndExpectQuicResponse("hello!");
1701}
1702
zhongyief3f4ce52017-07-05 23:53:281703TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561704 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281705 // Add support for another QUIC version besides |version_|. Also find a
1706 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561707 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281708 if (version == version_)
1709 continue;
1710 if (supported_versions_.size() != 2) {
1711 supported_versions_.push_back(version);
1712 continue;
1713 }
1714 unsupported_version = version;
1715 break;
1716 }
Nick Harper23290b82019-05-02 00:02:561717 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281718
1719 // Set up alternative service to use QUIC with a version that is not
1720 // supported.
1721 url::SchemeHostPort server(request_.url);
1722 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1723 443);
1724 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491725 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071726 server, NetworkIsolationKey(), alternative_service, expiration,
1727 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281728
1729 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491730 http_server_properties_->GetAlternativeServiceInfos(
1731 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281732 EXPECT_EQ(1u, alt_svc_info_vector.size());
1733 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1734 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1735 EXPECT_EQ(unsupported_version,
1736 alt_svc_info_vector[0].advertised_versions()[0]);
1737
1738 // First request should still be sent via TCP as the QUIC version advertised
1739 // in the stored AlternativeService is not supported by the client. However,
1740 // the response from the server will advertise new Alt-Svc with supported
1741 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061742 quic::ParsedQuicVersionVector versions;
1743 for (quic::QuicTransportVersion version :
1744 quic::AllSupportedTransportVersions()) {
1745 versions.push_back(
1746 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1747 }
zhongyief3f4ce52017-07-05 23:53:281748 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061749 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281750 std::string altsvc_header =
1751 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1752 advertised_versions_list_str.c_str());
1753 MockRead http_reads[] = {
1754 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1755 MockRead("hello world"),
1756 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1757 MockRead(ASYNC, OK)};
1758
Ryan Sleevib8d7ea02018-05-07 20:01:011759 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281760 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081761 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281762 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1763
1764 // Second request should be sent via QUIC as a new list of verions supported
1765 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591766 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231767 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251768 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231769 mock_quic_data.AddWrite(SYNCHRONOUS,
1770 ConstructInitialSettingsPacket(packet_num++));
1771 }
zhongyief3f4ce52017-07-05 23:53:281772 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231773 SYNCHRONOUS,
1774 ConstructClientRequestHeadersPacket(
1775 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1776 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431777 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331778 ASYNC, ConstructServerResponseHeadersPacket(
1779 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1780 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431781 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331782 mock_quic_data.AddRead(
1783 ASYNC, ConstructServerDataPacket(
1784 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171785 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231786 mock_quic_data.AddWrite(SYNCHRONOUS,
1787 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281788 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1789 mock_quic_data.AddRead(ASYNC, 0); // EOF
1790
1791 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1792
1793 AddHangingNonAlternateProtocolSocketData();
1794
1795 CreateSession(supported_versions_);
1796
1797 SendRequestAndExpectHttpResponse("hello world");
1798 SendRequestAndExpectQuicResponse("hello!");
1799
1800 // Check alternative service list is updated with new versions.
1801 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491802 session_->http_server_properties()->GetAlternativeServiceInfos(
1803 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281804 EXPECT_EQ(1u, alt_svc_info_vector.size());
1805 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1806 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1807 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561808 std::sort(
1809 supported_versions_.begin(), supported_versions_.end(),
1810 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1811 return a.transport_version < b.transport_version;
1812 });
zhongyief3f4ce52017-07-05 23:53:281813 EXPECT_EQ(supported_versions_[0],
1814 alt_svc_info_vector[0].advertised_versions()[0]);
1815 EXPECT_EQ(supported_versions_[1],
1816 alt_svc_info_vector[0].advertised_versions()[1]);
1817}
1818
bncaccd4962017-04-06 21:00:261819// Regression test for https://crbug.com/546991.
1820// The server might not be able to serve a request on an alternative connection,
1821// and might send a 421 Misdirected Request response status to indicate this.
1822// HttpNetworkTransaction should reset the request and retry without using
1823// alternative services.
1824TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1825 // Set up alternative service to use QUIC.
1826 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1827 // that overrides |enable_alternative_services|.
1828 url::SchemeHostPort server(request_.url);
1829 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1830 443);
1831 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491832 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071833 server, NetworkIsolationKey(), alternative_service, expiration,
1834 supported_versions_);
bncaccd4962017-04-06 21:00:261835
davidbena4449722017-05-05 23:30:531836 // First try: The alternative job uses QUIC and reports an HTTP 421
1837 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1838 // paused at Connect(), so it will never exit the socket pool. This ensures
1839 // that the alternate job always wins the race and keeps whether the
1840 // |http_data| exits the socket pool before the main job is aborted
1841 // deterministic. The first main job gets aborted without the socket pool ever
1842 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591843 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231844 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251845 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231846 mock_quic_data.AddWrite(SYNCHRONOUS,
1847 ConstructInitialSettingsPacket(packet_num++));
1848 }
rch5cb522462017-04-25 20:18:361849 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231850 SYNCHRONOUS,
1851 ConstructClientRequestHeadersPacket(
1852 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1853 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331854 mock_quic_data.AddRead(
1855 ASYNC, ConstructServerResponseHeadersPacket(
1856 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021857 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261858 mock_quic_data.AddRead(ASYNC, OK);
1859 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1860
davidbena4449722017-05-05 23:30:531861 // Second try: The main job uses TCP, and there is no alternate job. Once the
1862 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1863 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261864 // Note that if there was an alternative QUIC Job created for the second try,
1865 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1866 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531867 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1868 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1869 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1870 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1871 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1872 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011873 reads, writes);
bncaccd4962017-04-06 21:00:261874 socket_factory_.AddSocketDataProvider(&http_data);
1875 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1876
bncaccd4962017-04-06 21:00:261877 CreateSession();
1878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531879
1880 // Run until |mock_quic_data| has failed and |http_data| has paused.
1881 TestCompletionCallback callback;
1882 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1883 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1884 base::RunLoop().RunUntilIdle();
1885
1886 // |mock_quic_data| must have run to completion.
1887 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1888 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1889
1890 // Now that the QUIC data has been consumed, unblock |http_data|.
1891 http_data.socket()->OnConnectComplete(MockConnect());
1892
1893 // The retry logic must hide the 421 status. The transaction succeeds on
1894 // |http_data|.
1895 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261896 CheckWasHttpResponse(&trans);
1897 CheckResponsePort(&trans, 443);
1898 CheckResponseData(&trans, "hello!");
1899}
1900
[email protected]1e960032013-12-20 19:00:201901TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Nick Harper72ade192019-07-17 03:30:421902 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571903 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301904
Ryan Hamiltonabad59e2019-06-06 04:02:591905 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251906 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231907 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401908 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021909 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591910 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251911 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231912 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301913 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401914 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431915 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401916
1917 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1918 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301919
1920 CreateSession();
1921
tbansal0f56a39a2016-04-07 22:03:381922 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401923 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401925 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161926 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1928 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381929 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531930
1931 NetErrorDetails details;
1932 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521933 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401934 }
[email protected]cebe3282013-05-22 23:49:301935}
1936
tbansalc8a94ea2015-11-02 23:58:511937TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1938 // Attempt to "force" quic on 443, which will not be honored.
Nick Harper72ade192019-07-17 03:30:421939 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571940 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511941
1942 MockRead http_reads[] = {
1943 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1944 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1945 MockRead(ASYNC, OK)};
1946
Ryan Sleevib8d7ea02018-05-07 20:01:011947 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511948 socket_factory_.AddSocketDataProvider(&data);
1949 SSLSocketDataProvider ssl(ASYNC, OK);
1950 socket_factory_.AddSSLSocketDataProvider(&ssl);
1951
1952 CreateSession();
1953
1954 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381955 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511956}
1957
bncc958faa2015-07-31 18:14:521958TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521959 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561960 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1961 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521962 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1963 MockRead(ASYNC, OK)};
1964
Ryan Sleevib8d7ea02018-05-07 20:01:011965 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521966 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081967 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561968 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521969
Ryan Hamiltonabad59e2019-06-06 04:02:591970 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231971 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251972 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231973 mock_quic_data.AddWrite(SYNCHRONOUS,
1974 ConstructInitialSettingsPacket(packet_num++));
1975 }
rch5cb522462017-04-25 20:18:361976 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231977 SYNCHRONOUS,
1978 ConstructClientRequestHeadersPacket(
1979 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1980 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431981 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331982 ASYNC, ConstructServerResponseHeadersPacket(
1983 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1984 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431985 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331986 mock_quic_data.AddRead(
1987 ASYNC, ConstructServerDataPacket(
1988 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171989 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231990 mock_quic_data.AddWrite(SYNCHRONOUS,
1991 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:521992 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591993 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521994
1995 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1996
rtennetib8e80fb2016-05-16 00:12:091997 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321998 CreateSession();
bncc958faa2015-07-31 18:14:521999
2000 SendRequestAndExpectHttpResponse("hello world");
2001 SendRequestAndExpectQuicResponse("hello!");
2002}
2003
Ryan Hamilton64f21d52019-08-31 07:10:512004TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
2005 std::string alt_svc_header =
2006 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2007 MockRead http_reads[] = {
2008 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
2009 MockRead("hello world"),
2010 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2011 MockRead(ASYNC, OK)};
2012
2013 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2014 socket_factory_.AddSocketDataProvider(&http_data);
2015 AddCertificate(&ssl_data_);
2016 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2017
2018 MockQuicData mock_quic_data(version_);
2019 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252020 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512021 mock_quic_data.AddWrite(SYNCHRONOUS,
2022 ConstructInitialSettingsPacket(packet_num++));
2023 }
2024 mock_quic_data.AddWrite(
2025 SYNCHRONOUS,
2026 ConstructClientRequestHeadersPacket(
2027 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2028 true, GetRequestHeaders("GET", "https", "/")));
2029 mock_quic_data.AddRead(
2030 ASYNC, ConstructServerResponseHeadersPacket(
2031 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2032 GetResponseHeaders("200 OK")));
2033 std::string header = ConstructDataHeader(6);
2034 mock_quic_data.AddRead(
2035 ASYNC, ConstructServerDataPacket(
2036 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2037 header + "hello!"));
2038 mock_quic_data.AddWrite(SYNCHRONOUS,
2039 ConstructClientAckPacket(packet_num++, 2, 1, 1));
2040 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2041 mock_quic_data.AddRead(ASYNC, 0); // EOF
2042
2043 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2044
2045 AddHangingNonAlternateProtocolSocketData();
2046 CreateSession();
2047
2048 SendRequestAndExpectHttpResponse("hello world");
2049 SendRequestAndExpectQuicResponse("hello!");
2050}
2051
Matt Menke3233d8f22019-08-20 21:01:492052// Much like above, but makes sure NetworkIsolationKey is respected.
2053TEST_P(QuicNetworkTransactionTest,
2054 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2055 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052056 feature_list.InitWithFeatures(
2057 // enabled_features
2058 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2059 features::kPartitionConnectionsByNetworkIsolationKey},
2060 // disabled_features
2061 {});
Matt Menke3233d8f22019-08-20 21:01:492062 // Since HttpServerProperties caches the feature value, have to create a new
2063 // one.
2064 http_server_properties_ = std::make_unique<HttpServerProperties>();
2065
2066 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2067 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2068 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2069 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2070
2071 MockRead http_reads[] = {
2072 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2073 MockRead("hello world"),
2074 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2075 MockRead(ASYNC, OK)};
2076
2077 AddCertificate(&ssl_data_);
2078
2079 // Request with empty NetworkIsolationKey.
2080 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2081 socket_factory_.AddSocketDataProvider(&http_data1);
2082 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2083
2084 // First request with kNetworkIsolationKey1.
2085 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2086 socket_factory_.AddSocketDataProvider(&http_data2);
2087 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2088
2089 // Request with kNetworkIsolationKey2.
2090 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2091 socket_factory_.AddSocketDataProvider(&http_data3);
2092 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2093
2094 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2095 // alternative service infrmation has been received in this context before.
2096 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232097 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252098 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232099 mock_quic_data.AddWrite(SYNCHRONOUS,
2100 ConstructInitialSettingsPacket(packet_num++));
2101 }
Matt Menke3233d8f22019-08-20 21:01:492102 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232103 SYNCHRONOUS,
2104 ConstructClientRequestHeadersPacket(
2105 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2106 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492107 mock_quic_data.AddRead(
2108 ASYNC, ConstructServerResponseHeadersPacket(
2109 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2110 GetResponseHeaders("200 OK")));
2111 std::string header = ConstructDataHeader(6);
2112 mock_quic_data.AddRead(
2113 ASYNC, ConstructServerDataPacket(
2114 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2115 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232116 mock_quic_data.AddWrite(SYNCHRONOUS,
2117 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492118 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2119 mock_quic_data.AddRead(ASYNC, 0); // EOF
2120
2121 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2122
2123 AddHangingNonAlternateProtocolSocketData();
2124 CreateSession();
2125
2126 // This is first so that the test fails if alternative service info is
2127 // written with the right NetworkIsolationKey, but always queried with an
2128 // empty one.
2129 request_.network_isolation_key = NetworkIsolationKey();
2130 SendRequestAndExpectHttpResponse("hello world");
2131 request_.network_isolation_key = kNetworkIsolationKey1;
2132 SendRequestAndExpectHttpResponse("hello world");
2133 request_.network_isolation_key = kNetworkIsolationKey2;
2134 SendRequestAndExpectHttpResponse("hello world");
2135
2136 // Only use QUIC when using a NetworkIsolationKey which has been used when
2137 // alternative service information was received.
2138 request_.network_isolation_key = kNetworkIsolationKey1;
2139 SendRequestAndExpectQuicResponse("hello!");
2140}
2141
zhongyia00ca012017-07-06 23:36:392142TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2143 // Both server advertises and client supports two QUIC versions.
2144 // Only |version_| is advertised and supported.
2145 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2146 // PacketMakers are using |version_|.
2147
2148 // Add support for another QUIC version besides |version_| on the client side.
2149 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562150 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2151 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392152 if (version == version_)
2153 continue;
2154 if (supported_versions_.size() != 2) {
2155 supported_versions_.push_back(version);
2156 continue;
2157 }
2158 advertised_version_2 = version;
2159 break;
2160 }
Nick Harper23290b82019-05-02 00:02:562161 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392162
Nick Harper23290b82019-05-02 00:02:562163 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
2164 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2165 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392166
2167 MockRead http_reads[] = {
2168 MockRead("HTTP/1.1 200 OK\r\n"),
2169 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2170 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2171 MockRead(ASYNC, OK)};
2172
Ryan Sleevib8d7ea02018-05-07 20:01:012173 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392174 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082175 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392176 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2177
Ryan Hamiltonabad59e2019-06-06 04:02:592178 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232179 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252180 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232181 mock_quic_data.AddWrite(SYNCHRONOUS,
2182 ConstructInitialSettingsPacket(packet_num++));
2183 }
zhongyia00ca012017-07-06 23:36:392184 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232185 SYNCHRONOUS,
2186 ConstructClientRequestHeadersPacket(
2187 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2188 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432189 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332190 ASYNC, ConstructServerResponseHeadersPacket(
2191 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2192 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432193 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332194 mock_quic_data.AddRead(
2195 ASYNC, ConstructServerDataPacket(
2196 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172197 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232198 mock_quic_data.AddWrite(SYNCHRONOUS,
2199 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392200 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2201 mock_quic_data.AddRead(ASYNC, 0); // EOF
2202
2203 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2204
2205 AddHangingNonAlternateProtocolSocketData();
2206 CreateSession(supported_versions_);
2207
2208 SendRequestAndExpectHttpResponse("hello world");
2209 SendRequestAndExpectQuicResponse("hello!");
2210}
2211
2212TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
2213 // Client and server mutually support more than one QUIC_VERSION.
2214 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2215 // which is verified as the PacketMakers are using |version_|.
2216
Nick Harper23290b82019-05-02 00:02:562217 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2218 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392219 if (version == version_)
2220 continue;
2221 common_version_2 = version;
2222 break;
2223 }
Nick Harper23290b82019-05-02 00:02:562224 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:392225
2226 supported_versions_.push_back(
2227 common_version_2); // Supported but unpreferred.
2228
2229 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562230 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2231 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392232
2233 MockRead http_reads[] = {
2234 MockRead("HTTP/1.1 200 OK\r\n"),
2235 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2236 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2237 MockRead(ASYNC, OK)};
2238
Ryan Sleevib8d7ea02018-05-07 20:01:012239 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392240 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082241 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392242 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2243
Ryan Hamiltonabad59e2019-06-06 04:02:592244 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232245 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252246 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232247 mock_quic_data.AddWrite(SYNCHRONOUS,
2248 ConstructInitialSettingsPacket(packet_num++));
2249 }
zhongyia00ca012017-07-06 23:36:392250 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232251 SYNCHRONOUS,
2252 ConstructClientRequestHeadersPacket(
2253 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2254 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432255 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332256 ASYNC, ConstructServerResponseHeadersPacket(
2257 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2258 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432259 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332260 mock_quic_data.AddRead(
2261 ASYNC, ConstructServerDataPacket(
2262 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172263 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232264 mock_quic_data.AddWrite(SYNCHRONOUS,
2265 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392266 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2267 mock_quic_data.AddRead(ASYNC, 0); // EOF
2268
2269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2270
2271 AddHangingNonAlternateProtocolSocketData();
2272 CreateSession(supported_versions_);
2273
2274 SendRequestAndExpectHttpResponse("hello world");
2275 SendRequestAndExpectQuicResponse("hello!");
2276}
2277
rchf47265dc2016-03-21 21:33:122278TEST_P(QuicNetworkTransactionTest,
2279 UseAlternativeServiceWithProbabilityForQuic) {
2280 MockRead http_reads[] = {
2281 MockRead("HTTP/1.1 200 OK\r\n"),
2282 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2283 MockRead("hello world"),
2284 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2285 MockRead(ASYNC, OK)};
2286
Ryan Sleevib8d7ea02018-05-07 20:01:012287 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122288 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082289 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122290 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2291
Ryan Hamiltonabad59e2019-06-06 04:02:592292 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232293 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252294 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232295 mock_quic_data.AddWrite(SYNCHRONOUS,
2296 ConstructInitialSettingsPacket(packet_num++));
2297 }
rch5cb522462017-04-25 20:18:362298 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232299 SYNCHRONOUS,
2300 ConstructClientRequestHeadersPacket(
2301 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2302 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432303 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332304 ASYNC, ConstructServerResponseHeadersPacket(
2305 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2306 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432307 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332308 mock_quic_data.AddRead(
2309 ASYNC, ConstructServerDataPacket(
2310 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172311 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232312 mock_quic_data.AddWrite(SYNCHRONOUS,
2313 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122314 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2315 mock_quic_data.AddRead(ASYNC, 0); // EOF
2316
2317 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2318
rtennetib8e80fb2016-05-16 00:12:092319 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122320 CreateSession();
2321
2322 SendRequestAndExpectHttpResponse("hello world");
2323 SendRequestAndExpectQuicResponse("hello!");
2324}
2325
zhongyi3d4a55e72016-04-22 20:36:462326TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2327 MockRead http_reads[] = {
2328 MockRead("HTTP/1.1 200 OK\r\n"),
2329 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2330 MockRead("hello world"),
2331 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2332 MockRead(ASYNC, OK)};
2333
Ryan Sleevib8d7ea02018-05-07 20:01:012334 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462335 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082336 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462337 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2338
2339 CreateSession();
bncb26024382016-06-29 02:39:452340 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462341 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452342 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462343 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402344 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462345 session_->http_server_properties();
2346 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2347 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2348 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462349 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492350 2u, http_server_properties
2351 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2352 .size());
bncb26024382016-06-29 02:39:452353 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492354 http_server_properties
2355 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2356 .empty());
zhongyi3d4a55e72016-04-22 20:36:462357}
2358
2359TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2360 MockRead http_reads[] = {
2361 MockRead("HTTP/1.1 200 OK\r\n"),
2362 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2363 MockRead("hello world"),
2364 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2365 MockRead(ASYNC, OK)};
2366
Ryan Sleevib8d7ea02018-05-07 20:01:012367 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082368 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462369
2370 socket_factory_.AddSocketDataProvider(&http_data);
2371 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2372 socket_factory_.AddSocketDataProvider(&http_data);
2373 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2374
2375 CreateSession();
2376
2377 // Send https request and set alternative services if response header
2378 // advertises alternative service for mail.example.org.
2379 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402380 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462381 session_->http_server_properties();
2382
2383 const url::SchemeHostPort https_server(request_.url);
2384 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342385 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492386 2u, http_server_properties
2387 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2388 .size());
zhongyi3d4a55e72016-04-22 20:36:462389
2390 // Send http request to the same origin but with diffrent scheme, should not
2391 // use QUIC.
2392 request_.url = GURL("http://mail.example.org:443");
2393 SendRequestAndExpectHttpResponse("hello world");
2394}
2395
zhongyie537a002017-06-27 16:48:212396TEST_P(QuicNetworkTransactionTest,
2397 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442398 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562399 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442400 if (version == version_)
2401 continue;
2402 supported_versions_.push_back(version);
2403 break;
2404 }
2405
Ryan Hamilton8380c652019-06-04 02:25:062406 quic::ParsedQuicVersionVector versions;
2407 for (quic::QuicTransportVersion version :
2408 quic::AllSupportedTransportVersions()) {
2409 versions.push_back(
2410 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2411 }
zhongyie537a002017-06-27 16:48:212412 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062413 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212414 std::string altsvc_header =
2415 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2416 advertised_versions_list_str.c_str());
2417 MockRead http_reads[] = {
2418 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2419 MockRead("hello world"),
2420 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2421 MockRead(ASYNC, OK)};
2422
Ryan Sleevib8d7ea02018-05-07 20:01:012423 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212424 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082425 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212426 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2427
Ryan Hamiltonabad59e2019-06-06 04:02:592428 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232429 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252430 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232431 mock_quic_data.AddWrite(SYNCHRONOUS,
2432 ConstructInitialSettingsPacket(packet_num++));
2433 }
zhongyie537a002017-06-27 16:48:212434 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232435 SYNCHRONOUS,
2436 ConstructClientRequestHeadersPacket(
2437 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2438 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332440 ASYNC, ConstructServerResponseHeadersPacket(
2441 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2442 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432443 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332444 mock_quic_data.AddRead(
2445 ASYNC, ConstructServerDataPacket(
2446 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172447 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232448 mock_quic_data.AddWrite(SYNCHRONOUS,
2449 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212450 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2451 mock_quic_data.AddRead(ASYNC, 0); // EOF
2452
2453 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2454
2455 AddHangingNonAlternateProtocolSocketData();
2456
zhongyi86838d52017-06-30 01:19:442457 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212458
2459 SendRequestAndExpectHttpResponse("hello world");
2460 SendRequestAndExpectQuicResponse("hello!");
2461
2462 // Check alternative service is set with only mutually supported versions.
2463 const url::SchemeHostPort https_server(request_.url);
2464 const AlternativeServiceInfoVector alt_svc_info_vector =
2465 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492466 https_server, NetworkIsolationKey());
zhongyie537a002017-06-27 16:48:212467 EXPECT_EQ(1u, alt_svc_info_vector.size());
2468 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2469 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2470 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562471 std::sort(
2472 supported_versions_.begin(), supported_versions_.end(),
2473 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2474 return a.transport_version < b.transport_version;
2475 });
zhongyi86838d52017-06-30 01:19:442476 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212477 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442478 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212479 alt_svc_info_vector[0].advertised_versions()[1]);
2480}
2481
danzh3134c2562016-08-12 14:07:522482TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562483 std::string altsvc_header = base::StringPrintf(
2484 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072485 MockRead http_reads[] = {
2486 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2487 MockRead("hello world"),
2488 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2489 MockRead(ASYNC, OK)};
2490
Ryan Sleevib8d7ea02018-05-07 20:01:012491 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072492 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082493 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072494 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2495
Ryan Hamiltonabad59e2019-06-06 04:02:592496 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232497 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252498 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232499 mock_quic_data.AddWrite(SYNCHRONOUS,
2500 ConstructInitialSettingsPacket(packet_num++));
2501 }
rch5cb522462017-04-25 20:18:362502 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232503 SYNCHRONOUS,
2504 ConstructClientRequestHeadersPacket(
2505 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2506 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432507 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332508 ASYNC, ConstructServerResponseHeadersPacket(
2509 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2510 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432511 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332512 mock_quic_data.AddRead(
2513 ASYNC, ConstructServerDataPacket(
2514 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172515 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232516 mock_quic_data.AddWrite(SYNCHRONOUS,
2517 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072518 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592519 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072520
2521 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2522
rtennetib8e80fb2016-05-16 00:12:092523 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322524 CreateSession();
bnc8be55ebb2015-10-30 14:12:072525
2526 SendRequestAndExpectHttpResponse("hello world");
2527 SendRequestAndExpectQuicResponse("hello!");
2528}
2529
zhongyi6b5a3892016-03-12 04:46:202530TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562531 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangba21e032019-09-27 21:52:282532 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092533 return;
2534 }
Ryan Hamiltonabad59e2019-06-06 04:02:592535 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232536 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252537 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232538 mock_quic_data.AddWrite(SYNCHRONOUS,
2539 ConstructInitialSettingsPacket(packet_num++));
2540 }
rch5cb522462017-04-25 20:18:362541 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232542 SYNCHRONOUS,
2543 ConstructClientRequestHeadersPacket(
2544 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2545 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332546 mock_quic_data.AddRead(
2547 ASYNC, ConstructServerResponseHeadersPacket(
2548 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2549 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202550 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522551 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432552 mock_quic_data.AddRead(SYNCHRONOUS,
2553 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522554 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432555 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232556 mock_quic_data.AddWrite(SYNCHRONOUS,
2557 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432558 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332559 mock_quic_data.AddRead(
2560 SYNCHRONOUS, ConstructServerDataPacket(
2561 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172562 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232563 mock_quic_data.AddWrite(
2564 SYNCHRONOUS,
2565 ConstructClientAckAndRstPacket(
2566 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2567 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202568 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2569 mock_quic_data.AddRead(ASYNC, 0); // EOF
2570
2571 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2572
2573 // The non-alternate protocol job needs to hang in order to guarantee that
2574 // the alternate-protocol job will "win".
2575 AddHangingNonAlternateProtocolSocketData();
2576
2577 // In order for a new QUIC session to be established via alternate-protocol
2578 // without racing an HTTP connection, we need the host resolution to happen
2579 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2580 // connection to the the server, in this test we require confirmation
2581 // before encrypting so the HTTP job will still start.
2582 host_resolver_.set_synchronous_mode(true);
2583 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2584 "");
zhongyi6b5a3892016-03-12 04:46:202585
2586 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432587 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2588 false);
Ryan Hamilton9835e662018-08-02 05:36:272589 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202590
bnc691fda62016-08-12 00:43:162591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202592 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362593 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202595
2596 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522597 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012598 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202599
2600 // Check whether this transaction is correctly marked as received a go-away
2601 // because of migrating port.
2602 NetErrorDetails details;
2603 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162604 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202605 EXPECT_TRUE(details.quic_port_migration_detected);
2606}
2607
Zhongyi Shia6b68d112018-09-24 07:49:032608// This test verifies that a new QUIC connection will be attempted on the
2609// alternate network if the original QUIC connection fails with idle timeout
2610// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2611// alternate network as well, QUIC is marked as broken and the brokenness will
2612// not expire when default network changes.
2613TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432614 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2615 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2616 return;
2617 }
Zhongyi Shia6b68d112018-09-24 07:49:032618 SetUpTestForRetryConnectionOnAlternateNetwork();
2619
Michael Warres167db3e2019-03-01 21:38:032620 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032621
2622 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592623 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032624 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2625 int packet_num = 1;
2626 quic_data.AddWrite(SYNCHRONOUS,
2627 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2628 // Retranmit the handshake messages.
2629 quic_data.AddWrite(SYNCHRONOUS,
2630 client_maker_.MakeDummyCHLOPacket(packet_num++));
2631 quic_data.AddWrite(SYNCHRONOUS,
2632 client_maker_.MakeDummyCHLOPacket(packet_num++));
2633 quic_data.AddWrite(SYNCHRONOUS,
2634 client_maker_.MakeDummyCHLOPacket(packet_num++));
2635 quic_data.AddWrite(SYNCHRONOUS,
2636 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032637 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2638 quic_data.AddWrite(SYNCHRONOUS,
2639 client_maker_.MakeConnectionClosePacket(
2640 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2641 "No recent network activity."));
2642 quic_data.AddSocketDataToFactory(&socket_factory_);
2643
2644 // Add successful TCP data so that TCP job will succeed.
2645 MockWrite http_writes[] = {
2646 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2647 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2648 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2649
2650 MockRead http_reads[] = {
2651 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2652 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2653 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2654 SequencedSocketData http_data(http_reads, http_writes);
2655 socket_factory_.AddSocketDataProvider(&http_data);
2656 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2657
2658 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592659 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032660 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2661 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2662 quic_data2.AddSocketDataToFactory(&socket_factory_);
2663
2664 // Resolve the host resolution synchronously.
2665 host_resolver_.set_synchronous_mode(true);
2666 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2667 "");
Zhongyi Shia6b68d112018-09-24 07:49:032668
2669 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432670 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2671 false);
Zhongyi Shia6b68d112018-09-24 07:49:032672 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032673 QuicStreamFactoryPeer::SetAlarmFactory(
2674 session_->quic_stream_factory(),
2675 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222676 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032677 // Add alternate protocol mapping to race QUIC and TCP.
2678 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2679 // peer.
2680 AddQuicAlternateProtocolMapping(
2681 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2682
2683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2684 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362685 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2687
2688 // Pump the message loop to get the request started.
2689 // Request will be served with TCP job.
2690 base::RunLoop().RunUntilIdle();
2691 EXPECT_THAT(callback.WaitForResult(), IsOk());
2692 CheckResponseData(&trans, "TCP succeeds");
2693
Zhongyi Shia6b68d112018-09-24 07:49:032694 // Fast forward to idle timeout the original connection. A new connection will
2695 // be kicked off on the alternate network.
2696 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2697 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2698 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2699
2700 // Run the message loop to execute posted tasks, which will report job status.
2701 base::RunLoop().RunUntilIdle();
2702
2703 // Verify that QUIC is marked as broken.
2704 ExpectBrokenAlternateProtocolMapping();
2705
2706 // Deliver a message to notify the new network becomes default, the brokenness
2707 // will not expire as QUIC is broken on both networks.
2708 scoped_mock_change_notifier_->mock_network_change_notifier()
2709 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2710 ExpectBrokenAlternateProtocolMapping();
2711
2712 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2713 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2714}
2715
2716// This test verifies that a new QUIC connection will be attempted on the
2717// alternate network if the original QUIC connection fails with idle timeout
2718// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2719// alternate network, QUIC is marked as broken. The brokenness will expire when
2720// the default network changes.
2721TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432722 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2723 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2724 return;
2725 }
2726
Zhongyi Shia6b68d112018-09-24 07:49:032727 SetUpTestForRetryConnectionOnAlternateNetwork();
2728
Michael Warres167db3e2019-03-01 21:38:032729 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032730
2731 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592732 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032733 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2734 int packet_num = 1;
2735 quic_data.AddWrite(SYNCHRONOUS,
2736 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2737 // Retranmit the handshake messages.
2738 quic_data.AddWrite(SYNCHRONOUS,
2739 client_maker_.MakeDummyCHLOPacket(packet_num++));
2740 quic_data.AddWrite(SYNCHRONOUS,
2741 client_maker_.MakeDummyCHLOPacket(packet_num++));
2742 quic_data.AddWrite(SYNCHRONOUS,
2743 client_maker_.MakeDummyCHLOPacket(packet_num++));
2744 quic_data.AddWrite(SYNCHRONOUS,
2745 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032746 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2747 quic_data.AddWrite(SYNCHRONOUS,
2748 client_maker_.MakeConnectionClosePacket(
2749 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2750 "No recent network activity."));
2751 quic_data.AddSocketDataToFactory(&socket_factory_);
2752
2753 // Add successful TCP data so that TCP job will succeed.
2754 MockWrite http_writes[] = {
2755 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2756 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2757 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2758
2759 MockRead http_reads[] = {
2760 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2761 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2762 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2763 SequencedSocketData http_data(http_reads, http_writes);
2764 socket_factory_.AddSocketDataProvider(&http_data);
2765 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2766
2767 // Quic connection will be retried on the alternate network after the initial
2768 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592769 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032770 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2771 quic_data2.AddWrite(SYNCHRONOUS,
2772 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2773
2774 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252775 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232776 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032777 quic_data2.AddSocketDataToFactory(&socket_factory_);
2778
2779 // Resolve the host resolution synchronously.
2780 host_resolver_.set_synchronous_mode(true);
2781 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2782 "");
Zhongyi Shia6b68d112018-09-24 07:49:032783
2784 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432785 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2786 false);
Zhongyi Shia6b68d112018-09-24 07:49:032787 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032788 QuicStreamFactoryPeer::SetAlarmFactory(
2789 session_->quic_stream_factory(),
2790 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222791 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032792 // Add alternate protocol mapping to race QUIC and TCP.
2793 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2794 // peer.
2795 AddQuicAlternateProtocolMapping(
2796 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2797
2798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2799 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362800 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032801 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2802
2803 // Pump the message loop to get the request started.
2804 // Request will be served with TCP job.
2805 base::RunLoop().RunUntilIdle();
2806 EXPECT_THAT(callback.WaitForResult(), IsOk());
2807 CheckResponseData(&trans, "TCP succeeds");
2808
Zhongyi Shia6b68d112018-09-24 07:49:032809 // Fast forward to idle timeout the original connection. A new connection will
2810 // be kicked off on the alternate network.
2811 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2812 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2813 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2814
2815 // The second connection hasn't finish handshake, verify that QUIC is not
2816 // marked as broken.
2817 ExpectQuicAlternateProtocolMapping();
2818 // Explicitly confirm the handshake on the second connection.
2819 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2820 quic::QuicSession::HANDSHAKE_CONFIRMED);
2821 // Run message loop to execute posted tasks, which will notify JoController
2822 // about the orphaned job status.
2823 base::RunLoop().RunUntilIdle();
2824
2825 // Verify that QUIC is marked as broken.
2826 ExpectBrokenAlternateProtocolMapping();
2827
2828 // Deliver a message to notify the new network becomes default, the previous
2829 // brokenness will be clear as the brokenness is bond with old default
2830 // network.
2831 scoped_mock_change_notifier_->mock_network_change_notifier()
2832 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2833 ExpectQuicAlternateProtocolMapping();
2834
2835 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2836 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2837}
2838
Matt Menkeb32ba5122019-09-10 19:17:052839// Much like above test, but verifies NetworkIsolationKeys are respected.
2840TEST_P(QuicNetworkTransactionTest,
2841 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432842 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2843 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2844 return;
2845 }
2846
Matt Menkeb32ba5122019-09-10 19:17:052847 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2848 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2849 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2850 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2851
2852 base::test::ScopedFeatureList feature_list;
2853 feature_list.InitWithFeatures(
2854 // enabled_features
2855 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2856 // Need to partition connections by NetworkIsolationKey for
2857 // QuicSessionAliasKey to include NetworkIsolationKeys.
2858 features::kPartitionConnectionsByNetworkIsolationKey},
2859 // disabled_features
2860 {});
2861 // Since HttpServerProperties caches the feature value, have to create a new
2862 // one.
2863 http_server_properties_ = std::make_unique<HttpServerProperties>();
2864
2865 SetUpTestForRetryConnectionOnAlternateNetwork();
2866
2867 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2868
2869 // The request will initially go out over QUIC.
2870 MockQuicData quic_data(version_);
2871 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2872 int packet_num = 1;
2873 quic_data.AddWrite(SYNCHRONOUS,
2874 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2875 // Retranmit the handshake messages.
2876 quic_data.AddWrite(SYNCHRONOUS,
2877 client_maker_.MakeDummyCHLOPacket(packet_num++));
2878 quic_data.AddWrite(SYNCHRONOUS,
2879 client_maker_.MakeDummyCHLOPacket(packet_num++));
2880 quic_data.AddWrite(SYNCHRONOUS,
2881 client_maker_.MakeDummyCHLOPacket(packet_num++));
2882 quic_data.AddWrite(SYNCHRONOUS,
2883 client_maker_.MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052884 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2885 quic_data.AddWrite(SYNCHRONOUS,
2886 client_maker_.MakeConnectionClosePacket(
2887 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2888 "No recent network activity."));
2889 quic_data.AddSocketDataToFactory(&socket_factory_);
2890
2891 // Add successful TCP data so that TCP job will succeed.
2892 MockWrite http_writes[] = {
2893 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2894 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2895 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2896
2897 MockRead http_reads[] = {
2898 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2899 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2900 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2901 SequencedSocketData http_data(http_reads, http_writes);
2902 socket_factory_.AddSocketDataProvider(&http_data);
2903 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2904
2905 // Quic connection will be retried on the alternate network after the initial
2906 // one fails on the default network.
2907 MockQuicData quic_data2(version_);
2908 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2909 quic_data2.AddWrite(SYNCHRONOUS,
2910 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2911
2912 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252913 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:052914 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2915 quic_data2.AddSocketDataToFactory(&socket_factory_);
2916
2917 // Resolve the host resolution synchronously.
2918 host_resolver_.set_synchronous_mode(true);
2919 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2920 "");
2921
2922 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432923 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2924 false);
Matt Menkeb32ba5122019-09-10 19:17:052925 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2926 QuicStreamFactoryPeer::SetAlarmFactory(
2927 session_->quic_stream_factory(),
2928 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222929 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:052930 // Add alternate protocol mapping to race QUIC and TCP.
2931 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2932 // peer.
2933 AddQuicAlternateProtocolMapping(
2934 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2935 AddQuicAlternateProtocolMapping(
2936 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2937
2938 request_.network_isolation_key = kNetworkIsolationKey1;
2939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2940 TestCompletionCallback callback;
2941 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2943
2944 // Pump the message loop to get the request started.
2945 // Request will be served with TCP job.
2946 base::RunLoop().RunUntilIdle();
2947 EXPECT_THAT(callback.WaitForResult(), IsOk());
2948 CheckResponseData(&trans, "TCP succeeds");
2949
2950 // Fast forward to idle timeout the original connection. A new connection will
2951 // be kicked off on the alternate network.
2952 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2953 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2954 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2955
2956 // The second connection hasn't finish handshake, verify that QUIC is not
2957 // marked as broken.
2958 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2959 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2960 // Explicitly confirm the handshake on the second connection.
2961 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2962 quic::QuicSession::HANDSHAKE_CONFIRMED);
2963 // Run message loop to execute posted tasks, which will notify JoController
2964 // about the orphaned job status.
2965 base::RunLoop().RunUntilIdle();
2966
2967 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2968 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2969 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2970
2971 // Deliver a message to notify the new network becomes default, the previous
2972 // brokenness will be clear as the brokenness is bond with old default
2973 // network.
2974 scoped_mock_change_notifier_->mock_network_change_notifier()
2975 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2976 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2977 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2978
2979 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2980 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2981}
2982
Zhongyi Shia6b68d112018-09-24 07:49:032983// This test verifies that a new QUIC connection will be attempted on the
2984// alternate network if the original QUIC connection fails with idle timeout
2985// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2986// alternative network succeeds, QUIC is not marked as broken.
2987TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432988 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2989 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2990 return;
2991 }
2992
Zhongyi Shia6b68d112018-09-24 07:49:032993 SetUpTestForRetryConnectionOnAlternateNetwork();
2994
Michael Warres167db3e2019-03-01 21:38:032995 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032996
2997 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592998 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032999 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3000 int packet_num = 1;
3001 quic_data.AddWrite(SYNCHRONOUS,
3002 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
3003 // Retranmit the handshake messages.
3004 quic_data.AddWrite(SYNCHRONOUS,
3005 client_maker_.MakeDummyCHLOPacket(packet_num++));
3006 quic_data.AddWrite(SYNCHRONOUS,
3007 client_maker_.MakeDummyCHLOPacket(packet_num++));
3008 quic_data.AddWrite(SYNCHRONOUS,
3009 client_maker_.MakeDummyCHLOPacket(packet_num++));
3010 quic_data.AddWrite(SYNCHRONOUS,
3011 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033012 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3013 quic_data.AddWrite(SYNCHRONOUS,
3014 client_maker_.MakeConnectionClosePacket(
3015 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3016 "No recent network activity."));
3017 quic_data.AddSocketDataToFactory(&socket_factory_);
3018
3019 // Add hanging TCP data so that TCP job will never succeeded.
3020 AddHangingNonAlternateProtocolSocketData();
3021
3022 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593023 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233024 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:033025 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:233026 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033027
Victor Vasiliev076657c2019-03-12 02:46:433028 const std::string body = "hello!";
3029 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:413030
Zhongyi Shia6b68d112018-09-24 07:49:033031 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253032 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233033 quic_data2.AddWrite(SYNCHRONOUS,
3034 ConstructInitialSettingsPacket(packet_num++));
3035 }
Zhongyi Shia6b68d112018-09-24 07:49:033036 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233037 SYNCHRONOUS,
3038 ConstructClientRequestHeadersPacket(
3039 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3040 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033041 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333042 ASYNC, ConstructServerResponseHeadersPacket(
3043 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3044 GetResponseHeaders("200 OK")));
3045 quic_data2.AddRead(
3046 ASYNC, ConstructServerDataPacket(
3047 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173048 header + body));
Renjie Tangaadb84b2019-08-31 01:00:233049 quic_data2.AddWrite(SYNCHRONOUS,
3050 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033051 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3052 quic_data2.AddSocketDataToFactory(&socket_factory_);
3053
3054 // Resolve the host resolution synchronously.
3055 host_resolver_.set_synchronous_mode(true);
3056 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3057 "");
Zhongyi Shia6b68d112018-09-24 07:49:033058
3059 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433060 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3061 false);
Zhongyi Shia6b68d112018-09-24 07:49:033062 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033063 QuicStreamFactoryPeer::SetAlarmFactory(
3064 session_->quic_stream_factory(),
3065 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223066 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033067 // Add alternate protocol mapping to race QUIC and TCP.
3068 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3069 // peer.
3070 AddQuicAlternateProtocolMapping(
3071 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3072
3073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3074 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363075 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3077
3078 // Pump the message loop to get the request started.
3079 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033080
3081 // Fast forward to idle timeout the original connection. A new connection will
3082 // be kicked off on the alternate network.
3083 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3084 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3085 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3086
3087 // Verify that QUIC is not marked as broken.
3088 ExpectQuicAlternateProtocolMapping();
3089 // Explicitly confirm the handshake on the second connection.
3090 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3091 quic::QuicSession::HANDSHAKE_CONFIRMED);
3092
3093 // Read the response.
3094 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413095 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033096 // Verify that QUIC is not marked as broken.
3097 ExpectQuicAlternateProtocolMapping();
3098
3099 // Deliver a message to notify the new network becomes default.
3100 scoped_mock_change_notifier_->mock_network_change_notifier()
3101 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3102 ExpectQuicAlternateProtocolMapping();
3103 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3104 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3105}
3106
rch9ecde09b2017-04-08 00:18:233107// Verify that if a QUIC connection times out, the QuicHttpStream will
3108// return QUIC_PROTOCOL_ERROR.
3109TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433110 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3111 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3112 return;
3113 }
3114
Nick Harper72ade192019-07-17 03:30:423115 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Sleevi2e8255b2019-07-17 21:02:213116 session_params_.quic_params.idle_connection_timeout =
3117 base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233118
3119 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593120 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133121 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233122 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3123
Ryan Hamiltone940bd12019-06-30 02:46:453124 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033125 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493126 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253127 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493128 quic_data.AddWrite(SYNCHRONOUS,
3129 ConstructInitialSettingsPacket(packet_num++));
3130 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023131 quic_data.AddWrite(
3132 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453133 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493134 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3135 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453136
3137 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233138
Victor Vasiliev7da08172019-10-14 06:04:253139 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493140 // TLP 1
3141 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3142 1, packet_num++, true));
3143 // TLP 2
3144 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3145 2, packet_num++, true));
3146 // RTO 1
3147 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3148 1, packet_num++, true));
3149 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3150 2, packet_num++, true));
3151 // RTO 2
3152 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3153 1, packet_num++, true));
3154 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3155 2, packet_num++, true));
3156 // RTO 3
3157 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3158 1, packet_num++, true));
3159 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3160 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013161
Findit2403b85d2019-11-19 05:06:373162 quic_data.AddWrite(SYNCHRONOUS,
3163 client_maker_.MakeConnectionClosePacket(
3164 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3165 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493166 } else {
3167 // Settings were sent in the request packet so there is only 1 packet to
3168 // retransmit.
3169 // TLP 1
3170 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3171 1, packet_num++, true));
3172 // TLP 2
3173 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3174 1, packet_num++, true));
3175 // RTO 1
3176 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3177 1, packet_num++, true));
3178 // RTO 2
3179 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3180 1, packet_num++, true));
3181 // RTO 3
3182 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3183 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373184
Nick Harper057264a82019-09-12 23:33:493185 quic_data.AddWrite(SYNCHRONOUS,
3186 client_maker_.MakeConnectionClosePacket(
3187 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3188 "No recent network activity."));
3189 }
Fan Yang928f1632017-12-14 18:55:223190
rch9ecde09b2017-04-08 00:18:233191 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3192 quic_data.AddRead(ASYNC, OK);
3193 quic_data.AddSocketDataToFactory(&socket_factory_);
3194
3195 // In order for a new QUIC session to be established via alternate-protocol
3196 // without racing an HTTP connection, we need the host resolution to happen
3197 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3198 // connection to the the server, in this test we require confirmation
3199 // before encrypting so the HTTP job will still start.
3200 host_resolver_.set_synchronous_mode(true);
3201 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3202 "");
rch9ecde09b2017-04-08 00:18:233203
3204 CreateSession();
3205 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233206 QuicStreamFactoryPeer::SetAlarmFactory(
3207 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193208 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223209 context_.clock()));
rch9ecde09b2017-04-08 00:18:233210
Ryan Hamilton9835e662018-08-02 05:36:273211 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233212
3213 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3214 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363215 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3217
3218 // Pump the message loop to get the request started.
3219 base::RunLoop().RunUntilIdle();
3220 // Explicitly confirm the handshake.
3221 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523222 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233223
3224 // Run the QUIC session to completion.
3225 quic_task_runner_->RunUntilIdle();
3226
3227 ExpectQuicAlternateProtocolMapping();
3228 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3229 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3230}
3231
3232// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3233// return QUIC_PROTOCOL_ERROR.
3234TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433235 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3236 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3237 return;
3238 }
3239
Nick Harper72ade192019-07-17 03:30:423240 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
3241 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233242
3243 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593244 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133245 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233246 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3247
Ryan Hamiltone940bd12019-06-30 02:46:453248 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033249 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493250 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253251 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493252 quic_data.AddWrite(
3253 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3254 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023255 quic_data.AddWrite(
3256 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453257 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493258 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3259 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453260
3261 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253262 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493263 // TLP 1
3264 quic_data.AddWrite(SYNCHRONOUS,
3265 client_maker_.MakeRetransmissionPacket(1, 3, true));
3266 // TLP 2
3267 quic_data.AddWrite(SYNCHRONOUS,
3268 client_maker_.MakeRetransmissionPacket(2, 4, true));
3269 // RTO 1
3270 quic_data.AddWrite(SYNCHRONOUS,
3271 client_maker_.MakeRetransmissionPacket(1, 5, true));
3272 quic_data.AddWrite(SYNCHRONOUS,
3273 client_maker_.MakeRetransmissionPacket(2, 6, true));
3274 // RTO 2
3275 quic_data.AddWrite(SYNCHRONOUS,
3276 client_maker_.MakeRetransmissionPacket(1, 7, true));
3277 quic_data.AddWrite(SYNCHRONOUS,
3278 client_maker_.MakeRetransmissionPacket(2, 8, true));
3279 // RTO 3
3280 quic_data.AddWrite(SYNCHRONOUS,
3281 client_maker_.MakeRetransmissionPacket(1, 9, true));
3282 quic_data.AddWrite(SYNCHRONOUS,
3283 client_maker_.MakeRetransmissionPacket(2, 10, true));
3284 // RTO 4
3285 quic_data.AddWrite(SYNCHRONOUS,
3286 client_maker_.MakeRetransmissionPacket(1, 11, true));
3287 quic_data.AddWrite(SYNCHRONOUS,
3288 client_maker_.MakeRetransmissionPacket(2, 12, true));
3289 // RTO 5
3290 quic_data.AddWrite(SYNCHRONOUS,
3291 client_maker_.MakeConnectionClosePacket(
3292 13, true, quic::QUIC_TOO_MANY_RTOS,
3293 "5 consecutive retransmission timeouts"));
3294 } else {
3295 // TLP 1
3296 quic_data.AddWrite(SYNCHRONOUS,
3297 client_maker_.MakeRetransmissionPacket(1, 2, true));
3298 // TLP 2
3299 quic_data.AddWrite(SYNCHRONOUS,
3300 client_maker_.MakeRetransmissionPacket(1, 3, true));
3301 // RTO 1
3302 quic_data.AddWrite(SYNCHRONOUS,
3303 client_maker_.MakeRetransmissionPacket(1, 4, true));
3304 // RTO 2
3305 quic_data.AddWrite(SYNCHRONOUS,
3306 client_maker_.MakeRetransmissionPacket(1, 5, true));
3307 // RTO 3
3308 quic_data.AddWrite(SYNCHRONOUS,
3309 client_maker_.MakeRetransmissionPacket(1, 6, true));
3310 // RTO 4
3311 quic_data.AddWrite(SYNCHRONOUS,
3312 client_maker_.MakeRetransmissionPacket(1, 7, true));
3313 // RTO 5
3314 quic_data.AddWrite(SYNCHRONOUS,
3315 client_maker_.MakeConnectionClosePacket(
3316 8, true, quic::QUIC_TOO_MANY_RTOS,
3317 "5 consecutive retransmission timeouts"));
3318 }
rch9ecde09b2017-04-08 00:18:233319
3320 quic_data.AddRead(ASYNC, OK);
3321 quic_data.AddSocketDataToFactory(&socket_factory_);
3322
3323 // In order for a new QUIC session to be established via alternate-protocol
3324 // without racing an HTTP connection, we need the host resolution to happen
3325 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3326 // connection to the the server, in this test we require confirmation
3327 // before encrypting so the HTTP job will still start.
3328 host_resolver_.set_synchronous_mode(true);
3329 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3330 "");
rch9ecde09b2017-04-08 00:18:233331
3332 CreateSession();
3333 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233334 QuicStreamFactoryPeer::SetAlarmFactory(
3335 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193336 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223337 context_.clock()));
rch9ecde09b2017-04-08 00:18:233338
Ryan Hamilton9835e662018-08-02 05:36:273339 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233340
3341 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3342 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363343 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3345
3346 // Pump the message loop to get the request started.
3347 base::RunLoop().RunUntilIdle();
3348 // Explicitly confirm the handshake.
3349 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523350 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233351
3352 // Run the QUIC session to completion.
3353 quic_task_runner_->RunUntilIdle();
3354
3355 ExpectQuicAlternateProtocolMapping();
3356 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3357 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3358}
3359
3360// Verify that if a QUIC connection RTOs, while there are no active streams
3361// QUIC will not be marked as broken.
3362TEST_P(QuicNetworkTransactionTest,
3363 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433364 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3365 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3366 return;
3367 }
3368
Nick Harper72ade192019-07-17 03:30:423369 session_params_.quic_params.connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233370
3371 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593372 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133373 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233374 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3375
Ryan Hamiltone940bd12019-06-30 02:46:453376 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033377 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493378 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253379 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493380 quic_data.AddWrite(
3381 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3382 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023383 quic_data.AddWrite(
3384 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453385 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493386 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3387 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453388
3389 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233390
Victor Vasiliev7da08172019-10-14 06:04:253391 if (!VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493392 quic_data.AddWrite(SYNCHRONOUS,
3393 client_maker_.MakeRstPacket(
3394 packet_number++, true,
3395 GetNthClientInitiatedBidirectionalStreamId(0),
3396 quic::QUIC_STREAM_CANCELLED));
3397 // TLP 1
3398 quic_data.AddWrite(SYNCHRONOUS,
3399 client_maker_.MakeRetransmissionPacket(1, 3, true));
3400 // TLP 2
3401 quic_data.AddWrite(SYNCHRONOUS,
3402 client_maker_.MakeRetransmissionPacket(2, 4, true));
3403 // RTO 1
3404 quic_data.AddWrite(SYNCHRONOUS,
3405 client_maker_.MakeRetransmissionPacket(1, 5, true));
3406 quic_data.AddWrite(SYNCHRONOUS,
3407 client_maker_.MakeRetransmissionPacket(2, 6, true));
3408 // RTO 2
3409 quic_data.AddWrite(SYNCHRONOUS,
3410 client_maker_.MakeRetransmissionPacket(1, 7, true));
3411 quic_data.AddWrite(SYNCHRONOUS,
3412 client_maker_.MakeRetransmissionPacket(2, 8, true));
3413 // RTO 3
3414 quic_data.AddWrite(SYNCHRONOUS,
3415 client_maker_.MakeRetransmissionPacket(1, 9, true));
3416 quic_data.AddWrite(SYNCHRONOUS,
3417 client_maker_.MakeRetransmissionPacket(2, 10, true));
3418 // RTO 4
3419 quic_data.AddWrite(SYNCHRONOUS,
3420 client_maker_.MakeRetransmissionPacket(1, 11, true));
3421 quic_data.AddWrite(SYNCHRONOUS,
3422 client_maker_.MakeRetransmissionPacket(2, 12, true));
3423 // RTO 5
3424 quic_data.AddWrite(SYNCHRONOUS,
3425 client_maker_.MakeConnectionClosePacket(
3426 13, true, quic::QUIC_TOO_MANY_RTOS,
3427 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423428 } else if (FLAGS_quic_allow_http3_priority) {
Nick Harper057264a82019-09-12 23:33:493429 quic_data.AddWrite(
3430 SYNCHRONOUS, client_maker_.MakeRstPacket(
3431 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb01f886f2019-07-10 02:25:553432 quic::QUIC_STREAM_CANCELLED));
Nick Harper057264a82019-09-12 23:33:493433 client_maker_.RemoveSavedStreamFrames(
3434 GetNthClientInitiatedBidirectionalStreamId(0));
3435 // TLP 1
3436 quic_data.AddWrite(SYNCHRONOUS,
3437 client_maker_.MakeRetransmissionPacket(1, 4, true));
3438 // TLP 2
3439 quic_data.AddWrite(SYNCHRONOUS,
3440 client_maker_.MakeRetransmissionPacket(2, 5, true));
3441 // RTO 1
3442 quic_data.AddWrite(SYNCHRONOUS,
3443 client_maker_.MakeRetransmissionPacket(3, 6, true));
3444 quic_data.AddWrite(SYNCHRONOUS,
3445 client_maker_.MakeRetransmissionPacket(1, 7, true));
3446 // RTO 2
3447 quic_data.AddWrite(SYNCHRONOUS,
3448 client_maker_.MakeRetransmissionPacket(2, 8, true));
3449 quic_data.AddWrite(SYNCHRONOUS,
3450 client_maker_.MakeRetransmissionPacket(3, 9, true));
3451 // RTO 3
3452 quic_data.AddWrite(SYNCHRONOUS,
3453 client_maker_.MakeRetransmissionPacket(1, 10, true));
3454 quic_data.AddWrite(SYNCHRONOUS,
3455 client_maker_.MakeRetransmissionPacket(2, 11, true));
3456 // RTO 4
3457 quic_data.AddWrite(SYNCHRONOUS,
3458 client_maker_.MakeRetransmissionPacket(3, 12, true));
3459 quic_data.AddWrite(SYNCHRONOUS,
3460 client_maker_.MakeRetransmissionPacket(1, 13, true));
3461 // RTO 5
3462 quic_data.AddWrite(SYNCHRONOUS,
3463 client_maker_.MakeConnectionClosePacket(
3464 14, true, quic::QUIC_TOO_MANY_RTOS,
3465 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423466 } else {
3467 quic_data.AddWrite(
3468 SYNCHRONOUS, client_maker_.MakeRstPacket(
3469 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3470 quic::QUIC_STREAM_CANCELLED));
3471 client_maker_.RemoveSavedStreamFrames(
3472 GetNthClientInitiatedBidirectionalStreamId(0));
3473 // When PRIORITY is disabled, packet 2 only contains request headers. And
3474 // since the request stream is reset, packet 2 will not be retransmitted.
3475 // TLP 1
3476 quic_data.AddWrite(SYNCHRONOUS,
3477 client_maker_.MakeRetransmissionPacket(1, 4, true));
3478 // TLP 2
3479 quic_data.AddWrite(SYNCHRONOUS,
3480 client_maker_.MakeRetransmissionPacket(3, 5, true));
3481 // RTO 1
3482 quic_data.AddWrite(SYNCHRONOUS,
3483 client_maker_.MakeRetransmissionPacket(1, 6, true));
3484 quic_data.AddWrite(SYNCHRONOUS,
3485 client_maker_.MakeRetransmissionPacket(3, 7, true));
3486 // RTO 2
3487 quic_data.AddWrite(SYNCHRONOUS,
3488 client_maker_.MakeRetransmissionPacket(1, 8, true));
3489 quic_data.AddWrite(SYNCHRONOUS,
3490 client_maker_.MakeRetransmissionPacket(3, 9, true));
3491 // RTO 3
3492 quic_data.AddWrite(SYNCHRONOUS,
3493 client_maker_.MakeRetransmissionPacket(1, 10, true));
3494 quic_data.AddWrite(SYNCHRONOUS,
3495 client_maker_.MakeRetransmissionPacket(3, 11, true));
3496 // RTO 4
3497 quic_data.AddWrite(SYNCHRONOUS,
3498 client_maker_.MakeRetransmissionPacket(1, 12, true));
3499 quic_data.AddWrite(SYNCHRONOUS,
3500 client_maker_.MakeRetransmissionPacket(3, 13, true));
3501 // RTO 5
3502 quic_data.AddWrite(SYNCHRONOUS,
3503 client_maker_.MakeConnectionClosePacket(
3504 14, true, quic::QUIC_TOO_MANY_RTOS,
3505 "5 consecutive retransmission timeouts"));
Nick Harper057264a82019-09-12 23:33:493506 }
rch9ecde09b2017-04-08 00:18:233507
3508 quic_data.AddRead(ASYNC, OK);
3509 quic_data.AddSocketDataToFactory(&socket_factory_);
3510
3511 // In order for a new QUIC session to be established via alternate-protocol
3512 // without racing an HTTP connection, we need the host resolution to happen
3513 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3514 // connection to the the server, in this test we require confirmation
3515 // before encrypting so the HTTP job will still start.
3516 host_resolver_.set_synchronous_mode(true);
3517 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3518 "");
rch9ecde09b2017-04-08 00:18:233519
3520 CreateSession();
3521 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233522 QuicStreamFactoryPeer::SetAlarmFactory(
3523 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193524 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223525 context_.clock()));
rch9ecde09b2017-04-08 00:18:233526
Ryan Hamilton9835e662018-08-02 05:36:273527 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233528
Jeremy Roman0579ed62017-08-29 15:56:193529 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233530 session_.get());
3531 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363532 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3534
3535 // Pump the message loop to get the request started.
3536 base::RunLoop().RunUntilIdle();
3537 // Explicitly confirm the handshake.
3538 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523539 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233540
3541 // Now cancel the request.
3542 trans.reset();
3543
3544 // Run the QUIC session to completion.
3545 quic_task_runner_->RunUntilIdle();
3546
3547 ExpectQuicAlternateProtocolMapping();
3548
3549 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3550}
3551
rch2f2991c2017-04-13 19:28:173552// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3553// the request fails with QUIC_PROTOCOL_ERROR.
3554TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433555 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3556 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3557 return;
3558 }
3559
Nick Harper72ade192019-07-17 03:30:423560 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173561 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593562 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033563 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493564 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253565 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493566 quic_data.AddWrite(SYNCHRONOUS,
3567 ConstructInitialSettingsPacket(packet_num++));
3568 }
3569 quic_data.AddWrite(
3570 SYNCHRONOUS,
3571 ConstructClientRequestHeadersPacket(
3572 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3573 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023574 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553575 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173576 // Peer sending data from an non-existing stream causes this end to raise
3577 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333578 quic_data.AddRead(
3579 ASYNC, ConstructServerRstPacket(
3580 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3581 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173582 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373583 quic_data.AddWrite(SYNCHRONOUS,
3584 ConstructClientAckAndConnectionClosePacket(
3585 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3586 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3587 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173588 quic_data.AddSocketDataToFactory(&socket_factory_);
3589
3590 // In order for a new QUIC session to be established via alternate-protocol
3591 // without racing an HTTP connection, we need the host resolution to happen
3592 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3593 // connection to the the server, in this test we require confirmation
3594 // before encrypting so the HTTP job will still start.
3595 host_resolver_.set_synchronous_mode(true);
3596 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3597 "");
rch2f2991c2017-04-13 19:28:173598
3599 CreateSession();
3600
Ryan Hamilton9835e662018-08-02 05:36:273601 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173602
3603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3604 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363605 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173606 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3607
3608 // Pump the message loop to get the request started.
3609 base::RunLoop().RunUntilIdle();
3610 // Explicitly confirm the handshake.
3611 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523612 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173613
3614 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553615 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173616
3617 // Run the QUIC session to completion.
3618 base::RunLoop().RunUntilIdle();
3619 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3620 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3621
3622 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3623 ExpectQuicAlternateProtocolMapping();
3624 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3625}
3626
rch2f2991c2017-04-13 19:28:173627// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3628// connection times out, then QUIC will be marked as broken and the request
3629// retried over TCP.
3630TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433631 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3632 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3633 return;
3634 }
3635
Ryan Sleevi2e8255b2019-07-17 21:02:213636 session_params_.quic_params.idle_connection_timeout =
3637 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173638
3639 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593640 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133641 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173642 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3643
Ryan Hamiltone940bd12019-06-30 02:46:453644 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033645 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493646 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253647 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493648 quic_data.AddWrite(SYNCHRONOUS,
3649 client_maker_.MakeInitialSettingsPacket(packet_num++));
3650 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023651 quic_data.AddWrite(
3652 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453653 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493654 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3655 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453656
3657 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253658 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493659 // TLP 1
3660 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3661 1, packet_num++, true));
3662 // TLP 2
3663 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3664 2, packet_num++, true));
3665 // RTO 1
3666 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3667 1, packet_num++, true));
3668 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3669 2, packet_num++, true));
3670 // RTO 2
3671 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3672 1, packet_num++, true));
3673 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3674 2, packet_num++, true));
3675 // RTO 3
3676 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3677 1, packet_num++, true));
3678 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3679 2, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373680
3681 quic_data.AddWrite(SYNCHRONOUS,
3682 client_maker_.MakeConnectionClosePacket(
3683 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3684 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493685 } else {
3686 // TLP 1
3687 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3688 1, packet_num++, true));
3689 // TLP 2
3690 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3691 1, packet_num++, true));
3692 // RTO 1
3693 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3694 1, packet_num++, true));
3695 // RTO 2
3696 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3697 1, packet_num++, true));
3698 // RTO 3
3699 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3700 1, packet_num++, true));
3701
3702 quic_data.AddWrite(SYNCHRONOUS,
3703 client_maker_.MakeConnectionClosePacket(
3704 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3705 "No recent network activity."));
3706 }
Fan Yang928f1632017-12-14 18:55:223707
rch2f2991c2017-04-13 19:28:173708 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3709 quic_data.AddRead(ASYNC, OK);
3710 quic_data.AddSocketDataToFactory(&socket_factory_);
3711
3712 // After that fails, it will be resent via TCP.
3713 MockWrite http_writes[] = {
3714 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3715 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3716 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3717
3718 MockRead http_reads[] = {
3719 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3720 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3721 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013722 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173723 socket_factory_.AddSocketDataProvider(&http_data);
3724 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3725
3726 // In order for a new QUIC session to be established via alternate-protocol
3727 // without racing an HTTP connection, we need the host resolution to happen
3728 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3729 // connection to the the server, in this test we require confirmation
3730 // before encrypting so the HTTP job will still start.
3731 host_resolver_.set_synchronous_mode(true);
3732 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3733 "");
rch2f2991c2017-04-13 19:28:173734
3735 CreateSession();
3736 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173737 QuicStreamFactoryPeer::SetAlarmFactory(
3738 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193739 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223740 context_.clock()));
rch2f2991c2017-04-13 19:28:173741
Ryan Hamilton9835e662018-08-02 05:36:273742 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173743
3744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3745 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363746 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3748
3749 // Pump the message loop to get the request started.
3750 base::RunLoop().RunUntilIdle();
3751 // Explicitly confirm the handshake.
3752 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523753 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173754
3755 // Run the QUIC session to completion.
3756 quic_task_runner_->RunUntilIdle();
3757 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3758
3759 ExpectQuicAlternateProtocolMapping();
3760
3761 // Let the transaction proceed which will result in QUIC being marked
3762 // as broken and the request falling back to TCP.
3763 EXPECT_THAT(callback.WaitForResult(), IsOk());
3764
3765 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3766 ASSERT_FALSE(http_data.AllReadDataConsumed());
3767
3768 // Read the response body over TCP.
3769 CheckResponseData(&trans, "hello world");
3770 ExpectBrokenAlternateProtocolMapping();
3771 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3772 ASSERT_TRUE(http_data.AllReadDataConsumed());
3773}
3774
rch2f2991c2017-04-13 19:28:173775// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3776// protocol error occurs after the handshake is confirmed, the request
3777// retried over TCP and the QUIC will be marked as broken.
3778TEST_P(QuicNetworkTransactionTest,
3779 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433780 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3781 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3782 return;
3783 }
3784
Ryan Sleevi2e8255b2019-07-17 21:02:213785 session_params_.quic_params.idle_connection_timeout =
3786 base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173787
3788 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593789 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033790 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493791 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253792 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493793 quic_data.AddWrite(SYNCHRONOUS,
3794 ConstructInitialSettingsPacket(packet_num++));
3795 }
3796 quic_data.AddWrite(
3797 SYNCHRONOUS,
3798 ConstructClientRequestHeadersPacket(
3799 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3800 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023801 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553802 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3803
rch2f2991c2017-04-13 19:28:173804 // Peer sending data from an non-existing stream causes this end to raise
3805 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333806 quic_data.AddRead(
3807 ASYNC, ConstructServerRstPacket(
3808 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3809 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173810 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373811 quic_data.AddWrite(SYNCHRONOUS,
3812 ConstructClientAckAndConnectionClosePacket(
3813 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3814 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3815 quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173816 quic_data.AddSocketDataToFactory(&socket_factory_);
3817
3818 // After that fails, it will be resent via TCP.
3819 MockWrite http_writes[] = {
3820 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3821 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3822 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3823
3824 MockRead http_reads[] = {
3825 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3826 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3827 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013828 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173829 socket_factory_.AddSocketDataProvider(&http_data);
3830 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3831
3832 // In order for a new QUIC session to be established via alternate-protocol
3833 // without racing an HTTP connection, we need the host resolution to happen
3834 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3835 // connection to the the server, in this test we require confirmation
3836 // before encrypting so the HTTP job will still start.
3837 host_resolver_.set_synchronous_mode(true);
3838 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3839 "");
rch2f2991c2017-04-13 19:28:173840
3841 CreateSession();
3842
Ryan Hamilton9835e662018-08-02 05:36:273843 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173844
3845 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3846 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363847 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173848 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3849
3850 // Pump the message loop to get the request started.
3851 base::RunLoop().RunUntilIdle();
3852 // Explicitly confirm the handshake.
3853 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523854 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553855 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173856
3857 // Run the QUIC session to completion.
3858 base::RunLoop().RunUntilIdle();
3859 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3860
3861 ExpectQuicAlternateProtocolMapping();
3862
3863 // Let the transaction proceed which will result in QUIC being marked
3864 // as broken and the request falling back to TCP.
3865 EXPECT_THAT(callback.WaitForResult(), IsOk());
3866
3867 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3868 ASSERT_FALSE(http_data.AllReadDataConsumed());
3869
3870 // Read the response body over TCP.
3871 CheckResponseData(&trans, "hello world");
3872 ExpectBrokenAlternateProtocolMapping();
3873 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3874 ASSERT_TRUE(http_data.AllReadDataConsumed());
3875}
3876
Matt Menkeb32ba5122019-09-10 19:17:053877// Much like above test, but verifies that NetworkIsolationKey is respected.
3878TEST_P(QuicNetworkTransactionTest,
3879 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433880 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3881 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3882 return;
3883 }
3884
Matt Menkeb32ba5122019-09-10 19:17:053885 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3886 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3887 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3888 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3889
3890 base::test::ScopedFeatureList feature_list;
3891 feature_list.InitWithFeatures(
3892 // enabled_features
3893 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3894 features::kPartitionConnectionsByNetworkIsolationKey},
3895 // disabled_features
3896 {});
3897 // Since HttpServerProperties caches the feature value, have to create a new
3898 // one.
3899 http_server_properties_ = std::make_unique<HttpServerProperties>();
3900
3901 session_params_.quic_params.idle_connection_timeout =
3902 base::TimeDelta::FromSeconds(5);
3903
3904 // The request will initially go out over QUIC.
3905 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563906 uint64_t packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:053907 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253908 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563909 quic_data.AddWrite(SYNCHRONOUS,
3910 ConstructInitialSettingsPacket(packet_number++));
3911 }
3912 quic_data.AddWrite(
3913 SYNCHRONOUS,
3914 ConstructClientRequestHeadersPacket(
3915 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3916 true, GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053917 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053918 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3919
3920 // Peer sending data from an non-existing stream causes this end to raise
3921 // error and close connection.
3922 quic_data.AddRead(
3923 ASYNC, ConstructServerRstPacket(
3924 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3925 quic::QUIC_STREAM_LAST_ERROR));
3926 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373927 quic_data.AddWrite(
3928 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
3929 packet_number++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3930 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
3931 quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053932 quic_data.AddSocketDataToFactory(&socket_factory_);
3933
3934 // After that fails, it will be resent via TCP.
3935 MockWrite http_writes[] = {
3936 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3937 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3938 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3939
3940 MockRead http_reads[] = {
3941 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3942 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3943 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3944 SequencedSocketData http_data(http_reads, http_writes);
3945 socket_factory_.AddSocketDataProvider(&http_data);
3946 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3947
3948 // In order for a new QUIC session to be established via alternate-protocol
3949 // without racing an HTTP connection, we need the host resolution to happen
3950 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3951 // connection to the the server, in this test we require confirmation
3952 // before encrypting so the HTTP job will still start.
3953 host_resolver_.set_synchronous_mode(true);
3954 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3955 "");
3956
3957 CreateSession();
3958
3959 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3960 kNetworkIsolationKey1);
3961 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3962 kNetworkIsolationKey2);
3963
3964 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3965 TestCompletionCallback callback;
3966 request_.network_isolation_key = kNetworkIsolationKey1;
3967 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3968 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3969
3970 // Pump the message loop to get the request started.
3971 base::RunLoop().RunUntilIdle();
3972 // Explicitly confirm the handshake.
3973 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
3974 quic::QuicSession::HANDSHAKE_CONFIRMED);
3975 quic_data.Resume();
3976
3977 // Run the QUIC session to completion.
3978 base::RunLoop().RunUntilIdle();
3979 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3980
3981 // Let the transaction proceed which will result in QUIC being marked
3982 // as broken and the request falling back to TCP.
3983 EXPECT_THAT(callback.WaitForResult(), IsOk());
3984 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3985 ASSERT_FALSE(http_data.AllReadDataConsumed());
3986
3987 // Read the response body over TCP.
3988 CheckResponseData(&trans, "hello world");
3989 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3990 ASSERT_TRUE(http_data.AllReadDataConsumed());
3991
3992 // The alternative service shouldhave been marked as broken under
3993 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3994 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3995 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3996
3997 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3998 AddHttpDataAndRunRequest();
3999 // Requests using other NetworkIsolationKeys can still use QUIC.
4000 request_.network_isolation_key = kNetworkIsolationKey2;
4001 AddQuicDataAndRunRequest();
4002
4003 // The last two requests should not have changed the alternative service
4004 // mappings.
4005 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
4006 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
4007}
4008
rch30943ee2017-06-12 21:28:444009// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4010// request is reset from, then QUIC will be marked as broken and the request
4011// retried over TCP.
4012TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:434013 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
4014 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
4015 return;
4016 }
4017
rch30943ee2017-06-12 21:28:444018 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:594019 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:134020 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:444021 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
4022
Michael Warres167db3e2019-03-01 21:38:034023 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494024 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254025 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494026 quic_data.AddWrite(SYNCHRONOUS,
4027 ConstructInitialSettingsPacket(packet_num++));
4028 }
Ryan Hamilton0d65a8c2019-06-07 00:46:024029 quic_data.AddWrite(
4030 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:454031 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:494032 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4033 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:454034
4035 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:554036 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:444037
Fan Yang32c5a112018-12-10 20:06:334038 quic_data.AddRead(ASYNC,
4039 ConstructServerRstPacket(
4040 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
4041 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444042
4043 quic_data.AddRead(ASYNC, OK);
4044 quic_data.AddSocketDataToFactory(&socket_factory_);
4045
4046 // After that fails, it will be resent via TCP.
4047 MockWrite http_writes[] = {
4048 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4049 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
4050 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4051
4052 MockRead http_reads[] = {
4053 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4054 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4055 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014056 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444057 socket_factory_.AddSocketDataProvider(&http_data);
4058 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4059
4060 // In order for a new QUIC session to be established via alternate-protocol
4061 // without racing an HTTP connection, we need the host resolution to happen
4062 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4063 // connection to the the server, in this test we require confirmation
4064 // before encrypting so the HTTP job will still start.
4065 host_resolver_.set_synchronous_mode(true);
4066 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4067 "");
rch30943ee2017-06-12 21:28:444068
4069 CreateSession();
4070
Ryan Hamilton9835e662018-08-02 05:36:274071 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:444072
4073 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4074 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364075 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:444076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4077
4078 // Pump the message loop to get the request started.
4079 base::RunLoop().RunUntilIdle();
4080 // Explicitly confirm the handshake.
4081 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524082 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:554083 quic_data.Resume();
rch30943ee2017-06-12 21:28:444084
4085 // Run the QUIC session to completion.
4086 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4087
4088 ExpectQuicAlternateProtocolMapping();
4089
4090 // Let the transaction proceed which will result in QUIC being marked
4091 // as broken and the request falling back to TCP.
4092 EXPECT_THAT(callback.WaitForResult(), IsOk());
4093
4094 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4095 ASSERT_FALSE(http_data.AllReadDataConsumed());
4096
4097 // Read the response body over TCP.
4098 CheckResponseData(&trans, "hello world");
4099 ExpectBrokenAlternateProtocolMapping();
4100 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4101 ASSERT_TRUE(http_data.AllReadDataConsumed());
4102}
4103
Ryan Hamilton6c2a2a82017-12-15 02:06:284104// Verify that when an origin has two alt-svc advertisements, one local and one
4105// remote, that when the local is broken the request will go over QUIC via
4106// the remote Alt-Svc.
4107// This is a regression test for crbug/825646.
4108TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Nick Harper72ade192019-07-17 03:30:424109 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:284110
4111 GURL origin1 = request_.url; // mail.example.org
4112 GURL origin2("https://www.example.org/");
4113 ASSERT_NE(origin1.host(), origin2.host());
4114
4115 scoped_refptr<X509Certificate> cert(
4116 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244117 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4118 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284119
4120 ProofVerifyDetailsChromium verify_details;
4121 verify_details.cert_verify_result.verified_cert = cert;
4122 verify_details.cert_verify_result.is_issued_by_known_root = true;
4123 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4124
Ryan Hamiltonabad59e2019-06-06 04:02:594125 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234126 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254127 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234128 mock_quic_data.AddWrite(SYNCHRONOUS,
4129 ConstructInitialSettingsPacket(packet_num++));
4130 }
Ryan Hamilton6c2a2a82017-12-15 02:06:284131 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234132 SYNCHRONOUS,
4133 ConstructClientRequestHeadersPacket(
4134 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4135 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434136 mock_quic_data.AddRead(
4137 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334138 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024139 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434140 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434141 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334142 ASYNC, ConstructServerDataPacket(
4143 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174144 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234145 mock_quic_data.AddWrite(SYNCHRONOUS,
4146 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284147 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4148 mock_quic_data.AddRead(ASYNC, 0); // EOF
4149
4150 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594151 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284152 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4153 AddHangingNonAlternateProtocolSocketData();
4154
4155 CreateSession();
4156
4157 // Set up alternative service for |origin1|.
4158 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4159 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4160 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4161 AlternativeServiceInfoVector alternative_services;
4162 alternative_services.push_back(
4163 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4164 local_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424165 session_->params().quic_params.supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284166 alternative_services.push_back(
4167 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4168 remote_alternative, expiration,
Nick Harper72ade192019-07-17 03:30:424169 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494170 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4171 NetworkIsolationKey(),
4172 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284173
Matt Menkeb32ba5122019-09-10 19:17:054174 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4175 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284176
4177 SendRequestAndExpectQuicResponse("hello!");
4178}
4179
Ryan Hamilton899c2e02019-11-14 01:22:024180// Verify that when multiple alternatives are broken,
4181// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
4182// This is a regression test for crbug/1024613.
4183TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
4184 base::HistogramTester histogram_tester;
4185
4186 MockRead http_reads[] = {
4187 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4188 MockRead("hello world"),
4189 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4190 MockRead(ASYNC, OK)};
4191
4192 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4193 socket_factory_.AddSocketDataProvider(&http_data);
4194 AddCertificate(&ssl_data_);
4195 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4196
4197 GURL origin1 = request_.url; // mail.example.org
4198
4199 scoped_refptr<X509Certificate> cert(
4200 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4201 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4202
4203 ProofVerifyDetailsChromium verify_details;
4204 verify_details.cert_verify_result.verified_cert = cert;
4205 verify_details.cert_verify_result.is_issued_by_known_root = true;
4206 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4207
4208 CreateSession();
4209
4210 // Set up alternative service for |origin1|.
4211 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4212 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4213 AlternativeServiceInfoVector alternative_services;
4214 alternative_services.push_back(
4215 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4216 local_alternative, expiration,
4217 session_->params().quic_params.supported_versions));
4218 alternative_services.push_back(
4219 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4220 local_alternative, expiration,
4221 session_->params().quic_params.supported_versions));
4222 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4223 NetworkIsolationKey(),
4224 alternative_services);
4225
4226 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4227 NetworkIsolationKey());
4228
4229 SendRequestAndExpectHttpResponse("hello world");
4230
4231 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4232 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4233}
4234
rch30943ee2017-06-12 21:28:444235// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4236// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054237// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444238// connection instead of going back to the broken QUIC connection.
4239// This is a regression tests for crbug/731303.
4240TEST_P(QuicNetworkTransactionTest,
4241 ResetPooledAfterHandshakeConfirmedThenBroken) {
Nick Harper72ade192019-07-17 03:30:424242 session_params_.quic_params.allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444243
4244 GURL origin1 = request_.url;
4245 GURL origin2("https://www.example.org/");
4246 ASSERT_NE(origin1.host(), origin2.host());
4247
Ryan Hamiltonabad59e2019-06-06 04:02:594248 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444249
4250 scoped_refptr<X509Certificate> cert(
4251 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244252 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4253 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444254
4255 ProofVerifyDetailsChromium verify_details;
4256 verify_details.cert_verify_result.verified_cert = cert;
4257 verify_details.cert_verify_result.is_issued_by_known_root = true;
4258 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4259
Renjie Tangaadb84b2019-08-31 01:00:234260 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254261 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234262 mock_quic_data.AddWrite(SYNCHRONOUS,
4263 ConstructInitialSettingsPacket(packet_num++));
4264 }
rch30943ee2017-06-12 21:28:444265 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434266 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234267 SYNCHRONOUS,
4268 ConstructClientRequestHeadersPacket(
4269 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4270 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434271 mock_quic_data.AddRead(
4272 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334273 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024274 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434275 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434276 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334277 ASYNC, ConstructServerDataPacket(
4278 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174279 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234280 mock_quic_data.AddWrite(SYNCHRONOUS,
4281 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444282
4283 // Second request will go over the pooled QUIC connection, but will be
4284 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054285 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224286 version_,
4287 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4288 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054289 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174290 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224291 version_,
4292 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4293 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434294 mock_quic_data.AddWrite(
4295 SYNCHRONOUS,
4296 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234297 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4298 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024299 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334300 mock_quic_data.AddRead(
4301 ASYNC, ConstructServerRstPacket(
4302 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4303 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444304 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4305 mock_quic_data.AddRead(ASYNC, 0); // EOF
4306
4307 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4308
4309 // After that fails, it will be resent via TCP.
4310 MockWrite http_writes[] = {
4311 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4312 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4313 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4314
4315 MockRead http_reads[] = {
4316 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4317 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4318 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014319 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444320 socket_factory_.AddSocketDataProvider(&http_data);
4321 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4322
Ryan Hamilton6c2a2a82017-12-15 02:06:284323 // Then the next request to the second origin will be sent over TCP.
4324 socket_factory_.AddSocketDataProvider(&http_data);
4325 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444326
4327 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564328 QuicStreamFactoryPeer::SetAlarmFactory(
4329 session_->quic_stream_factory(),
4330 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224331 context_.clock()));
rch30943ee2017-06-12 21:28:444332
4333 // Set up alternative service for |origin1|.
4334 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244335 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494336 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074337 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4338 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444339
4340 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244341 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494342 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074343 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4344 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344345
rch30943ee2017-06-12 21:28:444346 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524347 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444348 SendRequestAndExpectQuicResponse("hello!");
4349
4350 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524351 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054352 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444353 request_.url = origin2;
4354 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054355 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4356 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244357 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054358 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4359 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244360 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444361
Matt Menkeb32ba5122019-09-10 19:17:054362 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444363 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284364 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444365}
4366
bnc8be55ebb2015-10-30 14:12:074367TEST_P(QuicNetworkTransactionTest,
4368 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564369 std::string altsvc_header =
4370 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4371 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074372 MockRead http_reads[] = {
4373 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4374 MockRead("hello world"),
4375 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4376 MockRead(ASYNC, OK)};
4377
Ryan Sleevib8d7ea02018-05-07 20:01:014378 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074379 socket_factory_.AddSocketDataProvider(&http_data);
4380 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4381 socket_factory_.AddSocketDataProvider(&http_data);
4382 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4383
rch3f4b8452016-02-23 16:59:324384 CreateSession();
bnc8be55ebb2015-10-30 14:12:074385
4386 SendRequestAndExpectHttpResponse("hello world");
4387 SendRequestAndExpectHttpResponse("hello world");
4388}
4389
Xida Chen9bfe0b62018-04-24 19:52:214390// When multiple alternative services are advertised, HttpStreamFactory should
4391// select the alternative service which uses existing QUIC session if available.
4392// If no existing QUIC session can be used, use the first alternative service
4393// from the list.
zhongyi32569c62016-01-08 02:54:304394TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Nick Harper72ade192019-07-17 03:30:424395 session_params_.quic_params.allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524396 MockRead http_reads[] = {
4397 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294398 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524399 MockRead("hello world"),
4400 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4401 MockRead(ASYNC, OK)};
4402
Ryan Sleevib8d7ea02018-05-07 20:01:014403 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524404 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084405 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564406 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524407
zhongyi32569c62016-01-08 02:54:304408 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294409 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304410 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594411 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234412 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254413 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234414 mock_quic_data.AddWrite(SYNCHRONOUS,
4415 ConstructInitialSettingsPacket(packet_num++));
4416 }
rch5cb522462017-04-25 20:18:364417 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234418 SYNCHRONOUS,
4419 ConstructClientRequestHeadersPacket(
4420 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4421 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304422
4423 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294424 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4425 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434426 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024427 ASYNC, ConstructServerResponseHeadersPacket(
4428 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4429 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434430 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434431 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334432 ASYNC, ConstructServerDataPacket(
4433 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174434 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234435 mock_quic_data.AddWrite(SYNCHRONOUS,
4436 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304437
4438 // Second QUIC request data.
4439 // Connection pooling, using existing session, no need to include version
4440 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584441 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234442 SYNCHRONOUS,
4443 ConstructClientRequestHeadersPacket(
4444 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4445 true, GetRequestHeaders("GET", "https", "/"),
4446 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434447 mock_quic_data.AddRead(
4448 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334449 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024450 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434451 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334452 ASYNC, ConstructServerDataPacket(
4453 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174454 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434455 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234456 SYNCHRONOUS,
4457 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524458 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594459 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524460
4461 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4462
rtennetib8e80fb2016-05-16 00:12:094463 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324464 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564465 QuicStreamFactoryPeer::SetAlarmFactory(
4466 session_->quic_stream_factory(),
4467 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224468 context_.clock()));
bncc958faa2015-07-31 18:14:524469
4470 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304471
bnc359ed2a2016-04-29 20:43:454472 SendRequestAndExpectQuicResponse("hello!");
4473 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304474}
4475
tbansal6490783c2016-09-20 17:55:274476// Check that an existing QUIC connection to an alternative proxy server is
4477// used.
4478TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4479 base::HistogramTester histogram_tester;
4480
tbansal6490783c2016-09-20 17:55:274481 // First QUIC request data.
4482 // Open a session to foo.example.org:443 using the first entry of the
4483 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594484 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234485 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254486 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234487 mock_quic_data.AddWrite(SYNCHRONOUS,
4488 ConstructInitialSettingsPacket(packet_num++));
4489 }
rch5cb522462017-04-25 20:18:364490 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234491 SYNCHRONOUS,
4492 ConstructClientRequestHeadersPacket(
4493 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4494 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274495
4496 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434497 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024498 ASYNC, ConstructServerResponseHeadersPacket(
4499 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4500 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434501 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434502 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334503 ASYNC, ConstructServerDataPacket(
4504 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174505 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234506 mock_quic_data.AddWrite(SYNCHRONOUS,
4507 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274508
4509 // Second QUIC request data.
4510 // Connection pooling, using existing session, no need to include version
4511 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274512 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234513 SYNCHRONOUS,
4514 ConstructClientRequestHeadersPacket(
4515 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4516 true, GetRequestHeaders("GET", "http", "/"),
4517 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434518 mock_quic_data.AddRead(
4519 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334520 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024521 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434522 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334523 ASYNC, ConstructServerDataPacket(
4524 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174525 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434526 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234527 SYNCHRONOUS,
4528 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274529 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4530 mock_quic_data.AddRead(ASYNC, 0); // EOF
4531
4532 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4533
4534 AddHangingNonAlternateProtocolSocketData();
4535
4536 TestProxyDelegate test_proxy_delegate;
4537
Lily Houghton8c2f97d2018-01-22 05:06:594538 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494539 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274540
4541 test_proxy_delegate.set_alternative_proxy_server(
4542 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524543 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274544
4545 request_.url = GURL("http://mail.example.org/");
4546
4547 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564548 QuicStreamFactoryPeer::SetAlarmFactory(
4549 session_->quic_stream_factory(),
4550 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224551 context_.clock()));
tbansal6490783c2016-09-20 17:55:274552
4553 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4554 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4555 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4556 1);
4557
4558 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4559 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4560 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4561 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4562 1);
4563}
4564
Ryan Hamilton8d9ee76e2018-05-29 23:52:524565// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454566// even if alternative service destination is different.
4567TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Nick Harper72ade192019-07-17 03:30:424568 session_params_.quic_params.allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594569 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454570
Renjie Tangaadb84b2019-08-31 01:00:234571 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254572 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234573 mock_quic_data.AddWrite(SYNCHRONOUS,
4574 ConstructInitialSettingsPacket(packet_num++));
4575 }
bnc359ed2a2016-04-29 20:43:454576 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434577 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234578 SYNCHRONOUS,
4579 ConstructClientRequestHeadersPacket(
4580 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4581 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434582 mock_quic_data.AddRead(
4583 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334584 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024585 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434586 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434587 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334588 ASYNC, ConstructServerDataPacket(
4589 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174590 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234591 mock_quic_data.AddWrite(SYNCHRONOUS,
4592 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304593
bnc359ed2a2016-04-29 20:43:454594 // Second request.
alyssar2adf3ac2016-05-03 17:12:584595 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234596 SYNCHRONOUS,
4597 ConstructClientRequestHeadersPacket(
4598 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4599 true, GetRequestHeaders("GET", "https", "/"),
4600 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434601 mock_quic_data.AddRead(
4602 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334603 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024604 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434605 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334606 ASYNC, ConstructServerDataPacket(
4607 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174608 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434609 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234610 SYNCHRONOUS,
4611 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304612 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4613 mock_quic_data.AddRead(ASYNC, 0); // EOF
4614
4615 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454616
4617 AddHangingNonAlternateProtocolSocketData();
4618 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304619
rch3f4b8452016-02-23 16:59:324620 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564621 QuicStreamFactoryPeer::SetAlarmFactory(
4622 session_->quic_stream_factory(),
4623 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224624 context_.clock()));
zhongyi32569c62016-01-08 02:54:304625
bnc359ed2a2016-04-29 20:43:454626 const char destination1[] = "first.example.com";
4627 const char destination2[] = "second.example.com";
4628
4629 // Set up alternative service entry to destination1.
4630 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214631 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454632 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494633 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074634 server, NetworkIsolationKey(), alternative_service, expiration,
4635 supported_versions_);
bnc359ed2a2016-04-29 20:43:454636 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524637 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454638 SendRequestAndExpectQuicResponse("hello!");
4639
4640 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214641 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494642 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074643 server, NetworkIsolationKey(), alternative_service, expiration,
4644 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524645 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454646 // even though alternative service destination is different.
4647 SendRequestAndExpectQuicResponse("hello!");
4648}
4649
4650// Pool to existing session with matching destination and matching certificate
4651// even if origin is different, and even if the alternative service with
4652// matching destination is not the first one on the list.
4653TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Nick Harper72ade192019-07-17 03:30:424654 session_params_.quic_params.allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454655 GURL origin1 = request_.url;
4656 GURL origin2("https://www.example.org/");
4657 ASSERT_NE(origin1.host(), origin2.host());
4658
Ryan Hamiltonabad59e2019-06-06 04:02:594659 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454660
Renjie Tangaadb84b2019-08-31 01:00:234661 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254662 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234663 mock_quic_data.AddWrite(SYNCHRONOUS,
4664 ConstructInitialSettingsPacket(packet_num++));
4665 }
bnc359ed2a2016-04-29 20:43:454666 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434667 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234668 SYNCHRONOUS,
4669 ConstructClientRequestHeadersPacket(
4670 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4671 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434672 mock_quic_data.AddRead(
4673 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334674 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024675 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434676 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434677 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334678 ASYNC, ConstructServerDataPacket(
4679 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174680 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234681 mock_quic_data.AddWrite(SYNCHRONOUS,
4682 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454683
4684 // Second request.
Yixin Wang079ad542018-01-11 04:06:054685 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224686 version_,
4687 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4688 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054689 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174690 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224691 version_,
4692 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4693 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584694 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434695 SYNCHRONOUS,
4696 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234697 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4698 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024699 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434700 mock_quic_data.AddRead(
4701 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334702 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024703 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434704 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334705 ASYNC, ConstructServerDataPacket(
4706 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174707 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434708 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234709 SYNCHRONOUS,
4710 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454711 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4712 mock_quic_data.AddRead(ASYNC, 0); // EOF
4713
4714 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4715
4716 AddHangingNonAlternateProtocolSocketData();
4717 AddHangingNonAlternateProtocolSocketData();
4718
4719 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564720 QuicStreamFactoryPeer::SetAlarmFactory(
4721 session_->quic_stream_factory(),
4722 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224723 context_.clock()));
bnc359ed2a2016-04-29 20:43:454724
4725 const char destination1[] = "first.example.com";
4726 const char destination2[] = "second.example.com";
4727
4728 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214729 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454730 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494731 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074732 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4733 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454734
4735 // Set up multiple alternative service entries for |origin2|,
4736 // the first one with a different destination as for |origin1|,
4737 // the second one with the same. The second one should be used,
4738 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214739 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454740 AlternativeServiceInfoVector alternative_services;
4741 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214742 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4743 alternative_service2, expiration,
Nick Harper72ade192019-07-17 03:30:424744 session_->params().quic_params.supported_versions));
bnc359ed2a2016-04-29 20:43:454745 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214746 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4747 alternative_service1, expiration,
Nick Harper72ade192019-07-17 03:30:424748 session_->params().quic_params.supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494749 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4750 NetworkIsolationKey(),
4751 alternative_services);
bnc359ed2a2016-04-29 20:43:454752 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524753 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454754 SendRequestAndExpectQuicResponse("hello!");
4755
4756 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524757 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454758 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584759
bnc359ed2a2016-04-29 20:43:454760 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304761}
4762
4763// Multiple origins have listed the same alternative services. When there's a
4764// existing QUIC session opened by a request to other origin,
4765// if the cert is valid, should select this QUIC session to make the request
4766// if this is also the first existing QUIC session.
4767TEST_P(QuicNetworkTransactionTest,
4768 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Nick Harper72ade192019-07-17 03:30:424769 session_params_.quic_params.allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294770 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304771
rch9ae5b3b2016-02-11 00:36:294772 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304773 MockRead http_reads[] = {
4774 MockRead("HTTP/1.1 200 OK\r\n"),
4775 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294776 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304777 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4778 MockRead(ASYNC, OK)};
4779
Ryan Sleevib8d7ea02018-05-07 20:01:014780 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304781 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084782 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304783 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4784
4785 // HTTP data for request to mail.example.org.
4786 MockRead http_reads2[] = {
4787 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294788 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304789 MockRead("hello world from mail.example.org"),
4790 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4791 MockRead(ASYNC, OK)};
4792
Ryan Sleevib8d7ea02018-05-07 20:01:014793 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304794 socket_factory_.AddSocketDataProvider(&http_data2);
4795 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4796
Yixin Wang079ad542018-01-11 04:06:054797 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224798 version_,
4799 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4800 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054801 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584802 server_maker_.set_hostname("www.example.org");
4803 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594804 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234805 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254806 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234807 mock_quic_data.AddWrite(SYNCHRONOUS,
4808 ConstructInitialSettingsPacket(packet_num++));
4809 }
zhongyi32569c62016-01-08 02:54:304810 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584811 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234812 SYNCHRONOUS,
4813 ConstructClientRequestHeadersPacket(
4814 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4815 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434816
4817 mock_quic_data.AddRead(
4818 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334819 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024820 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434821 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334822 mock_quic_data.AddRead(
4823 ASYNC, ConstructServerDataPacket(
4824 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174825 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234826 mock_quic_data.AddWrite(SYNCHRONOUS,
4827 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434828 // Second QUIC request data.
4829 mock_quic_data.AddWrite(
4830 SYNCHRONOUS,
4831 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234832 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4833 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024834 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434835 mock_quic_data.AddRead(
4836 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334837 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024838 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334839 mock_quic_data.AddRead(
4840 ASYNC, ConstructServerDataPacket(
4841 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174842 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434843 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234844 SYNCHRONOUS,
4845 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304846 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4847 mock_quic_data.AddRead(ASYNC, 0); // EOF
4848
4849 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304850
rtennetib8e80fb2016-05-16 00:12:094851 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324852 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564853 QuicStreamFactoryPeer::SetAlarmFactory(
4854 session_->quic_stream_factory(),
4855 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224856 context_.clock()));
zhongyi32569c62016-01-08 02:54:304857
4858 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294859 request_.url = GURL("https://www.example.org/");
4860 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304861 request_.url = GURL("https://mail.example.org/");
4862 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4863
rch9ae5b3b2016-02-11 00:36:294864 // Open a QUIC session to mail.example.org:443 when making request
4865 // to mail.example.org.
4866 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454867 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304868
rch9ae5b3b2016-02-11 00:36:294869 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304870 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454871 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524872}
4873
4874TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524875 MockRead http_reads[] = {
4876 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564877 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524878 MockRead("hello world"),
4879 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4880 MockRead(ASYNC, OK)};
4881
Ryan Sleevib8d7ea02018-05-07 20:01:014882 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524883 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084884 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564885 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524886
rtennetib8e80fb2016-05-16 00:12:094887 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324888 CreateSession();
bncc958faa2015-07-31 18:14:524889
4890 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454891
4892 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344893 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494894 http_server_properties_->GetAlternativeServiceInfos(
4895 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344896 ASSERT_EQ(1u, alternative_service_info_vector.size());
4897 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544898 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344899 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4900 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4901 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524902}
4903
4904TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524905 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564906 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4907 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524908 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4909 MockRead(ASYNC, OK)};
4910
Ryan Sleevib8d7ea02018-05-07 20:01:014911 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524912 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084913 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564914 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524915
Ryan Hamiltonabad59e2019-06-06 04:02:594916 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234917 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254918 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234919 mock_quic_data.AddWrite(SYNCHRONOUS,
4920 ConstructInitialSettingsPacket(packet_num++));
4921 }
rch5cb522462017-04-25 20:18:364922 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234923 SYNCHRONOUS,
4924 ConstructClientRequestHeadersPacket(
4925 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4926 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434927 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334928 ASYNC, ConstructServerResponseHeadersPacket(
4929 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4930 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434931 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334932 mock_quic_data.AddRead(
4933 ASYNC, ConstructServerDataPacket(
4934 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174935 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234936 mock_quic_data.AddWrite(SYNCHRONOUS,
4937 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524938 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4939 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524940
4941 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4942
rtennetib8e80fb2016-05-16 00:12:094943 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324944 CreateSession();
bncc958faa2015-07-31 18:14:524945
bnc3472afd2016-11-17 15:27:214946 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524947 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494948 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054949 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494950 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054951 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524952
4953 SendRequestAndExpectHttpResponse("hello world");
4954 SendRequestAndExpectQuicResponse("hello!");
4955
mmenkee24011922015-12-17 22:12:594956 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524957
Matt Menke3233d8f22019-08-20 21:01:494958 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054959 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444960 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4961 url::SchemeHostPort("https", request_.url.host(), 443),
4962 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524963}
4964
Matt Menkeb32ba5122019-09-10 19:17:054965TEST_P(QuicNetworkTransactionTest,
4966 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4967 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4968 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4969 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4970 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4971
4972 base::test::ScopedFeatureList feature_list;
4973 feature_list.InitWithFeatures(
4974 // enabled_features
4975 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4976 features::kPartitionConnectionsByNetworkIsolationKey},
4977 // disabled_features
4978 {});
4979 // Since HttpServerProperties caches the feature value, have to create a new
4980 // one.
4981 http_server_properties_ = std::make_unique<HttpServerProperties>();
4982
4983 MockRead http_reads[] = {
4984 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4985 MockRead("hello world"),
4986 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4987 MockRead(ASYNC, OK)};
4988
4989 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4990 socket_factory_.AddSocketDataProvider(&http_data);
4991 AddCertificate(&ssl_data_);
4992 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4993
4994 MockQuicData mock_quic_data(version_);
4995 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254996 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:054997 mock_quic_data.AddWrite(SYNCHRONOUS,
4998 ConstructInitialSettingsPacket(packet_num++));
4999 }
5000 mock_quic_data.AddWrite(
5001 SYNCHRONOUS,
5002 ConstructClientRequestHeadersPacket(
5003 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5004 true, GetRequestHeaders("GET", "https", "/")));
5005 mock_quic_data.AddRead(
5006 ASYNC, ConstructServerResponseHeadersPacket(
5007 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5008 GetResponseHeaders("200 OK")));
5009 std::string header = ConstructDataHeader(6);
5010 mock_quic_data.AddRead(
5011 ASYNC, ConstructServerDataPacket(
5012 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5013 header + "hello!"));
5014 mock_quic_data.AddWrite(SYNCHRONOUS,
5015 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5016 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5017 mock_quic_data.AddRead(ASYNC, 0); // EOF
5018
5019 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5020
5021 CreateSession();
5022
5023 AlternativeService alternative_service(kProtoQUIC,
5024 HostPortPair::FromURL(request_.url));
5025 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5026 alternative_service, kNetworkIsolationKey1);
5027 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5028 alternative_service, kNetworkIsolationKey2);
5029 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5030 alternative_service, kNetworkIsolationKey1));
5031 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5032 alternative_service, kNetworkIsolationKey2));
5033
5034 request_.network_isolation_key = kNetworkIsolationKey1;
5035 SendRequestAndExpectHttpResponse("hello world");
5036 SendRequestAndExpectQuicResponse("hello!");
5037
5038 mock_quic_data.Resume();
5039
5040 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5041 alternative_service, kNetworkIsolationKey1));
5042 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
5043 url::SchemeHostPort("https", request_.url.host(), 443),
5044 kNetworkIsolationKey1));
5045 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5046 alternative_service, kNetworkIsolationKey2));
5047 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5048 url::SchemeHostPort("https", request_.url.host(), 443),
5049 kNetworkIsolationKey2));
5050}
5051
bncc958faa2015-07-31 18:14:525052TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:525053 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565054 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5055 MockRead("hello world"),
bncc958faa2015-07-31 18:14:525056 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5057 MockRead(ASYNC, OK)};
5058
Ryan Sleevib8d7ea02018-05-07 20:01:015059 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:525060 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565061 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:525062
Ryan Hamiltonabad59e2019-06-06 04:02:595063 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235064 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255065 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235066 mock_quic_data.AddWrite(SYNCHRONOUS,
5067 ConstructInitialSettingsPacket(packet_num++));
5068 }
rch5cb522462017-04-25 20:18:365069 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235070 SYNCHRONOUS,
5071 ConstructClientRequestHeadersPacket(
5072 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5073 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435074 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335075 ASYNC, ConstructServerResponseHeadersPacket(
5076 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5077 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435078 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335079 mock_quic_data.AddRead(
5080 ASYNC, ConstructServerDataPacket(
5081 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175082 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235083 mock_quic_data.AddWrite(SYNCHRONOUS,
5084 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:525085 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
5086
5087 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5088
5089 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325090 CreateSession();
bncc958faa2015-07-31 18:14:525091
5092 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
5093 SendRequestAndExpectHttpResponse("hello world");
5094}
5095
tbansalc3308d72016-08-27 10:25:045096// Tests that the connection to an HTTPS proxy is raced with an available
5097// alternative proxy server.
5098TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:275099 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595100 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495101 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045102
Ryan Hamiltonabad59e2019-06-06 04:02:595103 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235104 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255105 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235106 mock_quic_data.AddWrite(SYNCHRONOUS,
5107 ConstructInitialSettingsPacket(packet_num++));
5108 }
rch5cb522462017-04-25 20:18:365109 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235110 SYNCHRONOUS,
5111 ConstructClientRequestHeadersPacket(
5112 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5113 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435114 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335115 ASYNC, ConstructServerResponseHeadersPacket(
5116 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5117 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435118 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335119 mock_quic_data.AddRead(
5120 ASYNC, ConstructServerDataPacket(
5121 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175122 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235123 mock_quic_data.AddWrite(SYNCHRONOUS,
5124 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:045125 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5126 mock_quic_data.AddRead(ASYNC, 0); // EOF
5127
5128 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5129
5130 // There is no need to set up main job, because no attempt will be made to
5131 // speak to the proxy over TCP.
5132 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:045133 TestProxyDelegate test_proxy_delegate;
5134 const HostPortPair host_port_pair("mail.example.org", 443);
5135
5136 test_proxy_delegate.set_alternative_proxy_server(
5137 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525138 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045139 CreateSession();
5140 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5141
5142 // The main job needs to hang in order to guarantee that the alternative
5143 // proxy server job will "win".
5144 AddHangingNonAlternateProtocolSocketData();
5145
5146 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
5147
5148 // Verify that the alternative proxy server is not marked as broken.
5149 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5150
5151 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595152 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275153
5154 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5155 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5156 1);
tbansalc3308d72016-08-27 10:25:045157}
5158
bnc1c196c6e2016-05-28 13:51:485159TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:305160 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275161 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:305162
5163 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:565164 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:295165 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565166 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:305167
5168 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565169 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485170 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565171 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:305172
Ryan Sleevib8d7ea02018-05-07 20:01:015173 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505174 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:085175 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:505176 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305177
5178 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:455179 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:305180 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:455181 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:305182 };
Ryan Sleevib8d7ea02018-05-07 20:01:015183 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:505184 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:305185
5186 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:015187 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505188 socket_factory_.AddSocketDataProvider(&http_data2);
5189 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305190
bnc912a04b2016-04-20 14:19:505191 CreateSession();
[email protected]dda75ab2013-06-22 22:43:305192
5193 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:305194 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:175195 ASSERT_TRUE(http_data.AllReadDataConsumed());
5196 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305197
5198 // Now run the second request in which the QUIC socket hangs,
5199 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:305200 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455201 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305202
rch37de576c2015-05-17 20:28:175203 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5204 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455205 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305206}
5207
[email protected]1e960032013-12-20 19:00:205208TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435209 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5210 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5211 return;
5212 }
5213
Ryan Hamiltonabad59e2019-06-06 04:02:595214 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035215 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495216 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255217 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495218 mock_quic_data.AddWrite(SYNCHRONOUS,
5219 ConstructInitialSettingsPacket(packet_num++));
5220 }
Zhongyi Shi32f2fd02018-04-16 18:23:435221 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495222 SYNCHRONOUS,
5223 ConstructClientRequestHeadersPacket(
5224 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5225 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435226 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335227 ASYNC, ConstructServerResponseHeadersPacket(
5228 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5229 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435230 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335231 mock_quic_data.AddRead(
5232 ASYNC, ConstructServerDataPacket(
5233 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175234 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495235 mock_quic_data.AddWrite(SYNCHRONOUS,
5236 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505237 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595238 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485239
rcha5399e02015-04-21 19:32:045240 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485241
rtennetib8e80fb2016-05-16 00:12:095242 // The non-alternate protocol job needs to hang in order to guarantee that
5243 // the alternate-protocol job will "win".
5244 AddHangingNonAlternateProtocolSocketData();
5245
rch3f4b8452016-02-23 16:59:325246 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275247 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195248 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305249
Matt Menke19475f72019-08-21 18:57:445250 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5251 url::SchemeHostPort("https", request_.url.host(), 443),
5252 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485253}
5254
[email protected]1e960032013-12-20 19:00:205255TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435256 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5257 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5258 return;
5259 }
5260
Ryan Hamiltonabad59e2019-06-06 04:02:595261 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035262 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495263 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255264 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495265 mock_quic_data.AddWrite(
5266 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5267 }
Fan Yang32c5a112018-12-10 20:06:335268 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495269 SYNCHRONOUS,
5270 ConstructClientRequestHeadersPacket(
5271 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5272 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435273 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335274 ASYNC, ConstructServerResponseHeadersPacket(
5275 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5276 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435277 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335278 mock_quic_data.AddRead(
5279 ASYNC, ConstructServerDataPacket(
5280 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175281 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495282 mock_quic_data.AddWrite(SYNCHRONOUS,
5283 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505284 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595285 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045286 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275287
5288 // In order for a new QUIC session to be established via alternate-protocol
5289 // without racing an HTTP connection, we need the host resolution to happen
5290 // synchronously.
5291 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295292 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565293 "");
[email protected]3a120a6b2013-06-25 01:08:275294
rtennetib8e80fb2016-05-16 00:12:095295 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325296 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275297 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275298 SendRequestAndExpectQuicResponse("hello!");
5299}
5300
[email protected]0fc924b2014-03-31 04:34:155301TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495302 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5303 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155304
5305 // Since we are using a proxy, the QUIC job will not succeed.
5306 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295307 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5308 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565309 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155310
5311 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565312 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485313 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565314 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155315
Ryan Sleevib8d7ea02018-05-07 20:01:015316 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155317 socket_factory_.AddSocketDataProvider(&http_data);
5318
5319 // In order for a new QUIC session to be established via alternate-protocol
5320 // without racing an HTTP connection, we need the host resolution to happen
5321 // synchronously.
5322 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295323 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565324 "");
[email protected]0fc924b2014-03-31 04:34:155325
rch9ae5b3b2016-02-11 00:36:295326 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325327 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275328 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155329 SendRequestAndExpectHttpResponse("hello world");
5330}
5331
[email protected]1e960032013-12-20 19:00:205332TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435333 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5334 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5335 return;
5336 }
5337
Ryan Hamiltonabad59e2019-06-06 04:02:595338 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235339 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495340 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255341 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235342 mock_quic_data.AddWrite(SYNCHRONOUS,
5343 ConstructInitialSettingsPacket(packet_num++));
5344 }
Nick Harper057264a82019-09-12 23:33:495345 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365346 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235347 SYNCHRONOUS,
5348 ConstructClientRequestHeadersPacket(
5349 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5350 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435351 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335352 ASYNC, ConstructServerResponseHeadersPacket(
5353 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5354 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435355 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335356 mock_quic_data.AddRead(
5357 ASYNC, ConstructServerDataPacket(
5358 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175359 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235360 mock_quic_data.AddWrite(SYNCHRONOUS,
5361 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595362 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045363 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125364
rtennetib8e80fb2016-05-16 00:12:095365 // The non-alternate protocol job needs to hang in order to guarantee that
5366 // the alternate-protocol job will "win".
5367 AddHangingNonAlternateProtocolSocketData();
5368
[email protected]11c05872013-08-20 02:04:125369 // In order for a new QUIC session to be established via alternate-protocol
5370 // without racing an HTTP connection, we need the host resolution to happen
5371 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5372 // connection to the the server, in this test we require confirmation
5373 // before encrypting so the HTTP job will still start.
5374 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295375 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565376 "");
[email protected]11c05872013-08-20 02:04:125377
rch3f4b8452016-02-23 16:59:325378 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435379 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5380 false);
Ryan Hamilton9835e662018-08-02 05:36:275381 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125382
bnc691fda62016-08-12 00:43:165383 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125384 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365385 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015386 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125387
5388 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525389 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015390 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505391
bnc691fda62016-08-12 00:43:165392 CheckWasQuicResponse(&trans);
5393 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125394}
5395
Steven Valdez58097ec32018-07-16 18:29:045396TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435397 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5398 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5399 return;
5400 }
5401
Ryan Hamilton3cc2c152019-07-09 19:36:015402 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595403 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035404 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255405 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495406 mock_quic_data.AddWrite(
5407 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5408 }
Steven Valdez58097ec32018-07-16 18:29:045409 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015410 SYNCHRONOUS,
5411 ConstructClientRequestHeadersPacket(
5412 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5413 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335414 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025415 ASYNC, ConstructServerResponseHeadersPacket(
5416 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5417 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015418 mock_quic_data.AddWrite(
5419 SYNCHRONOUS,
5420 ConstructClientAckAndRstPacket(
5421 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5422 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045423
5424 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5425
Steven Valdez58097ec32018-07-16 18:29:045426 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015427 SYNCHRONOUS,
5428 ConstructClientRequestHeadersPacket(
5429 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5430 true, GetRequestHeaders("GET", "https", "/"),
5431 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045432 mock_quic_data.AddRead(
5433 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335434 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025435 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435436 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045437 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335438 ASYNC, ConstructServerDataPacket(
5439 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175440 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045441 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015442 SYNCHRONOUS,
5443 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045444 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5445 mock_quic_data.AddRead(ASYNC, 0); // EOF
5446
5447 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5448
5449 // In order for a new QUIC session to be established via alternate-protocol
5450 // without racing an HTTP connection, we need the host resolution to happen
5451 // synchronously.
5452 host_resolver_.set_synchronous_mode(true);
5453 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5454 "");
Steven Valdez58097ec32018-07-16 18:29:045455
5456 AddHangingNonAlternateProtocolSocketData();
5457 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275458 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565459 QuicStreamFactoryPeer::SetAlarmFactory(
5460 session_->quic_stream_factory(),
5461 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225462 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045463
5464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5465 TestCompletionCallback callback;
5466 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5468
5469 // Confirm the handshake after the 425 Too Early.
5470 base::RunLoop().RunUntilIdle();
5471
5472 // The handshake hasn't been confirmed yet, so the retry should not have
5473 // succeeded.
5474 EXPECT_FALSE(callback.have_result());
5475
5476 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5477 quic::QuicSession::HANDSHAKE_CONFIRMED);
5478
5479 EXPECT_THAT(callback.WaitForResult(), IsOk());
5480 CheckWasQuicResponse(&trans);
5481 CheckResponseData(&trans, "hello!");
5482}
5483
5484TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435485 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5486 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5487 return;
5488 }
5489
Ryan Hamilton3cc2c152019-07-09 19:36:015490 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595491 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035492 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255493 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495494 mock_quic_data.AddWrite(
5495 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5496 }
Steven Valdez58097ec32018-07-16 18:29:045497 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015498 SYNCHRONOUS,
5499 ConstructClientRequestHeadersPacket(
5500 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5501 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335502 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025503 ASYNC, ConstructServerResponseHeadersPacket(
5504 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5505 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015506 mock_quic_data.AddWrite(
5507 SYNCHRONOUS,
5508 ConstructClientAckAndRstPacket(
5509 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5510 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045511
5512 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5513
Steven Valdez58097ec32018-07-16 18:29:045514 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015515 SYNCHRONOUS,
5516 ConstructClientRequestHeadersPacket(
5517 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5518 true, GetRequestHeaders("GET", "https", "/"),
5519 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335520 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025521 ASYNC, ConstructServerResponseHeadersPacket(
5522 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5523 GetResponseHeaders("425 TOO_EARLY")));
Ryan Hamilton3cc2c152019-07-09 19:36:015524 mock_quic_data.AddWrite(
5525 SYNCHRONOUS,
5526 ConstructClientAckAndRstPacket(
5527 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5528 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045529 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5530 mock_quic_data.AddRead(ASYNC, 0); // EOF
5531
5532 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5533
5534 // In order for a new QUIC session to be established via alternate-protocol
5535 // without racing an HTTP connection, we need the host resolution to happen
5536 // synchronously.
5537 host_resolver_.set_synchronous_mode(true);
5538 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5539 "");
Steven Valdez58097ec32018-07-16 18:29:045540
5541 AddHangingNonAlternateProtocolSocketData();
5542 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275543 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565544 QuicStreamFactoryPeer::SetAlarmFactory(
5545 session_->quic_stream_factory(),
5546 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225547 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045548
5549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5550 TestCompletionCallback callback;
5551 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5553
5554 // Confirm the handshake after the 425 Too Early.
5555 base::RunLoop().RunUntilIdle();
5556
5557 // The handshake hasn't been confirmed yet, so the retry should not have
5558 // succeeded.
5559 EXPECT_FALSE(callback.have_result());
5560
5561 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5562 quic::QuicSession::HANDSHAKE_CONFIRMED);
5563
5564 EXPECT_THAT(callback.WaitForResult(), IsOk());
5565 const HttpResponseInfo* response = trans.GetResponseInfo();
5566 ASSERT_TRUE(response != nullptr);
5567 ASSERT_TRUE(response->headers.get() != nullptr);
5568 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5569 EXPECT_TRUE(response->was_fetched_via_spdy);
5570 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085571 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5572 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045573}
5574
zhongyica364fbb2015-12-12 03:39:125575TEST_P(QuicNetworkTransactionTest,
5576 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435577 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5578 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5579 return;
5580 }
5581
Nick Harper72ade192019-07-17 03:30:425582 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595583 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235584 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495585 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255586 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235587 mock_quic_data.AddWrite(SYNCHRONOUS,
5588 ConstructInitialSettingsPacket(packet_num++));
5589 }
Nick Harper057264a82019-09-12 23:33:495590 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365591 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235592 SYNCHRONOUS,
5593 ConstructClientRequestHeadersPacket(
5594 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5595 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125596 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525597 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435598 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125599 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5600
5601 // The non-alternate protocol job needs to hang in order to guarantee that
5602 // the alternate-protocol job will "win".
5603 AddHangingNonAlternateProtocolSocketData();
5604
5605 // In order for a new QUIC session to be established via alternate-protocol
5606 // without racing an HTTP connection, we need the host resolution to happen
5607 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5608 // connection to the the server, in this test we require confirmation
5609 // before encrypting so the HTTP job will still start.
5610 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295611 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125612 "");
zhongyica364fbb2015-12-12 03:39:125613
rch3f4b8452016-02-23 16:59:325614 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435615 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5616 false);
Ryan Hamilton9835e662018-08-02 05:36:275617 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125618
bnc691fda62016-08-12 00:43:165619 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125620 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365621 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015622 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125623
5624 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525625 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015626 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125627
5628 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525629 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125630
bnc691fda62016-08-12 00:43:165631 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125632 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525633 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5634 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125635}
5636
5637TEST_P(QuicNetworkTransactionTest,
5638 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435639 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5640 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5641 return;
5642 }
5643
Nick Harper72ade192019-07-17 03:30:425644 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595645 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235646 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495647 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255648 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235649 mock_quic_data.AddWrite(SYNCHRONOUS,
5650 ConstructInitialSettingsPacket(packet_num++));
5651 }
Nick Harper057264a82019-09-12 23:33:495652 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365653 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235654 SYNCHRONOUS,
5655 ConstructClientRequestHeadersPacket(
5656 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5657 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215658 // Peer sending data from an non-existing stream causes this end to raise
5659 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335660 mock_quic_data.AddRead(
5661 ASYNC, ConstructServerRstPacket(
5662 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5663 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215664 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375665 mock_quic_data.AddWrite(
5666 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5667 packet_num++, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5668 quic::QUIC_INVALID_STREAM_ID, quic_error_details,
5669 quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125670 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5671
5672 // The non-alternate protocol job needs to hang in order to guarantee that
5673 // the alternate-protocol job will "win".
5674 AddHangingNonAlternateProtocolSocketData();
5675
5676 // In order for a new QUIC session to be established via alternate-protocol
5677 // without racing an HTTP connection, we need the host resolution to happen
5678 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5679 // connection to the the server, in this test we require confirmation
5680 // before encrypting so the HTTP job will still start.
5681 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295682 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125683 "");
zhongyica364fbb2015-12-12 03:39:125684
rch3f4b8452016-02-23 16:59:325685 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435686 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5687 false);
Ryan Hamilton9835e662018-08-02 05:36:275688 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125689
bnc691fda62016-08-12 00:43:165690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125691 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365692 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125694
5695 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525696 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015697 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125698 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525699 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125700
bnc691fda62016-08-12 00:43:165701 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525702 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125703}
5704
Nick Harper057264a82019-09-12 23:33:495705TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435706 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5707 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5708 return;
5709 }
5710
Ryan Hamiltonabad59e2019-06-06 04:02:595711 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235712 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495713 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255714 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235715 mock_quic_data.AddWrite(SYNCHRONOUS,
5716 ConstructInitialSettingsPacket(packet_num++));
5717 }
Nick Harper057264a82019-09-12 23:33:495718 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365719 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235720 SYNCHRONOUS,
5721 ConstructClientRequestHeadersPacket(
5722 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5723 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485724 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335725 mock_quic_data.AddRead(
5726 ASYNC, ConstructServerResponseHeadersPacket(
5727 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5728 GetResponseHeaders("200 OK")));
5729 mock_quic_data.AddRead(
5730 ASYNC, ConstructServerRstPacket(
5731 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5732 quic::QUIC_STREAM_CANCELLED));
Renjie Tangaadb84b2019-08-31 01:00:235733 mock_quic_data.AddWrite(SYNCHRONOUS,
5734 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485735 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5736 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5737
5738 // The non-alternate protocol job needs to hang in order to guarantee that
5739 // the alternate-protocol job will "win".
5740 AddHangingNonAlternateProtocolSocketData();
5741
5742 // In order for a new QUIC session to be established via alternate-protocol
5743 // without racing an HTTP connection, we need the host resolution to happen
5744 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5745 // connection to the the server, in this test we require confirmation
5746 // before encrypting so the HTTP job will still start.
5747 host_resolver_.set_synchronous_mode(true);
5748 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5749 "");
rchcd5f1c62016-06-23 02:43:485750
5751 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435752 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5753 false);
Ryan Hamilton9835e662018-08-02 05:36:275754 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485755
bnc691fda62016-08-12 00:43:165756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485757 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365758 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485760
5761 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525762 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485763 // Read the headers.
robpercival214763f2016-07-01 23:27:015764 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485765
bnc691fda62016-08-12 00:43:165766 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485767 ASSERT_TRUE(response != nullptr);
5768 ASSERT_TRUE(response->headers.get() != nullptr);
5769 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5770 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525771 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085772 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5773 response->connection_info);
rchcd5f1c62016-06-23 02:43:485774
5775 std::string response_data;
bnc691fda62016-08-12 00:43:165776 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485777}
5778
Nick Harper057264a82019-09-12 23:33:495779TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435780 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5781 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5782 return;
5783 }
5784
Nick Harper72ade192019-07-17 03:30:425785 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595786 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235787 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495788 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255789 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235790 mock_quic_data.AddWrite(SYNCHRONOUS,
5791 ConstructInitialSettingsPacket(packet_num++));
5792 }
Nick Harper057264a82019-09-12 23:33:495793 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365794 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235795 SYNCHRONOUS,
5796 ConstructClientRequestHeadersPacket(
5797 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5798 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335799 mock_quic_data.AddRead(
5800 ASYNC, ConstructServerRstPacket(
5801 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5802 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485803 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5804 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5805
5806 // The non-alternate protocol job needs to hang in order to guarantee that
5807 // the alternate-protocol job will "win".
5808 AddHangingNonAlternateProtocolSocketData();
5809
5810 // In order for a new QUIC session to be established via alternate-protocol
5811 // without racing an HTTP connection, we need the host resolution to happen
5812 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5813 // connection to the the server, in this test we require confirmation
5814 // before encrypting so the HTTP job will still start.
5815 host_resolver_.set_synchronous_mode(true);
5816 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5817 "");
rchcd5f1c62016-06-23 02:43:485818
5819 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435820 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5821 false);
Ryan Hamilton9835e662018-08-02 05:36:275822 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485823
bnc691fda62016-08-12 00:43:165824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485825 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365826 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485828
5829 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525830 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485831 // Read the headers.
robpercival214763f2016-07-01 23:27:015832 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485833}
5834
[email protected]1e960032013-12-20 19:00:205835TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305836 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525837 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585838 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305839 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505840 MockRead(ASYNC, close->data(), close->length()),
5841 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5842 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305843 };
Ryan Sleevib8d7ea02018-05-07 20:01:015844 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305845 socket_factory_.AddSocketDataProvider(&quic_data);
5846
5847 // Main job which will succeed even though the alternate job fails.
5848 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025849 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5850 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5851 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305852
Ryan Sleevib8d7ea02018-05-07 20:01:015853 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305854 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565855 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305856
rch3f4b8452016-02-23 16:59:325857 CreateSession();
David Schinazic8281052019-01-24 06:14:175858 AddQuicAlternateProtocolMapping(
5859 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195860 SendRequestAndExpectHttpResponse("hello from http");
5861 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305862}
5863
Matt Menkeb32ba5122019-09-10 19:17:055864TEST_P(QuicNetworkTransactionTest,
5865 BrokenAlternateProtocolWithNetworkIsolationKey) {
5866 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5867 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5868 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5869 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5870
5871 base::test::ScopedFeatureList feature_list;
5872 feature_list.InitWithFeatures(
5873 // enabled_features
5874 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5875 features::kPartitionConnectionsByNetworkIsolationKey},
5876 // disabled_features
5877 {});
5878 // Since HttpServerProperties caches the feature value, have to create a new
5879 // one.
5880 http_server_properties_ = std::make_unique<HttpServerProperties>();
5881
5882 // Alternate-protocol job
5883 std::unique_ptr<quic::QuicEncryptedPacket> close(
5884 ConstructServerConnectionClosePacket(1));
5885 MockRead quic_reads[] = {
5886 MockRead(ASYNC, close->data(), close->length()),
5887 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5888 MockRead(ASYNC, OK), // EOF
5889 };
5890 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5891 socket_factory_.AddSocketDataProvider(&quic_data);
5892
5893 // Main job which will succeed even though the alternate job fails.
5894 MockRead http_reads[] = {
5895 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5897 MockRead(ASYNC, OK)};
5898
5899 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5900 socket_factory_.AddSocketDataProvider(&http_data);
5901 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5902
5903 CreateSession();
5904 AddQuicAlternateProtocolMapping(
5905 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5906 AddQuicAlternateProtocolMapping(
5907 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5908 request_.network_isolation_key = kNetworkIsolationKey1;
5909 SendRequestAndExpectHttpResponse("hello from http");
5910
5911 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5912 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5913}
5914
[email protected]1e960032013-12-20 19:00:205915TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595916 // Alternate-protocol job
5917 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025918 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595919 };
Ryan Sleevib8d7ea02018-05-07 20:01:015920 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595921 socket_factory_.AddSocketDataProvider(&quic_data);
5922
5923 // Main job which will succeed even though the alternate job fails.
5924 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025925 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5926 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5927 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595928
Ryan Sleevib8d7ea02018-05-07 20:01:015929 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595930 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565931 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595932
rch3f4b8452016-02-23 16:59:325933 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595934
Ryan Hamilton9835e662018-08-02 05:36:275935 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195936 SendRequestAndExpectHttpResponse("hello from http");
5937 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595938}
5939
[email protected]00c159f2014-05-21 22:38:165940TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535941 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165942 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025943 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165944 };
Ryan Sleevib8d7ea02018-05-07 20:01:015945 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165946 socket_factory_.AddSocketDataProvider(&quic_data);
5947
[email protected]eb71ab62014-05-23 07:57:535948 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165949 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025950 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165951 };
5952
Ryan Sleevib8d7ea02018-05-07 20:01:015953 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165954 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5955 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565956 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165957
rtennetib8e80fb2016-05-16 00:12:095958 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325959 CreateSession();
[email protected]00c159f2014-05-21 22:38:165960
Ryan Hamilton9835e662018-08-02 05:36:275961 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165962 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165963 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165964 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5966 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165967 ExpectQuicAlternateProtocolMapping();
5968}
5969
Zhongyi Shia0cef1082017-08-25 01:49:505970TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435971 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5972 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5973 return;
5974 }
5975
Zhongyi Shia0cef1082017-08-25 01:49:505976 // Tests that TCP job is delayed and QUIC job does not require confirmation
5977 // if QUIC was recently supported on the same IP on start.
5978
5979 // Set QUIC support on the last IP address, which is same with the local IP
5980 // address. Require confirmation mode will be turned off immediately when
5981 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:435982 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
5983 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:505984
Ryan Hamiltonabad59e2019-06-06 04:02:595985 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035986 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495987 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255988 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495989 mock_quic_data.AddWrite(SYNCHRONOUS,
5990 ConstructInitialSettingsPacket(packet_number++));
5991 }
Zhongyi Shi32f2fd02018-04-16 18:23:435992 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495993 SYNCHRONOUS,
5994 ConstructClientRequestHeadersPacket(
5995 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5996 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435997 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335998 ASYNC, ConstructServerResponseHeadersPacket(
5999 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6000 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436001 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336002 mock_quic_data.AddRead(
6003 ASYNC, ConstructServerDataPacket(
6004 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176005 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:496006 mock_quic_data.AddWrite(SYNCHRONOUS,
6007 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506008 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6009 mock_quic_data.AddRead(ASYNC, 0); // EOF
6010
6011 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6012 // No HTTP data is mocked as TCP job never starts in this case.
6013
6014 CreateSession();
6015 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:436016 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6017 false);
Zhongyi Shia0cef1082017-08-25 01:49:506018
Ryan Hamilton9835e662018-08-02 05:36:276019 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506020
6021 // Stall host resolution so that QUIC job will not succeed synchronously.
6022 // Socket will not be configured immediately and QUIC support is not sorted
6023 // out, TCP job will still be delayed as server properties indicates QUIC
6024 // support on last IP address.
6025 host_resolver_.set_synchronous_mode(false);
6026
6027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6028 TestCompletionCallback callback;
6029 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6030 IsError(ERR_IO_PENDING));
6031 // Complete host resolution in next message loop so that QUIC job could
6032 // proceed.
6033 base::RunLoop().RunUntilIdle();
6034 EXPECT_THAT(callback.WaitForResult(), IsOk());
6035
6036 CheckWasQuicResponse(&trans);
6037 CheckResponseData(&trans, "hello!");
6038}
6039
6040TEST_P(QuicNetworkTransactionTest,
6041 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436042 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6043 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6044 return;
6045 }
6046
Zhongyi Shia0cef1082017-08-25 01:49:506047 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
6048 // was recently supported on a different IP address on start.
6049
6050 // Set QUIC support on the last IP address, which is different with the local
6051 // IP address. Require confirmation mode will remain when local IP address is
6052 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436053 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6054 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:506055
Ryan Hamiltonabad59e2019-06-06 04:02:596056 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236057 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:496058 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:256059 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236060 mock_quic_data.AddWrite(SYNCHRONOUS,
6061 ConstructInitialSettingsPacket(packet_num++));
6062 }
Nick Harper057264a82019-09-12 23:33:496063 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:506064 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236065 SYNCHRONOUS,
6066 ConstructClientRequestHeadersPacket(
6067 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6068 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436069 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336070 ASYNC, ConstructServerResponseHeadersPacket(
6071 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6072 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436073 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336074 mock_quic_data.AddRead(
6075 ASYNC, ConstructServerDataPacket(
6076 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176077 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236078 mock_quic_data.AddWrite(SYNCHRONOUS,
6079 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506080 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6081 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6082 // No HTTP data is mocked as TCP job will be delayed and never starts.
6083
6084 CreateSession();
Matt Menkeb566c392019-09-11 23:22:436085 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6086 false);
Ryan Hamilton9835e662018-08-02 05:36:276087 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506088
6089 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
6090 // Socket will not be configured immediately and QUIC support is not sorted
6091 // out, TCP job will still be delayed as server properties indicates QUIC
6092 // support on last IP address.
6093 host_resolver_.set_synchronous_mode(false);
6094
6095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6096 TestCompletionCallback callback;
6097 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6098 IsError(ERR_IO_PENDING));
6099
6100 // Complete host resolution in next message loop so that QUIC job could
6101 // proceed.
6102 base::RunLoop().RunUntilIdle();
6103 // Explicitly confirm the handshake so that QUIC job could succeed.
6104 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:526105 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:506106 EXPECT_THAT(callback.WaitForResult(), IsOk());
6107
6108 CheckWasQuicResponse(&trans);
6109 CheckResponseData(&trans, "hello!");
6110}
6111
Ryan Hamilton75f197262017-08-17 14:00:076112TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
6113 // Test that NetErrorDetails is correctly populated, even if the
6114 // handshake has not yet been confirmed and no stream has been created.
6115
6116 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:596117 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:076118 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6119 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
6120 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6121
6122 // Main job will also fail.
6123 MockRead http_reads[] = {
6124 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6125 };
6126
Ryan Sleevib8d7ea02018-05-07 20:01:016127 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:076128 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6129 socket_factory_.AddSocketDataProvider(&http_data);
6130 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6131
6132 AddHangingNonAlternateProtocolSocketData();
6133 CreateSession();
6134 // Require handshake confirmation to ensure that no QUIC streams are
6135 // created, and to ensure that the TCP job does not wait for the QUIC
6136 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:436137 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6138 false);
Ryan Hamilton75f197262017-08-17 14:00:076139
Ryan Hamilton9835e662018-08-02 05:36:276140 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:076141 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6142 TestCompletionCallback callback;
6143 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6144 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6145 // Allow the TCP job to fail.
6146 base::RunLoop().RunUntilIdle();
6147 // Now let the QUIC job fail.
6148 mock_quic_data.Resume();
6149 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6150 ExpectQuicAlternateProtocolMapping();
6151 NetErrorDetails details;
6152 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526153 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:076154}
6155
[email protected]1e960032013-12-20 19:00:206156TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:456157 // Alternate-protocol job
6158 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:026159 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:456160 };
Ryan Sleevib8d7ea02018-05-07 20:01:016161 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:456162 socket_factory_.AddSocketDataProvider(&quic_data);
6163
[email protected]c92c1b52014-05-31 04:16:066164 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:016165 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:066166 socket_factory_.AddSocketDataProvider(&quic_data2);
6167
[email protected]4d283b32013-10-17 12:57:276168 // Final job that will proceed when the QUIC job fails.
6169 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026170 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6171 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6172 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:276173
Ryan Sleevib8d7ea02018-05-07 20:01:016174 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:276175 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566176 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:276177
rch3f4b8452016-02-23 16:59:326178 CreateSession();
[email protected]77c6c162013-08-17 02:57:456179
Ryan Hamilton9835e662018-08-02 05:36:276180 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:456181
[email protected]4d283b32013-10-17 12:57:276182 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:456183
6184 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:276185
rch37de576c2015-05-17 20:28:176186 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6187 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:456188}
6189
Matt Menkeb32ba5122019-09-10 19:17:056190TEST_P(QuicNetworkTransactionTest,
6191 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436192 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6193 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6194 return;
6195 }
6196
Matt Menkeb32ba5122019-09-10 19:17:056197 base::test::ScopedFeatureList feature_list;
6198 feature_list.InitWithFeatures(
6199 // enabled_features
6200 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
6201 features::kPartitionConnectionsByNetworkIsolationKey},
6202 // disabled_features
6203 {});
6204 // Since HttpServerProperties caches the feature value, have to create a new
6205 // one.
6206 http_server_properties_ = std::make_unique<HttpServerProperties>();
6207
6208 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
6209 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
6210 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
6211 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
6212
6213 // Alternate-protocol job
6214 MockRead quic_reads[] = {
6215 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6216 };
6217 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
6218 socket_factory_.AddSocketDataProvider(&quic_data);
6219
6220 // Second Alternate-protocol job which will race with the TCP job.
6221 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
6222 socket_factory_.AddSocketDataProvider(&quic_data2);
6223
6224 // Final job that will proceed when the QUIC job fails.
6225 MockRead http_reads[] = {
6226 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6227 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6228 MockRead(ASYNC, OK)};
6229
6230 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6231 socket_factory_.AddSocketDataProvider(&http_data);
6232 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6233
6234 CreateSession();
6235
6236 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6237 kNetworkIsolationKey1);
6238 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6239 kNetworkIsolationKey2);
6240
6241 request_.network_isolation_key = kNetworkIsolationKey1;
6242 SendRequestAndExpectHttpResponse("hello from http");
6243 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6244 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6245
6246 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6247 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6248
6249 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6250 AddHttpDataAndRunRequest();
6251 // Requests using other NetworkIsolationKeys can still use QUIC.
6252 request_.network_isolation_key = kNetworkIsolationKey2;
6253 AddQuicDataAndRunRequest();
6254
6255 // The last two requests should not have changed the alternative service
6256 // mappings.
6257 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6258 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6259}
6260
[email protected]93b31772014-06-19 08:03:356261TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036262 // Alternate-protocol job
6263 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596264 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036265 };
Ryan Sleevib8d7ea02018-05-07 20:01:016266 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036267 socket_factory_.AddSocketDataProvider(&quic_data);
6268
6269 // Main job that will proceed when the QUIC job fails.
6270 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026271 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6272 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6273 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036274
Ryan Sleevib8d7ea02018-05-07 20:01:016275 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036276 socket_factory_.AddSocketDataProvider(&http_data);
6277
rtennetib8e80fb2016-05-16 00:12:096278 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326279 CreateSession();
[email protected]65768442014-06-06 23:37:036280
Ryan Hamilton9835e662018-08-02 05:36:276281 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036282
6283 SendRequestAndExpectHttpResponse("hello from http");
6284}
6285
[email protected]eb71ab62014-05-23 07:57:536286TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336287 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016288 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496289 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336290 socket_factory_.AddSocketDataProvider(&quic_data);
6291
6292 // Main job which will succeed even though the alternate job fails.
6293 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026294 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6295 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6296 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336297
Ryan Sleevib8d7ea02018-05-07 20:01:016298 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336299 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566300 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336301
rch3f4b8452016-02-23 16:59:326302 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276303 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336304 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536305
6306 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336307}
6308
[email protected]4fee9672014-01-08 14:47:156309TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:596310 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176311 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6312 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:046313 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156314
6315 // When the QUIC connection fails, we will try the request again over HTTP.
6316 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486317 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566318 MockRead("hello world"),
6319 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6320 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156321
Ryan Sleevib8d7ea02018-05-07 20:01:016322 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156323 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566324 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156325
6326 // In order for a new QUIC session to be established via alternate-protocol
6327 // without racing an HTTP connection, we need the host resolution to happen
6328 // synchronously.
6329 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296330 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566331 "");
[email protected]4fee9672014-01-08 14:47:156332
rch3f4b8452016-02-23 16:59:326333 CreateSession();
David Schinazic8281052019-01-24 06:14:176334 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6335 AddQuicAlternateProtocolMapping(
6336 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156337 SendRequestAndExpectHttpResponse("hello world");
6338}
6339
tbansalc3308d72016-08-27 10:25:046340// For an alternative proxy that supports QUIC, test that the request is
6341// successfully fetched by the main job when the alternate proxy job encounters
6342// an error.
6343TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6344 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6345}
6346TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6347 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6348}
6349TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6350 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6351}
6352TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6353 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6354}
6355TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6356 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6357}
6358TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6359 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6360}
6361TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6362 TestAlternativeProxy(ERR_IO_PENDING);
6363}
6364TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6365 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6366}
6367
6368TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596369 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176370 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6371 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336372 mock_quic_data.AddWrite(
6373 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6374 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6375 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436376 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046377 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6378
6379 // When the QUIC connection fails, we will try the request again over HTTP.
6380 MockRead http_reads[] = {
6381 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6382 MockRead("hello world"),
6383 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6384 MockRead(ASYNC, OK)};
6385
Ryan Sleevib8d7ea02018-05-07 20:01:016386 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046387 socket_factory_.AddSocketDataProvider(&http_data);
6388 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6389
6390 TestProxyDelegate test_proxy_delegate;
6391 const HostPortPair host_port_pair("myproxy.org", 443);
6392 test_proxy_delegate.set_alternative_proxy_server(
6393 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6394 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6395
Ramin Halavatica8d5252018-03-12 05:33:496396 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6397 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526398 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046399 request_.url = GURL("http://mail.example.org/");
6400
6401 // In order for a new QUIC session to be established via alternate-protocol
6402 // without racing an HTTP connection, we need the host resolution to happen
6403 // synchronously.
6404 host_resolver_.set_synchronous_mode(true);
6405 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046406
6407 CreateSession();
David Schinazic8281052019-01-24 06:14:176408 crypto_client_stream_factory_.set_handshake_mode(
6409 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046410 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596411 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166412 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046413}
6414
bnc508835902015-05-12 20:10:296415TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586416 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386417 EXPECT_FALSE(
6418 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596419 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236420 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256421 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236422 mock_quic_data.AddWrite(SYNCHRONOUS,
6423 ConstructInitialSettingsPacket(packet_num++));
6424 }
rch5cb522462017-04-25 20:18:366425 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236426 SYNCHRONOUS,
6427 ConstructClientRequestHeadersPacket(
6428 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6429 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436430 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336431 ASYNC, ConstructServerResponseHeadersPacket(
6432 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6433 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436434 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336435 mock_quic_data.AddRead(
6436 ASYNC, ConstructServerDataPacket(
6437 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176438 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236439 mock_quic_data.AddWrite(SYNCHRONOUS,
6440 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506441 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296442 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6443
bncb07c05532015-05-14 19:07:206444 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096445 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326446 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276447 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296448 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386449 EXPECT_TRUE(
6450 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296451}
6452
zhongyi363c91c2017-03-23 23:16:086453// TODO(zhongyi): disabled this broken test as it was not testing the correct
6454// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6455TEST_P(QuicNetworkTransactionTest,
6456 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276457 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596458 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496459 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046460
6461 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046462
6463 test_proxy_delegate.set_alternative_proxy_server(
6464 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526465 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046466
6467 request_.url = GURL("http://mail.example.org/");
6468
6469 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6470 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016471 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046472 socket_factory_.AddSocketDataProvider(&socket_data);
6473
6474 // The non-alternate protocol job needs to hang in order to guarantee that
6475 // the alternate-protocol job will "win".
6476 AddHangingNonAlternateProtocolSocketData();
6477
6478 CreateSession();
6479 request_.method = "POST";
6480 ChunkedUploadDataStream upload_data(0);
6481 upload_data.AppendData("1", 1, true);
6482
6483 request_.upload_data_stream = &upload_data;
6484
6485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6486 TestCompletionCallback callback;
6487 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6488 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6489 EXPECT_NE(OK, callback.WaitForResult());
6490
6491 // Verify that the alternative proxy server is not marked as broken.
6492 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6493
6494 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596495 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276496
6497 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6498 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6499 1);
tbansalc3308d72016-08-27 10:25:046500}
6501
rtenneti56977812016-01-15 19:26:566502TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Nick Harper72ade192019-07-17 03:30:426503 session_params_.quic_params.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576504 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566505
Renjie Tangaadb84b2019-08-31 01:00:236506 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256507 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236508 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6509 else
6510 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6511 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6512 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6513
6514 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6515 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6516 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016517 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236518 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566519
rtennetib8e80fb2016-05-16 00:12:096520 // The non-alternate protocol job needs to hang in order to guarantee that
6521 // the alternate-protocol job will "win".
6522 AddHangingNonAlternateProtocolSocketData();
6523
rtenneti56977812016-01-15 19:26:566524 CreateSession();
6525 request_.method = "POST";
6526 ChunkedUploadDataStream upload_data(0);
6527 upload_data.AppendData("1", 1, true);
6528
6529 request_.upload_data_stream = &upload_data;
6530
bnc691fda62016-08-12 00:43:166531 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566532 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166533 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566535 EXPECT_NE(OK, callback.WaitForResult());
6536}
6537
rche11300ef2016-09-02 01:44:286538TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Nick Harper72ade192019-07-17 03:30:426539 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286540 ScopedMockNetworkChangeNotifier network_change_notifier;
6541 MockNetworkChangeNotifier* mock_ncn =
6542 network_change_notifier.mock_network_change_notifier();
6543 mock_ncn->ForceNetworkHandlesSupported();
6544 mock_ncn->SetConnectedNetworksList(
6545 {kDefaultNetworkForTests, kNewNetworkForTests});
6546
Nick Harper72ade192019-07-17 03:30:426547 session_params_.quic_params.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286548 HostPortPair::FromString("mail.example.org:443"));
Nick Harper72ade192019-07-17 03:30:426549 session_params_.quic_params.migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286550
Ryan Hamiltonabad59e2019-06-06 04:02:596551 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286552 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236553 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256554 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236555 socket_data.AddWrite(SYNCHRONOUS,
6556 ConstructInitialSettingsPacket(packet_num++));
6557 }
Fan Yang32c5a112018-12-10 20:06:336558 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236559 SYNCHRONOUS,
6560 ConstructClientRequestHeadersPacket(
6561 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6562 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286563 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6564 socket_data.AddSocketDataToFactory(&socket_factory_);
6565
Ryan Hamiltonabad59e2019-06-06 04:02:596566 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286567 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6568 socket_data2.AddSocketDataToFactory(&socket_factory_);
6569
6570 // The non-alternate protocol job needs to hang in order to guarantee that
6571 // the alternate-protocol job will "win".
6572 AddHangingNonAlternateProtocolSocketData();
6573
6574 CreateSession();
6575 request_.method = "POST";
6576 ChunkedUploadDataStream upload_data(0);
6577
6578 request_.upload_data_stream = &upload_data;
6579
rdsmith1d343be52016-10-21 20:37:506580 std::unique_ptr<HttpNetworkTransaction> trans(
6581 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286582 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506583 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6585
6586 base::RunLoop().RunUntilIdle();
6587 upload_data.AppendData("1", 1, true);
6588 base::RunLoop().RunUntilIdle();
6589
6590 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506591 trans.reset();
rche11300ef2016-09-02 01:44:286592 session_.reset();
6593}
6594
Ryan Hamilton4b3574532017-10-30 20:17:256595TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426596 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256597 HostPortPair::FromString("mail.example.org:443"));
6598
Ryan Hamiltonabad59e2019-06-06 04:02:596599 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236600 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256601 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236602 socket_data.AddWrite(SYNCHRONOUS,
6603 ConstructInitialSettingsPacket(packet_num++));
6604 }
Ryan Hamilton4b3574532017-10-30 20:17:256605 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336606 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236607 SYNCHRONOUS,
6608 ConstructClientRequestHeadersPacket(
6609 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6610 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436611 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336612 ASYNC, ConstructServerResponseHeadersPacket(
6613 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6614 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436615 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336616 socket_data.AddRead(
6617 ASYNC, ConstructServerDataPacket(
6618 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176619 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236620 socket_data.AddWrite(SYNCHRONOUS,
6621 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256622 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436623 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6624 // TLS1.3 supports multiple packet number space, so the ack is no longer
6625 // sent.
6626 socket_data.AddWrite(
6627 SYNCHRONOUS,
6628 client_maker_.MakeConnectionClosePacket(
6629 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6630 } else {
6631 socket_data.AddWrite(
6632 SYNCHRONOUS,
6633 client_maker_.MakeAckAndConnectionClosePacket(
6634 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6635 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6636 }
Ryan Hamilton4b3574532017-10-30 20:17:256637
6638 socket_data.AddSocketDataToFactory(&socket_factory_);
6639
6640 CreateSession();
6641
6642 SendRequestAndExpectQuicResponse("hello!");
6643 session_.reset();
6644}
6645
6646TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426647 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256648 HostPortPair::FromString("mail.example.org:443"));
6649
Ryan Hamiltonabad59e2019-06-06 04:02:596650 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236651 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256652 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236653 socket_data.AddWrite(SYNCHRONOUS,
6654 ConstructInitialSettingsPacket(packet_num++));
6655 }
Ryan Hamilton4b3574532017-10-30 20:17:256656 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336657 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236658 SYNCHRONOUS,
6659 ConstructClientRequestHeadersPacket(
6660 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6661 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436662 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336663 ASYNC, ConstructServerResponseHeadersPacket(
6664 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6665 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436666 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336667 socket_data.AddRead(
6668 ASYNC, ConstructServerDataPacket(
6669 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176670 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236671 socket_data.AddWrite(SYNCHRONOUS,
6672 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256673 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436674 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6675 // TLS1.3 supports multiple packet number space, so the ack is no longer
6676 // sent.
6677 socket_data.AddWrite(
6678 SYNCHRONOUS,
6679 client_maker_.MakeConnectionClosePacket(
6680 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6681 } else {
6682 socket_data.AddWrite(
6683 SYNCHRONOUS,
6684 client_maker_.MakeAckAndConnectionClosePacket(
6685 packet_num++, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6686 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
6687 }
Ryan Hamilton4b3574532017-10-30 20:17:256688
6689 socket_data.AddSocketDataToFactory(&socket_factory_);
6690
6691 CreateSession();
6692
6693 SendRequestAndExpectQuicResponse("hello!");
6694 session_.reset();
6695}
6696
Ryan Hamilton9edcf1a2017-11-22 05:55:176697TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426698 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6699 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256700 HostPortPair::FromString("mail.example.org:443"));
6701
Ryan Hamiltonabad59e2019-06-06 04:02:596702 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256703 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256704 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236705 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176706 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256707 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6708 }
6709 socket_data.AddSocketDataToFactory(&socket_factory_);
6710
6711 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176712 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176713 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6714 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256715
Victor Vasiliev7752898d2019-11-14 21:30:226716 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6718 TestCompletionCallback callback;
6719 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176721 while (!callback.have_result()) {
6722 base::RunLoop().RunUntilIdle();
6723 quic_task_runner_->RunUntilIdle();
6724 }
6725 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256726 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176727 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6728 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6729 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226730 EXPECT_TRUE(context_.clock()->Now() - start >
6731 quic::QuicTime::Delta::FromSeconds(4));
6732 EXPECT_TRUE(context_.clock()->Now() - start <
6733 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256734}
6735
Ryan Hamilton9edcf1a2017-11-22 05:55:176736TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Nick Harper72ade192019-07-17 03:30:426737 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6738 session_params_.quic_params.origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256739 HostPortPair::FromString("mail.example.org:443"));
6740
Ryan Hamiltonabad59e2019-06-06 04:02:596741 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256742 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256743 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236744 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176745 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256746 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6747 }
6748 socket_data.AddSocketDataToFactory(&socket_factory_);
6749
6750 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176751 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176752 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6753 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256754
Victor Vasiliev7752898d2019-11-14 21:30:226755 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256756 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6757 TestCompletionCallback callback;
6758 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176760 while (!callback.have_result()) {
6761 base::RunLoop().RunUntilIdle();
6762 quic_task_runner_->RunUntilIdle();
6763 }
6764 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256765 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176766 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6767 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6768 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226769 EXPECT_TRUE(context_.clock()->Now() - start >
6770 quic::QuicTime::Delta::FromSeconds(4));
6771 EXPECT_TRUE(context_.clock()->Now() - start <
6772 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256773}
6774
Cherie Shi7596de632018-02-22 07:28:186775TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Nick Harper72ade192019-07-17 03:30:426776 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6777 session_params_.quic_params.origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186778 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436779 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526780 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6781 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186782
Ryan Hamiltonabad59e2019-06-06 04:02:596783 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186784 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236785 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256786 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236787 socket_data.AddWrite(SYNCHRONOUS,
6788 ConstructInitialSettingsPacket(packet_num++));
6789 }
Cherie Shi7596de632018-02-22 07:28:186790 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6791 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526792 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236793 SYNCHRONOUS,
6794 client_maker_.MakeConnectionClosePacket(
6795 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186796 socket_data.AddSocketDataToFactory(&socket_factory_);
6797
6798 CreateSession();
6799
6800 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6801 TestCompletionCallback callback;
6802 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6804 base::RunLoop().RunUntilIdle();
6805 ASSERT_TRUE(callback.have_result());
6806 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6807 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6808 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6809}
6810
ckrasic769733c2016-06-30 00:42:136811// Adds coverage to catch regression such as https://crbug.com/622043
6812TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Nick Harper72ade192019-07-17 03:30:426813 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136814 HostPortPair::FromString("mail.example.org:443"));
6815
Ryan Hamiltonabad59e2019-06-06 04:02:596816 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236817 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256818 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236819 mock_quic_data.AddWrite(
6820 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6821 }
Zhongyi Shi32f2fd02018-04-16 18:23:436822 mock_quic_data.AddWrite(
6823 SYNCHRONOUS,
6824 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336825 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026826 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436827 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026828 ASYNC,
6829 ConstructServerPushPromisePacket(
6830 1, GetNthClientInitiatedBidirectionalStreamId(0),
6831 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6832 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316833 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426834 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256835 !VersionUsesHttp3(version_.transport_version)) ||
6836 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426837 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026838 mock_quic_data.AddWrite(
6839 SYNCHRONOUS,
6840 ConstructClientPriorityPacket(
6841 client_packet_number++, false,
6842 GetNthServerInitiatedUnidirectionalStreamId(0),
6843 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576844 }
Zhongyi Shi32f2fd02018-04-16 18:23:436845 mock_quic_data.AddRead(
6846 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336847 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026848 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576849 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436850 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6851 mock_quic_data.AddRead(
6852 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336853 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026854 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436855 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436856 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336857 ASYNC, ConstructServerDataPacket(
6858 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176859 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576860 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436861 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436862 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436863 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336864 ASYNC, ConstructServerDataPacket(
6865 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176866 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336867 mock_quic_data.AddWrite(SYNCHRONOUS,
6868 ConstructClientAckAndRstPacket(
6869 client_packet_number++,
6870 GetNthServerInitiatedUnidirectionalStreamId(0),
6871 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136872 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6873 mock_quic_data.AddRead(ASYNC, 0); // EOF
6874 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6875
6876 // The non-alternate protocol job needs to hang in order to guarantee that
6877 // the alternate-protocol job will "win".
6878 AddHangingNonAlternateProtocolSocketData();
6879
6880 CreateSession();
6881
6882 // PUSH_PROMISE handling in the http layer gets exercised here.
6883 SendRequestAndExpectQuicResponse("hello!");
6884
6885 request_.url = GURL("https://mail.example.org/pushed.jpg");
6886 SendRequestAndExpectQuicResponse("and hello!");
6887
6888 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546889 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136890 EXPECT_LT(0u, entries.size());
6891
6892 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6893 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006894 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6895 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136896 EXPECT_LT(0, pos);
6897}
6898
rch56ec40a2017-06-23 14:48:446899// Regression test for http://crbug.com/719461 in which a promised stream
6900// is closed before the pushed headers arrive, but after the connection
6901// is closed and before the callbacks are executed.
6902TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Nick Harper72ade192019-07-17 03:30:426903 session_params_.quic_params.retry_without_alt_svc_on_quic_errors = false;
6904 session_params_.quic_params.origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446905 HostPortPair::FromString("mail.example.org:443"));
6906
Ryan Hamiltonabad59e2019-06-06 04:02:596907 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236908 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446909 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256910 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236911 mock_quic_data.AddWrite(
6912 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6913 }
rch56ec40a2017-06-23 14:48:446914 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436915 mock_quic_data.AddWrite(
6916 SYNCHRONOUS,
6917 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336918 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026919 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446920 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436921 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026922 ASYNC,
6923 ConstructServerPushPromisePacket(
6924 1, GetNthClientInitiatedBidirectionalStreamId(0),
6925 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6926 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316927 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426928 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:256929 !VersionUsesHttp3(version_.transport_version)) ||
6930 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:426931 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026932 mock_quic_data.AddWrite(
6933 SYNCHRONOUS,
6934 ConstructClientPriorityPacket(
6935 client_packet_number++, false,
6936 GetNthServerInitiatedUnidirectionalStreamId(0),
6937 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576938 }
rch56ec40a2017-06-23 14:48:446939 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436940 mock_quic_data.AddRead(
6941 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336942 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026943 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:446944 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576945 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436946 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446947 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436948 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436949 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336950 ASYNC, ConstructServerDataPacket(
6951 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176952 header + "hello!"));
rch56ec40a2017-06-23 14:48:446953 // Write error for the third request.
6954 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6955 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6956 mock_quic_data.AddRead(ASYNC, 0); // EOF
6957 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6958
6959 CreateSession();
6960
6961 // Send a request which triggers a push promise from the server.
6962 SendRequestAndExpectQuicResponse("hello!");
6963
6964 // Start a push transaction that will be cancelled after the connection
6965 // is closed, but before the callback is executed.
6966 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196967 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446968 session_.get());
6969 TestCompletionCallback callback2;
6970 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6972 base::RunLoop().RunUntilIdle();
6973
6974 // Cause the connection to close on a write error.
6975 HttpRequestInfo request3;
6976 request3.method = "GET";
6977 request3.url = GURL("https://mail.example.org/");
6978 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106979 request3.traffic_annotation =
6980 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446981 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6982 TestCompletionCallback callback3;
6983 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6984 IsError(ERR_IO_PENDING));
6985
6986 base::RunLoop().RunUntilIdle();
6987
6988 // When |trans2| is destroyed, the underlying stream will be closed.
6989 EXPECT_FALSE(callback2.have_result());
6990 trans2 = nullptr;
6991
6992 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6993}
6994
ckrasicda193a82016-07-09 00:39:366995TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Nick Harper72ade192019-07-17 03:30:426996 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366997 HostPortPair::FromString("mail.example.org:443"));
6998
Ryan Hamiltonabad59e2019-06-06 04:02:596999 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:367000
Renjief49758b2019-01-11 23:32:417001 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257002 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237003 mock_quic_data.AddWrite(
7004 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7005 }
ckrasicda193a82016-07-09 00:39:367006
Victor Vasiliev076657c2019-03-12 02:46:437007 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567008 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417009 mock_quic_data.AddWrite(
7010 SYNCHRONOUS,
7011 ConstructClientRequestHeadersAndDataFramesPacket(
7012 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7013 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027014 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:417015 } else {
7016 mock_quic_data.AddWrite(
7017 SYNCHRONOUS,
7018 ConstructClientRequestHeadersAndDataFramesPacket(
7019 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7020 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027021 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:417022 {header, "1"}));
7023 }
ckrasicda193a82016-07-09 00:39:367024
Zhongyi Shi32f2fd02018-04-16 18:23:437025 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337026 ASYNC, ConstructServerResponseHeadersPacket(
7027 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7028 GetResponseHeaders("200 OK")));
7029
Victor Vasiliev076657c2019-03-12 02:46:437030 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337031 mock_quic_data.AddRead(
7032 ASYNC, ConstructServerDataPacket(
7033 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177034 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:367035
Renjief49758b2019-01-11 23:32:417036 mock_quic_data.AddWrite(
7037 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:367038
7039 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7040 mock_quic_data.AddRead(ASYNC, 0); // EOF
7041 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7042
7043 // The non-alternate protocol job needs to hang in order to guarantee that
7044 // the alternate-protocol job will "win".
7045 AddHangingNonAlternateProtocolSocketData();
7046
7047 CreateSession();
7048 request_.method = "POST";
7049 ChunkedUploadDataStream upload_data(0);
7050 upload_data.AppendData("1", 1, true);
7051
7052 request_.upload_data_stream = &upload_data;
7053
7054 SendRequestAndExpectQuicResponse("hello!");
7055}
7056
allada71b2efb2016-09-09 04:57:487057class QuicURLRequestContext : public URLRequestContext {
7058 public:
7059 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
7060 MockClientSocketFactory* socket_factory)
7061 : storage_(this) {
7062 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:077063 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:047064 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:487065 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:047066 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:597067 storage_.set_proxy_resolution_service(
7068 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:077069 storage_.set_ssl_config_service(
7070 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:487071 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:117072 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:487073 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:267074 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:047075 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:487076 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:047077 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
7078 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
7079 false));
allada71b2efb2016-09-09 04:57:487080 }
7081
7082 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
7083
7084 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
7085
7086 private:
7087 MockClientSocketFactory* socket_factory_;
7088 URLRequestContextStorage storage_;
7089};
7090
7091TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Nick Harper72ade192019-07-17 03:30:427092 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487093 HostPortPair::FromString("mail.example.org:443"));
7094
Ryan Hamiltonabad59e2019-06-06 04:02:597095 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237096 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257097 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237098 mock_quic_data.AddWrite(SYNCHRONOUS,
7099 ConstructInitialSettingsPacket(packet_num++));
7100 }
Ryan Hamilton0239aac2018-05-19 00:03:137101 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487102 headers["user-agent"] = "";
7103 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:337104 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237105 SYNCHRONOUS,
7106 ConstructClientRequestHeadersPacket(
7107 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7108 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487109
Fan Yang32c5a112018-12-10 20:06:337110 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027111 ASYNC, ConstructServerResponseHeadersPacket(
7112 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7113 GetResponseHeaders("200 OK")));
7114 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457115 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257116 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457117 ? GetNthClientInitiatedBidirectionalStreamId(0)
7118 : quic::QuicUtils::GetHeadersStreamId(
7119 version_.transport_version));
allada71b2efb2016-09-09 04:57:487120
Victor Vasiliev076657c2019-03-12 02:46:437121 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367122 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337123 ASYNC, ConstructServerDataPacket(
7124 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177125 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:237126 mock_quic_data.AddWrite(SYNCHRONOUS,
7127 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487128
7129 mock_quic_data.AddRead(ASYNC, 0); // EOF
7130
7131 CreateSession();
7132
7133 TestDelegate delegate;
7134 QuicURLRequestContext quic_url_request_context(std::move(session_),
7135 &socket_factory_);
7136
7137 mock_quic_data.AddSocketDataToFactory(
7138 &quic_url_request_context.socket_factory());
7139 TestNetworkDelegate network_delegate;
7140 quic_url_request_context.set_network_delegate(&network_delegate);
7141
7142 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297143 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7144 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487145 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7146 &ssl_data_);
7147
7148 request->Start();
Wez2a31b222018-06-07 22:07:157149 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487150
7151 EXPECT_LT(0, request->GetTotalSentBytes());
7152 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:487153 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
7154 request->raw_header_size());
Wez0e717112018-06-18 23:09:227155
7156 // Pump the message loop to allow all data to be consumed.
7157 base::RunLoop().RunUntilIdle();
7158
allada71b2efb2016-09-09 04:57:487159 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7160 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7161}
7162
7163TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Nick Harper72ade192019-07-17 03:30:427164 session_params_.quic_params.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487165 HostPortPair::FromString("mail.example.org:443"));
7166
Ryan Hamiltonabad59e2019-06-06 04:02:597167 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237168 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257169 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237170 mock_quic_data.AddWrite(
7171 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7172 }
Ryan Hamilton0239aac2018-05-19 00:03:137173 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487174 headers["user-agent"] = "";
7175 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:437176 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337177 SYNCHRONOUS,
7178 ConstructClientRequestHeadersPacket(
7179 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027180 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487181
Fan Yang2330d182019-08-05 14:50:507182 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
7183 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:437184 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027185 ASYNC,
7186 ConstructServerPushPromisePacket(
7187 1, GetNthClientInitiatedBidirectionalStreamId(0),
7188 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7189 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:507190 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:257191 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:507192 push_promise_offset = server_maker_.stream_offset(
7193 GetNthClientInitiatedBidirectionalStreamId(0)) -
7194 initial;
7195 }
allada71b2efb2016-09-09 04:57:487196
Renjie Tang703fea92019-07-23 21:08:317197 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427198 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:257199 !VersionUsesHttp3(version_.transport_version)) ||
7200 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:427201 (FLAGS_quic_allow_http3_priority))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027202 mock_quic_data.AddWrite(
7203 SYNCHRONOUS,
7204 ConstructClientPriorityPacket(
7205 client_packet_number++, false,
7206 GetNthServerInitiatedUnidirectionalStreamId(0),
7207 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577208 }
7209
Ryan Hamiltone940bd12019-06-30 02:46:457210 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257211 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457212 ? GetNthClientInitiatedBidirectionalStreamId(0)
7213 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:437214 mock_quic_data.AddRead(
7215 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337216 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027217 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:457218 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257219 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457220 ? GetNthClientInitiatedBidirectionalStreamId(0)
7221 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:027222 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457223 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:487224
Yixin Wangb470bc882018-02-15 18:43:577225 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437226 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487227
ckrasicbf2f59c2017-05-04 23:54:367228 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437229 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337230 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027231 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437232 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:437233 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337234 ASYNC, ConstructServerDataPacket(
7235 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177236 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:487237
Yixin Wangb470bc882018-02-15 18:43:577238 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437239 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:437240 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367241 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337242 ASYNC, ConstructServerDataPacket(
7243 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177244 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:487245
Zhongyi Shi32f2fd02018-04-16 18:23:437246 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:487247
7248 CreateSession();
7249
7250 TestDelegate delegate;
7251 QuicURLRequestContext quic_url_request_context(std::move(session_),
7252 &socket_factory_);
7253
7254 mock_quic_data.AddSocketDataToFactory(
7255 &quic_url_request_context.socket_factory());
7256 TestNetworkDelegate network_delegate;
7257 quic_url_request_context.set_network_delegate(&network_delegate);
7258
7259 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297260 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7261 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487262 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7263 &ssl_data_);
7264
7265 request->Start();
Wez2a31b222018-06-07 22:07:157266 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487267
7268 EXPECT_LT(0, request->GetTotalSentBytes());
7269 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:507270 EXPECT_EQ(
7271 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
7272 request->raw_header_size());
Wez0e717112018-06-18 23:09:227273
7274 // Pump the message loop to allow all data to be consumed.
7275 base::RunLoop().RunUntilIdle();
7276
allada71b2efb2016-09-09 04:57:487277 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7278 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7279}
7280
Ryan Sleevia9d6aa62019-07-26 13:32:187281TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
7282 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:207283
7284 MockRead http_reads[] = {
7285 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7286 MockRead("hello world"),
7287 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7288 MockRead(ASYNC, OK)};
7289
Ryan Sleevib8d7ea02018-05-07 20:01:017290 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207291 socket_factory_.AddSocketDataProvider(&http_data);
7292 AddCertificate(&ssl_data_);
7293 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7294
Ryan Hamiltonabad59e2019-06-06 04:02:597295 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237296 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257297 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237298 mock_quic_data.AddWrite(SYNCHRONOUS,
7299 ConstructInitialSettingsPacket(packet_num++));
7300 }
Yixin Wang10f477ed2017-11-21 04:20:207301 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237302 SYNCHRONOUS,
7303 ConstructClientRequestHeadersPacket(
7304 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7305 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437306 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337307 ASYNC, ConstructServerResponseHeadersPacket(
7308 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7309 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437310 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337311 mock_quic_data.AddRead(
7312 ASYNC, ConstructServerDataPacket(
7313 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177314 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237315 mock_quic_data.AddWrite(SYNCHRONOUS,
7316 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207317 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7318 mock_quic_data.AddRead(ASYNC, 0); // EOF
7319
7320 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7321
7322 AddHangingNonAlternateProtocolSocketData();
7323 CreateSession();
7324
7325 SendRequestAndExpectHttpResponse("hello world");
7326 SendRequestAndExpectQuicResponse("hello!");
7327}
7328
Ryan Sleevia9d6aa62019-07-26 13:32:187329TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7330 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207331
7332 MockRead http_reads[] = {
7333 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7334 MockRead("hello world"),
7335 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7336 MockRead(ASYNC, OK)};
7337
Ryan Sleevib8d7ea02018-05-07 20:01:017338 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207339 socket_factory_.AddSocketDataProvider(&http_data);
7340 AddCertificate(&ssl_data_);
7341 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7342 socket_factory_.AddSocketDataProvider(&http_data);
7343 AddCertificate(&ssl_data_);
7344 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7345
7346 AddHangingNonAlternateProtocolSocketData();
7347 CreateSession();
7348
7349 SendRequestAndExpectHttpResponse("hello world");
7350 SendRequestAndExpectHttpResponse("hello world");
7351}
7352
bnc359ed2a2016-04-29 20:43:457353class QuicNetworkTransactionWithDestinationTest
7354 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017355 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057356 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457357 protected:
7358 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557359 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057360 client_headers_include_h2_stream_dependency_(
7361 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567362 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457363 destination_type_(GetParam().destination_type),
7364 cert_transparency_verifier_(new MultiLogCTVerifier()),
7365 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:597366 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117367 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:457368 ssl_data_(ASYNC, OK) {}
7369
7370 void SetUp() override {
7371 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557372 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457373
mmenke6ddfbea2017-05-31 21:48:417374 HttpNetworkSession::Params session_params;
7375 session_params.enable_quic = true;
Nick Harper72ade192019-07-17 03:30:427376 session_params.quic_params.allow_remote_alt_svc = true;
7377 session_params.quic_params.supported_versions = supported_versions_;
7378 session_params.quic_params.headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057379 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417380
7381 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457382
Victor Vasiliev7752898d2019-11-14 21:30:227383 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457384
7385 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277386 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417387 session_context.quic_crypto_client_stream_factory =
7388 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457389
Victor Vasiliev7752898d2019-11-14 21:30:227390 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417391 session_context.client_socket_factory = &socket_factory_;
7392 session_context.host_resolver = &host_resolver_;
7393 session_context.cert_verifier = &cert_verifier_;
7394 session_context.transport_security_state = &transport_security_state_;
7395 session_context.cert_transparency_verifier =
7396 cert_transparency_verifier_.get();
7397 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7398 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457399 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417400 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597401 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417402 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7403 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457404
mmenke6ddfbea2017-05-31 21:48:417405 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437406 session_->quic_stream_factory()
7407 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457408 }
7409
7410 void TearDown() override {
7411 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7412 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557413 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457414 PlatformTest::TearDown();
7415 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557416 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407417 session_.reset();
bnc359ed2a2016-04-29 20:43:457418 }
7419
zhongyie537a002017-06-27 16:48:217420 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457421 HostPortPair destination;
7422 switch (destination_type_) {
7423 case SAME_AS_FIRST:
7424 destination = HostPortPair(origin1_, 443);
7425 break;
7426 case SAME_AS_SECOND:
7427 destination = HostPortPair(origin2_, 443);
7428 break;
7429 case DIFFERENT:
7430 destination = HostPortPair(kDifferentHostname, 443);
7431 break;
7432 }
bnc3472afd2016-11-17 15:27:217433 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457434 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217435 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077436 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7437 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457438 }
7439
Ryan Hamilton8d9ee76e2018-05-29 23:52:527440 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237441 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527442 quic::QuicStreamId stream_id,
7443 bool should_include_version,
7444 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527445 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137446 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457447 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137448 spdy::SpdyHeaderBlock headers(
7449 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027450 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457451 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027452 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457453 }
7454
Ryan Hamilton8d9ee76e2018-05-29 23:52:527455 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237456 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527457 quic::QuicStreamId stream_id,
7458 bool should_include_version,
7459 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587460 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027461 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457462 }
7463
Ryan Hamilton8d9ee76e2018-05-29 23:52:527464 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237465 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527466 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527467 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137468 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027469 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7470 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457471 }
7472
Ryan Hamilton8d9ee76e2018-05-29 23:52:527473 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237474 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527475 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457476 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437477 std::string header = "";
Nick Harper23290b82019-05-02 00:02:567478 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417479 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:577480 auto header_length =
7481 quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437482 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417483 }
Ryan Hamilton7505eb92019-06-08 00:22:177484 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417485 header + "hello");
bnc359ed2a2016-04-29 20:43:457486 }
7487
Ryan Hamilton8d9ee76e2018-05-29 23:52:527488 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237489 uint64_t packet_number,
7490 uint64_t largest_received,
7491 uint64_t smallest_received,
7492 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457493 QuicTestPacketMaker* maker) {
7494 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497495 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457496 }
7497
Ryan Hamilton8d9ee76e2018-05-29 23:52:527498 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237499 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377500 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027501 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377502 }
7503
bnc359ed2a2016-04-29 20:43:457504 void AddRefusedSocketData() {
7505 std::unique_ptr<StaticSocketDataProvider> refused_data(
7506 new StaticSocketDataProvider());
7507 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7508 refused_data->set_connect_data(refused_connect);
7509 socket_factory_.AddSocketDataProvider(refused_data.get());
7510 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7511 }
7512
7513 void AddHangingSocketData() {
7514 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7515 new StaticSocketDataProvider());
7516 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7517 hanging_data->set_connect_data(hanging_connect);
7518 socket_factory_.AddSocketDataProvider(hanging_data.get());
7519 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7520 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7521 }
7522
7523 bool AllDataConsumed() {
7524 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7525 if (!socket_data_ptr->AllReadDataConsumed() ||
7526 !socket_data_ptr->AllWriteDataConsumed()) {
7527 return false;
7528 }
7529 }
7530 return true;
7531 }
7532
7533 void SendRequestAndExpectQuicResponse(const std::string& host) {
7534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7535 HttpRequestInfo request;
7536 std::string url("https://");
7537 url.append(host);
7538 request.url = GURL(url);
7539 request.load_flags = 0;
7540 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107541 request.traffic_annotation =
7542 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457543 TestCompletionCallback callback;
7544 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017545 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457546
7547 std::string response_data;
robpercival214763f2016-07-01 23:27:017548 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457549 EXPECT_EQ("hello", response_data);
7550
7551 const HttpResponseInfo* response = trans.GetResponseInfo();
7552 ASSERT_TRUE(response != nullptr);
7553 ASSERT_TRUE(response->headers.get() != nullptr);
7554 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7555 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527556 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087557 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457558 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377559 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457560 }
7561
Fan Yang32c5a112018-12-10 20:06:337562 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567563 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7564 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367565 }
7566
Nick Harper23290b82019-05-02 00:02:567567 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057568 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567569 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457570 DestinationType destination_type_;
7571 std::string origin1_;
7572 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227573 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457574 std::unique_ptr<HttpNetworkSession> session_;
7575 MockClientSocketFactory socket_factory_;
7576 MockHostResolver host_resolver_;
7577 MockCertVerifier cert_verifier_;
7578 TransportSecurityState transport_security_state_;
7579 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237580 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457581 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077582 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597583 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457584 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267585 HttpServerProperties http_server_properties_;
bnc359ed2a2016-04-29 20:43:457586 BoundTestNetLog net_log_;
7587 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7588 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7589 static_socket_data_provider_vector_;
7590 SSLSocketDataProvider ssl_data_;
7591};
7592
Victor Costane635086f2019-01-27 05:20:307593INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7594 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577595 ::testing::ValuesIn(GetPoolingTestParams()),
7596 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457597
7598// A single QUIC request fails because the certificate does not match the origin
7599// hostname, regardless of whether it matches the alternative service hostname.
7600TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7601 if (destination_type_ == DIFFERENT)
7602 return;
7603
7604 GURL url("https://mail.example.com/");
7605 origin1_ = url.host();
7606
7607 // Not used for requests, but this provides a test case where the certificate
7608 // is valid for the hostname of the alternative service.
7609 origin2_ = "mail.example.org";
7610
zhongyie537a002017-06-27 16:48:217611 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457612
7613 scoped_refptr<X509Certificate> cert(
7614 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247615 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7616 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457617
7618 ProofVerifyDetailsChromium verify_details;
7619 verify_details.cert_verify_result.verified_cert = cert;
7620 verify_details.cert_verify_result.is_issued_by_known_root = true;
7621 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7622
Ryan Hamiltonabad59e2019-06-06 04:02:597623 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457624 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7625 mock_quic_data.AddRead(ASYNC, 0);
7626
7627 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7628
7629 AddRefusedSocketData();
7630
7631 HttpRequestInfo request;
7632 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107633 request.traffic_annotation =
7634 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457635
7636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7637 TestCompletionCallback callback;
7638 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017639 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457640
7641 EXPECT_TRUE(AllDataConsumed());
7642}
7643
7644// First request opens QUIC session to alternative service. Second request
7645// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527646// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457647TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7648 origin1_ = "mail.example.org";
7649 origin2_ = "news.example.org";
7650
zhongyie537a002017-06-27 16:48:217651 SetQuicAlternativeService(origin1_);
7652 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457653
7654 scoped_refptr<X509Certificate> cert(
7655 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247656 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7657 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7658 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457659
7660 ProofVerifyDetailsChromium verify_details;
7661 verify_details.cert_verify_result.verified_cert = cert;
7662 verify_details.cert_verify_result.is_issued_by_known_root = true;
7663 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7664
Yixin Wang079ad542018-01-11 04:06:057665 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227666 version_,
7667 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7668 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057669 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177670 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227671 version_,
7672 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7673 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457674
Ryan Hamiltonabad59e2019-06-06 04:02:597675 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237676 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257677 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237678 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7679 packet_num++, &client_maker));
7680 }
Fan Yang32c5a112018-12-10 20:06:337681 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237682 SYNCHRONOUS,
7683 ConstructClientRequestHeadersPacket(
7684 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7685 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027686 mock_quic_data.AddRead(
7687 ASYNC,
7688 ConstructServerResponseHeadersPacket(
7689 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437690 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337691 ASYNC,
7692 ConstructServerDataPacket(
7693 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237694 mock_quic_data.AddWrite(
7695 SYNCHRONOUS,
7696 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457697
Yixin Wang079ad542018-01-11 04:06:057698 client_maker.set_hostname(origin2_);
7699 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457700
Zhongyi Shi32f2fd02018-04-16 18:23:437701 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027702 SYNCHRONOUS,
7703 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237704 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027705 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7706 mock_quic_data.AddRead(
7707 ASYNC,
7708 ConstructServerResponseHeadersPacket(
7709 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337711 ASYNC,
7712 ConstructServerDataPacket(
7713 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237714 mock_quic_data.AddWrite(
7715 SYNCHRONOUS,
7716 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457717 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7718 mock_quic_data.AddRead(ASYNC, 0); // EOF
7719
7720 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7721
7722 AddHangingSocketData();
7723 AddHangingSocketData();
7724
Victor Vasiliev7752898d2019-11-14 21:30:227725 scoped_refptr<TestTaskRunner> quic_task_runner(
7726 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567727 QuicStreamFactoryPeer::SetAlarmFactory(
7728 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097729 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227730 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567731
bnc359ed2a2016-04-29 20:43:457732 SendRequestAndExpectQuicResponse(origin1_);
7733 SendRequestAndExpectQuicResponse(origin2_);
7734
7735 EXPECT_TRUE(AllDataConsumed());
7736}
7737
7738// First request opens QUIC session to alternative service. Second request does
7739// not pool to it, even though destination matches, because certificate is not
7740// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527741// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457742TEST_P(QuicNetworkTransactionWithDestinationTest,
7743 DoNotPoolIfCertificateInvalid) {
7744 origin1_ = "news.example.org";
7745 origin2_ = "mail.example.com";
7746
zhongyie537a002017-06-27 16:48:217747 SetQuicAlternativeService(origin1_);
7748 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457749
7750 scoped_refptr<X509Certificate> cert1(
7751 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247752 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7753 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7754 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457755
7756 scoped_refptr<X509Certificate> cert2(
7757 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247758 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7759 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457760
7761 ProofVerifyDetailsChromium verify_details1;
7762 verify_details1.cert_verify_result.verified_cert = cert1;
7763 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7764 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7765
7766 ProofVerifyDetailsChromium verify_details2;
7767 verify_details2.cert_verify_result.verified_cert = cert2;
7768 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7769 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7770
Yixin Wang079ad542018-01-11 04:06:057771 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227772 version_,
7773 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7774 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057775 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177776 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227777 version_,
7778 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7779 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457780
Ryan Hamiltonabad59e2019-06-06 04:02:597781 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237782 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257783 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237784 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7785 packet_num++, &client_maker1));
7786 }
Fan Yang32c5a112018-12-10 20:06:337787 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237788 SYNCHRONOUS,
7789 ConstructClientRequestHeadersPacket(
7790 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7791 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437792 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337793 ASYNC,
7794 ConstructServerResponseHeadersPacket(
7795 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437796 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337797 ASYNC,
7798 ConstructServerDataPacket(
7799 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437800 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237801 SYNCHRONOUS,
7802 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457803 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7804 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7805
7806 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7807
Yixin Wang079ad542018-01-11 04:06:057808 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227809 version_,
7810 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7811 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057812 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177813 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227814 version_,
7815 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7816 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457817
Ryan Hamiltonabad59e2019-06-06 04:02:597818 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237819 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257820 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237821 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7822 packet_num2++, &client_maker2));
7823 }
Fan Yang32c5a112018-12-10 20:06:337824 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237825 SYNCHRONOUS,
7826 ConstructClientRequestHeadersPacket(
7827 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7828 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437829 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337830 ASYNC,
7831 ConstructServerResponseHeadersPacket(
7832 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437833 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337834 ASYNC,
7835 ConstructServerDataPacket(
7836 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437837 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237838 SYNCHRONOUS,
7839 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457840 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7841 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7842
7843 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7844
bnc359ed2a2016-04-29 20:43:457845 SendRequestAndExpectQuicResponse(origin1_);
7846 SendRequestAndExpectQuicResponse(origin2_);
7847
7848 EXPECT_TRUE(AllDataConsumed());
7849}
7850
ckrasicdee37572017-04-06 22:42:277851// crbug.com/705109 - this confirms that matching request with a body
7852// triggers a crash (pre-fix).
7853TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Nick Harper72ade192019-07-17 03:30:427854 session_params_.quic_params.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277855 HostPortPair::FromString("mail.example.org:443"));
7856
Ryan Hamiltonabad59e2019-06-06 04:02:597857 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237858 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257859 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237860 mock_quic_data.AddWrite(
7861 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7862 }
Zhongyi Shi32f2fd02018-04-16 18:23:437863 mock_quic_data.AddWrite(
7864 SYNCHRONOUS,
7865 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337866 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027867 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437868 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027869 ASYNC,
7870 ConstructServerPushPromisePacket(
7871 1, GetNthClientInitiatedBidirectionalStreamId(0),
7872 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7873 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317874
7875 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427876 version_.transport_version >= quic::QUIC_VERSION_43 &&
Victor Vasiliev7da08172019-10-14 06:04:257877 !VersionUsesHttp3(version_.transport_version)) ||
7878 (VersionUsesHttp3(version_.transport_version) &&
Renjie Tang33f43ce2019-09-23 22:11:427879 FLAGS_quic_allow_http3_priority)) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027880 mock_quic_data.AddWrite(
7881 SYNCHRONOUS,
7882 ConstructClientPriorityPacket(
7883 client_packet_number++, false,
7884 GetNthServerInitiatedUnidirectionalStreamId(0),
7885 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577886 }
Zhongyi Shi32f2fd02018-04-16 18:23:437887 mock_quic_data.AddRead(
7888 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337889 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027890 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577891 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437892 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7893 mock_quic_data.AddRead(
7894 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337895 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027896 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437897 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437898 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337899 ASYNC, ConstructServerDataPacket(
7900 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177901 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577902 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437903 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417904
Victor Vasiliev076657c2019-03-12 02:46:437905 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437906 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337907 ASYNC, ConstructServerDataPacket(
7908 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177909 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277910
7911 // Because the matching request has a body, we will see the push
7912 // stream get cancelled, and the matching request go out on the
7913 // wire.
Fan Yang32c5a112018-12-10 20:06:337914 mock_quic_data.AddWrite(SYNCHRONOUS,
7915 ConstructClientAckAndRstPacket(
7916 client_packet_number++,
7917 GetNthServerInitiatedUnidirectionalStreamId(0),
7918 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277919 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437920 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567921 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417922 mock_quic_data.AddWrite(
7923 SYNCHRONOUS,
7924 ConstructClientRequestHeadersAndDataFramesPacket(
7925 client_packet_number++,
7926 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7927 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027928 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417929 } else {
7930 mock_quic_data.AddWrite(
7931 SYNCHRONOUS,
7932 ConstructClientRequestHeadersAndDataFramesPacket(
7933 client_packet_number++,
7934 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7935 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027936 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7937 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417938 }
ckrasicdee37572017-04-06 22:42:277939
7940 // We see the same response as for the earlier pushed and cancelled
7941 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437942 mock_quic_data.AddRead(
7943 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337944 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027945 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:437946 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337947 ASYNC, ConstructServerDataPacket(
7948 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177949 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277950
Yixin Wangb470bc882018-02-15 18:43:577951 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437952 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277953 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7954 mock_quic_data.AddRead(ASYNC, 0); // EOF
7955 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7956
7957 // The non-alternate protocol job needs to hang in order to guarantee that
7958 // the alternate-protocol job will "win".
7959 AddHangingNonAlternateProtocolSocketData();
7960
7961 CreateSession();
7962
7963 // PUSH_PROMISE handling in the http layer gets exercised here.
7964 SendRequestAndExpectQuicResponse("hello!");
7965
7966 request_.url = GURL("https://mail.example.org/pushed.jpg");
7967 ChunkedUploadDataStream upload_data(0);
7968 upload_data.AppendData("1", 1, true);
7969 request_.upload_data_stream = &upload_data;
7970 SendRequestAndExpectQuicResponse("and hello!");
7971}
7972
Bence Béky7538a952018-02-01 16:59:527973// Regression test for https://crbug.com/797825: If pushed headers describe a
7974// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7975// not be called (otherwise a DCHECK fails).
7976TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137977 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527978 pushed_request_headers[":authority"] = "";
7979 pushed_request_headers[":method"] = "GET";
7980 pushed_request_headers[":path"] = "/";
7981 pushed_request_headers[":scheme"] = "nosuchscheme";
7982
Nick Harper72ade192019-07-17 03:30:427983 session_params_.quic_params.origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:527984 HostPortPair::FromString("mail.example.org:443"));
7985
Ryan Hamiltonabad59e2019-06-06 04:02:597986 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527987
Renjie Tangaadb84b2019-08-31 01:00:237988 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257989 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237990 mock_quic_data.AddWrite(SYNCHRONOUS,
7991 ConstructInitialSettingsPacket(packet_num++));
7992 }
Bence Béky7538a952018-02-01 16:59:527993 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237994 SYNCHRONOUS,
7995 ConstructClientRequestHeadersPacket(
7996 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7997 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:527998
Fan Yang32c5a112018-12-10 20:06:337999 mock_quic_data.AddRead(
8000 ASYNC, ConstructServerPushPromisePacket(
8001 1, GetNthClientInitiatedBidirectionalStreamId(0),
8002 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028003 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:238004 mock_quic_data.AddWrite(
8005 SYNCHRONOUS,
8006 ConstructClientRstPacket(packet_num++,
8007 GetNthServerInitiatedUnidirectionalStreamId(0),
8008 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:528009
Zhongyi Shi32f2fd02018-04-16 18:23:438010 mock_quic_data.AddRead(
8011 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338012 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028013 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238014 mock_quic_data.AddWrite(SYNCHRONOUS,
8015 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:528016
Zhongyi Shi32f2fd02018-04-16 18:23:438017 mock_quic_data.AddRead(
8018 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338019 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028020 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:438021 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:438022 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338023 ASYNC, ConstructServerDataPacket(
8024 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:178025 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:238026 mock_quic_data.AddWrite(SYNCHRONOUS,
8027 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:528028
8029 mock_quic_data.AddRead(ASYNC, 0);
8030 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8031
8032 // The non-alternate protocol job needs to hang in order to guarantee that
8033 // the alternate-protocol job will "win".
8034 AddHangingNonAlternateProtocolSocketData();
8035
8036 CreateSession();
8037
8038 // PUSH_PROMISE handling in the http layer gets exercised here.
8039 SendRequestAndExpectQuicResponse("hello!");
8040
8041 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8042 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8043}
8044
Yixin Wang46a273ec302018-01-23 17:59:568045// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148046TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:568047 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148048 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568049 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498050 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568051
Ryan Hamiltonabad59e2019-06-06 04:02:598052 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238053 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258054 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238055 mock_quic_data.AddWrite(SYNCHRONOUS,
8056 ConstructInitialSettingsPacket(packet_num++));
8057 }
Fan Yang32c5a112018-12-10 20:06:338058 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238059 SYNCHRONOUS,
8060 ConstructClientRequestHeadersPacket(
8061 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8062 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8063 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338064 mock_quic_data.AddRead(
8065 ASYNC, ConstructServerResponseHeadersPacket(
8066 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8067 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568068
8069 const char get_request[] =
8070 "GET / HTTP/1.1\r\n"
8071 "Host: mail.example.org\r\n"
8072 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438073 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568074 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418075 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358076 SYNCHRONOUS,
8077 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238078 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8079 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418080 } else {
8081 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418082 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358083 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238084 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8085 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418086 }
8087
Yixin Wang46a273ec302018-01-23 17:59:568088 const char get_response[] =
8089 "HTTP/1.1 200 OK\r\n"
8090 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438091 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438092 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338093 ASYNC, ConstructServerDataPacket(
8094 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178095 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438096 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338097 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418098 SYNCHRONOUS, ConstructServerDataPacket(
8099 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178100 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238101 mock_quic_data.AddWrite(SYNCHRONOUS,
8102 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568103 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8104
8105 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418106 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238107 ConstructClientRstPacket(packet_num++,
8108 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418109 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568110
8111 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8112
8113 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8114
8115 CreateSession();
8116
8117 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:098118 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:568119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8120 HeadersHandler headers_handler;
8121 trans.SetBeforeHeadersSentCallback(
8122 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8123 base::Unretained(&headers_handler)));
8124 RunTransaction(&trans);
8125 CheckWasHttpResponse(&trans);
8126 CheckResponsePort(&trans, 70);
8127 CheckResponseData(&trans, "0123456789");
8128 EXPECT_TRUE(headers_handler.was_proxied());
8129 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8130
8131 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8132 // proxy socket to disconnect.
8133 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8134
8135 base::RunLoop().RunUntilIdle();
8136 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8137 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8138}
8139
8140// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148141TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:568142 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148143 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568144 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498145 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568146
Ryan Hamiltonabad59e2019-06-06 04:02:598147 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238148 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258149 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238150 mock_quic_data.AddWrite(SYNCHRONOUS,
8151 ConstructInitialSettingsPacket(packet_num++));
8152 }
Fan Yang32c5a112018-12-10 20:06:338153 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238154 SYNCHRONOUS,
8155 ConstructClientRequestHeadersPacket(
8156 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8157 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8158 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338159 mock_quic_data.AddRead(
8160 ASYNC, ConstructServerResponseHeadersPacket(
8161 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8162 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568163
8164 SpdyTestUtil spdy_util;
8165
Ryan Hamilton0239aac2018-05-19 00:03:138166 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568167 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438168 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568169 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418170 mock_quic_data.AddWrite(
8171 SYNCHRONOUS,
8172 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238173 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8174 1, 1, 1, false,
8175 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418176 } else {
8177 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418178 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358179 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238180 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8181 1, 1, 1, false,
8182 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418183 }
Ryan Hamilton0239aac2018-05-19 00:03:138184 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568185 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438186 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438187 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178188 ASYNC, ConstructServerDataPacket(
8189 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8190 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568191
Ryan Hamilton0239aac2018-05-19 00:03:138192 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198193 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:438194 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438195 mock_quic_data.AddRead(
8196 SYNCHRONOUS,
8197 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:338198 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438199 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:238200 mock_quic_data.AddWrite(SYNCHRONOUS,
8201 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568202 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8203
8204 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438205 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238206 ConstructClientRstPacket(packet_num++,
8207 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418208 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568209
8210 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8211
8212 SSLSocketDataProvider ssl_data(ASYNC, OK);
8213 ssl_data.next_proto = kProtoHTTP2;
8214 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8215
8216 CreateSession();
8217
8218 request_.url = GURL("https://mail.example.org/");
8219 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8220 HeadersHandler headers_handler;
8221 trans.SetBeforeHeadersSentCallback(
8222 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8223 base::Unretained(&headers_handler)));
8224 RunTransaction(&trans);
8225 CheckWasSpdyResponse(&trans);
8226 CheckResponsePort(&trans, 70);
8227 CheckResponseData(&trans, "0123456789");
8228 EXPECT_TRUE(headers_handler.was_proxied());
8229 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8230
Wez0e717112018-06-18 23:09:228231 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
8232 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:568233 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8234
8235 base::RunLoop().RunUntilIdle();
8236 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8237 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8238}
8239
8240// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
8241// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148242TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:568243 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148244 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568245 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498246 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568247
Ryan Hamiltonabad59e2019-06-06 04:02:598248 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:418249 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:258250 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238251 mock_quic_data.AddWrite(
8252 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
8253 }
Fan Yang32c5a112018-12-10 20:06:338254 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418255 SYNCHRONOUS,
8256 ConstructClientRequestHeadersPacket(
8257 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:048258 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028259 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338260 mock_quic_data.AddRead(
8261 ASYNC, ConstructServerResponseHeadersPacket(
8262 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8263 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568264
Ryan Hamilton8d9ee76e2018-05-29 23:52:528265 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568266 const char get_request_1[] =
8267 "GET / HTTP/1.1\r\n"
8268 "Host: mail.example.org\r\n"
8269 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438270 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:568271 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418272 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178273 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8274 write_packet_index++, false,
8275 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
8276 false, quic::QuicStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:418277 } else {
8278 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178279 SYNCHRONOUS, ConstructClientAckAndMultipleDataFramesPacket(
8280 write_packet_index++, false,
8281 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
8282 false, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:418283 }
8284
Yixin Wang46a273ec302018-01-23 17:59:568285 const char get_response_1[] =
8286 "HTTP/1.1 200 OK\r\n"
8287 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438288 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:438289 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438290 ASYNC, ConstructServerDataPacket(
8291 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178292 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418293 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568294
Victor Vasiliev076657c2019-03-12 02:46:438295 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338296 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178297 SYNCHRONOUS, ConstructServerDataPacket(
8298 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8299 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418300 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568301
Renjief49758b2019-01-11 23:32:418302 mock_quic_data.AddWrite(
8303 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568304
8305 const char get_request_2[] =
8306 "GET /2 HTTP/1.1\r\n"
8307 "Host: mail.example.org\r\n"
8308 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438309 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:568310 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418311 mock_quic_data.AddWrite(
8312 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358313 ConstructClientMultipleDataFramesPacket(
8314 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:178315 false, false, {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358316 } else {
8317 mock_quic_data.AddWrite(
8318 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178319 ConstructClientDataPacket(
8320 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
8321 false, false, quic::QuicStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418322 }
Yixin Wang46a273ec302018-01-23 17:59:568323
8324 const char get_response_2[] =
8325 "HTTP/1.1 200 OK\r\n"
8326 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438327 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438328 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438329 ASYNC, ConstructServerDataPacket(
8330 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178331 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418332 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568333
Victor Vasiliev076657c2019-03-12 02:46:438334 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528335 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178336 SYNCHRONOUS, ConstructServerDataPacket(
8337 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8338 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418339 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568340
Renjief49758b2019-01-11 23:32:418341 mock_quic_data.AddWrite(
8342 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568343 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8344
Renjief49758b2019-01-11 23:32:418345 mock_quic_data.AddWrite(
8346 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418347 ConstructClientRstPacket(write_packet_index++,
8348 GetNthClientInitiatedBidirectionalStreamId(0),
8349 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568350
8351 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8352
8353 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8354
8355 CreateSession();
8356
8357 request_.url = GURL("https://mail.example.org/");
8358 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8359 HeadersHandler headers_handler_1;
8360 trans_1.SetBeforeHeadersSentCallback(
8361 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8362 base::Unretained(&headers_handler_1)));
8363 RunTransaction(&trans_1);
8364 CheckWasHttpResponse(&trans_1);
8365 CheckResponsePort(&trans_1, 70);
8366 CheckResponseData(&trans_1, "0123456789");
8367 EXPECT_TRUE(headers_handler_1.was_proxied());
8368 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8369
8370 request_.url = GURL("https://mail.example.org/2");
8371 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8372 HeadersHandler headers_handler_2;
8373 trans_2.SetBeforeHeadersSentCallback(
8374 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8375 base::Unretained(&headers_handler_2)));
8376 RunTransaction(&trans_2);
8377 CheckWasHttpResponse(&trans_2);
8378 CheckResponsePort(&trans_2, 70);
8379 CheckResponseData(&trans_2, "0123456");
8380 EXPECT_TRUE(headers_handler_2.was_proxied());
8381 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8382
8383 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8384 // proxy socket to disconnect.
8385 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8386
8387 base::RunLoop().RunUntilIdle();
8388 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8389 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8390}
8391
8392// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8393// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8394// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148395TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568396 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148397 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568398 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498399 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568400
Ryan Hamiltonabad59e2019-06-06 04:02:598401 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238402 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258403 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238404 mock_quic_data.AddWrite(SYNCHRONOUS,
8405 ConstructInitialSettingsPacket(packet_num++));
8406 }
Yixin Wang46a273ec302018-01-23 17:59:568407
8408 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338409 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238410 SYNCHRONOUS,
8411 ConstructClientRequestHeadersPacket(
8412 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8413 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8414 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438415 mock_quic_data.AddRead(
8416 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338417 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028418 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568419
8420 // GET request, response, and data over QUIC tunnel for first request
8421 const char get_request[] =
8422 "GET / HTTP/1.1\r\n"
8423 "Host: mail.example.org\r\n"
8424 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438425 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568426 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418427 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358428 SYNCHRONOUS,
8429 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238430 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8431 1, 1, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418432 } else {
8433 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418434 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358435 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238436 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8437 1, 1, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418438 }
8439
Yixin Wang46a273ec302018-01-23 17:59:568440 const char get_response[] =
8441 "HTTP/1.1 200 OK\r\n"
8442 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438443 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568444 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338445 ASYNC, ConstructServerDataPacket(
8446 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178447 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438448 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338449 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418450 SYNCHRONOUS, ConstructServerDataPacket(
8451 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178452 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238453 mock_quic_data.AddWrite(SYNCHRONOUS,
8454 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568455
8456 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438457 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238458 SYNCHRONOUS,
8459 ConstructClientRequestHeadersPacket(
8460 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8461 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8462 ConnectRequestHeaders("different.example.org:443"),
8463 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438464 mock_quic_data.AddRead(
8465 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338466 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028467 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568468
8469 // GET request, response, and data over QUIC tunnel for second request
8470 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138471 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568472 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438473 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568474 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418475 mock_quic_data.AddWrite(
8476 SYNCHRONOUS,
8477 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238478 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8479 4, 4, 1, false,
8480 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418481 } else {
8482 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418483 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358484 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238485 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8486 4, 4, 1, false,
8487 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418488 }
Yixin Wang46a273ec302018-01-23 17:59:568489
Ryan Hamilton0239aac2018-05-19 00:03:138490 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568491 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438492 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438493 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178494 ASYNC, ConstructServerDataPacket(
8495 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8496 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568497
Ryan Hamilton0239aac2018-05-19 00:03:138498 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198499 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438500 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438501 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438502 ASYNC, ConstructServerDataPacket(
8503 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438504 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568505
Renjie Tangaadb84b2019-08-31 01:00:238506 mock_quic_data.AddWrite(SYNCHRONOUS,
8507 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568508 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8509
8510 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418511 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238512 ConstructClientRstPacket(packet_num++,
8513 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418514 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568515 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438516 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238517 ConstructClientRstPacket(packet_num++,
8518 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418519 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568520
8521 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8522
8523 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8524
8525 SSLSocketDataProvider ssl_data(ASYNC, OK);
8526 ssl_data.next_proto = kProtoHTTP2;
8527 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8528
8529 CreateSession();
8530
8531 request_.url = GURL("https://mail.example.org/");
8532 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8533 HeadersHandler headers_handler_1;
8534 trans_1.SetBeforeHeadersSentCallback(
8535 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8536 base::Unretained(&headers_handler_1)));
8537 RunTransaction(&trans_1);
8538 CheckWasHttpResponse(&trans_1);
8539 CheckResponsePort(&trans_1, 70);
8540 CheckResponseData(&trans_1, "0123456789");
8541 EXPECT_TRUE(headers_handler_1.was_proxied());
8542 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8543
8544 request_.url = GURL("https://different.example.org/");
8545 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8546 HeadersHandler headers_handler_2;
8547 trans_2.SetBeforeHeadersSentCallback(
8548 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8549 base::Unretained(&headers_handler_2)));
8550 RunTransaction(&trans_2);
8551 CheckWasSpdyResponse(&trans_2);
8552 CheckResponsePort(&trans_2, 70);
8553 CheckResponseData(&trans_2, "0123456");
8554 EXPECT_TRUE(headers_handler_2.was_proxied());
8555 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8556
8557 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8558 // proxy socket to disconnect.
8559 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8560
8561 base::RunLoop().RunUntilIdle();
8562 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8563 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8564}
8565
8566// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148567TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568568 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148569 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568570 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498571 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568572
Ryan Hamiltonabad59e2019-06-06 04:02:598573 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238574 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258575 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238576 mock_quic_data.AddWrite(SYNCHRONOUS,
8577 ConstructInitialSettingsPacket(packet_num++));
8578 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528579 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238580 SYNCHRONOUS,
8581 ConstructClientRequestHeadersPacket(
8582 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8583 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8584 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338585 mock_quic_data.AddRead(
8586 ASYNC, ConstructServerResponseHeadersPacket(
8587 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8588 GetResponseHeaders("500")));
8589 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238590 mock_quic_data.AddWrite(
8591 SYNCHRONOUS,
8592 ConstructClientAckAndRstPacket(
8593 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8594 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568595
8596 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8597
8598 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8599
8600 CreateSession();
8601
8602 request_.url = GURL("https://mail.example.org/");
8603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8604 HeadersHandler headers_handler;
8605 trans.SetBeforeHeadersSentCallback(
8606 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8607 base::Unretained(&headers_handler)));
8608 TestCompletionCallback callback;
8609 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8610 EXPECT_EQ(ERR_IO_PENDING, rv);
8611 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8612 EXPECT_EQ(false, headers_handler.was_proxied());
8613
8614 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8615 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8616}
8617
8618// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148619TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568620 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148621 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568622 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498623 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568624
Ryan Hamiltonabad59e2019-06-06 04:02:598625 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238626 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258627 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238628 mock_quic_data.AddWrite(SYNCHRONOUS,
8629 ConstructInitialSettingsPacket(packet_num++));
8630 }
Fan Yang32c5a112018-12-10 20:06:338631 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238632 SYNCHRONOUS,
8633 ConstructClientRequestHeadersPacket(
8634 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8635 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8636 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568637 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8638
8639 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8640
8641 CreateSession();
8642
8643 request_.url = GURL("https://mail.example.org/");
8644 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8645 HeadersHandler headers_handler;
8646 trans.SetBeforeHeadersSentCallback(
8647 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8648 base::Unretained(&headers_handler)));
8649 TestCompletionCallback callback;
8650 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8651 EXPECT_EQ(ERR_IO_PENDING, rv);
8652 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8653
8654 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8655 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8656}
8657
8658// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8659// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148660TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568661 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148662 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568663 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498664 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568665
Ryan Hamiltonabad59e2019-06-06 04:02:598666 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238667 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258668 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238669 mock_quic_data.AddWrite(SYNCHRONOUS,
8670 ConstructInitialSettingsPacket(packet_num++));
8671 }
Fan Yang32c5a112018-12-10 20:06:338672 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238673 SYNCHRONOUS,
8674 ConstructClientRequestHeadersPacket(
8675 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8676 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8677 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438678 mock_quic_data.AddRead(
8679 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338680 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028681 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238682 mock_quic_data.AddWrite(
8683 SYNCHRONOUS,
8684 ConstructClientAckAndRstPacket(
8685 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8686 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568687
Zhongyi Shi32f2fd02018-04-16 18:23:438688 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238689 SYNCHRONOUS,
8690 ConstructClientRequestHeadersPacket(
8691 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8692 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8693 ConnectRequestHeaders("mail.example.org:443"),
8694 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438695 mock_quic_data.AddRead(
8696 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338697 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028698 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568699
8700 const char get_request[] =
8701 "GET / HTTP/1.1\r\n"
8702 "Host: mail.example.org\r\n"
8703 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438704 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568705 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418706 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358707 SYNCHRONOUS,
8708 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238709 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8710 2, 2, 1, false, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418711 } else {
8712 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418713 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358714 ConstructClientAckAndMultipleDataFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:238715 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8716 2, 2, 1, false, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418717 }
Yixin Wang46a273ec302018-01-23 17:59:568718 const char get_response[] =
8719 "HTTP/1.1 200 OK\r\n"
8720 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438721 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438722 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338723 ASYNC, ConstructServerDataPacket(
8724 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178725 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528726
Victor Vasiliev076657c2019-03-12 02:46:438727 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338728 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418729 SYNCHRONOUS, ConstructServerDataPacket(
8730 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178731 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238732 mock_quic_data.AddWrite(SYNCHRONOUS,
8733 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568734 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8735
8736 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418737 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238738 ConstructClientRstPacket(packet_num++,
8739 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418740 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568741
8742 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8743
8744 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8745 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8746
8747 SSLSocketDataProvider ssl_data(ASYNC, OK);
8748 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8749
8750 CreateSession();
8751
8752 request_.url = GURL("https://mail.example.org/");
8753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8754 HeadersHandler headers_handler;
8755 trans.SetBeforeHeadersSentCallback(
8756 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8757 base::Unretained(&headers_handler)));
8758 TestCompletionCallback callback;
8759 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8760 EXPECT_EQ(ERR_IO_PENDING, rv);
8761 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8762
8763 rv = trans.RestartIgnoringLastError(callback.callback());
8764 EXPECT_EQ(ERR_IO_PENDING, rv);
8765 EXPECT_EQ(OK, callback.WaitForResult());
8766
8767 CheckWasHttpResponse(&trans);
8768 CheckResponsePort(&trans, 70);
8769 CheckResponseData(&trans, "0123456789");
8770 EXPECT_EQ(true, headers_handler.was_proxied());
8771 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8772
8773 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8774 // proxy socket to disconnect.
8775 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8776
8777 base::RunLoop().RunUntilIdle();
8778 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8779 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8780}
8781
8782// Checks if a request's specified "user-agent" header shows up correctly in the
8783// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148784TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008785 const char kConfiguredUserAgent[] = "Configured User-Agent";
8786 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568787 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148788 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568789 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498790 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568791
Ryan Hamiltonabad59e2019-06-06 04:02:598792 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238793 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258794 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238795 mock_quic_data.AddWrite(SYNCHRONOUS,
8796 ConstructInitialSettingsPacket(packet_num++));
8797 }
Yixin Wang46a273ec302018-01-23 17:59:568798
Ryan Hamilton0239aac2018-05-19 00:03:138799 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008800 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338801 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028802 SYNCHRONOUS,
8803 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238804 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8805 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
8806 0));
Yixin Wang46a273ec302018-01-23 17:59:568807 // Return an error, so the transaction stops here (this test isn't interested
8808 // in the rest).
8809 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8810
8811 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8812
Matt Menked732ea42019-03-08 12:05:008813 StaticHttpUserAgentSettings http_user_agent_settings(
8814 std::string() /* accept_language */, kConfiguredUserAgent);
8815 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568816 CreateSession();
8817
8818 request_.url = GURL("https://mail.example.org/");
8819 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008820 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568821 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8822 HeadersHandler headers_handler;
8823 trans.SetBeforeHeadersSentCallback(
8824 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8825 base::Unretained(&headers_handler)));
8826 TestCompletionCallback callback;
8827 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8828 EXPECT_EQ(ERR_IO_PENDING, rv);
8829 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8830
8831 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8832 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8833}
8834
Yixin Wang00fc44c2018-01-23 21:12:208835// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8836// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148837TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208838 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148839 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208840 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498841 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208842
8843 const RequestPriority request_priority = MEDIUM;
8844
Ryan Hamiltonabad59e2019-06-06 04:02:598845 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238846 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258847 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238848 mock_quic_data.AddWrite(SYNCHRONOUS,
8849 ConstructInitialSettingsPacket(packet_num++));
8850 }
Zhongyi Shi32f2fd02018-04-16 18:23:438851 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238852 SYNCHRONOUS,
8853 ConstructClientRequestHeadersPacket(
8854 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8855 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8856 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208857 // Return an error, so the transaction stops here (this test isn't interested
8858 // in the rest).
8859 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8860
8861 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8862
8863 CreateSession();
8864
8865 request_.url = GURL("https://mail.example.org/");
8866 HttpNetworkTransaction trans(request_priority, session_.get());
8867 TestCompletionCallback callback;
8868 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8869 EXPECT_EQ(ERR_IO_PENDING, rv);
8870 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8871
8872 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8873 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8874}
8875
Matt Menkeedaf3b82019-03-14 21:39:448876// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8877// HTTP/2 stream dependency and weights given the request priority.
8878TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8879 session_params_.enable_quic = true;
8880 session_params_.enable_quic_proxies_for_https_urls = true;
8881 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8882 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8883
8884 const RequestPriority kRequestPriority = MEDIUM;
8885 const RequestPriority kRequestPriority2 = LOWEST;
8886
Ryan Hamiltonabad59e2019-06-06 04:02:598887 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:258888 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238889 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
8890 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8891 } else {
8892 mock_quic_data.AddWrite(
8893 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8894 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
8895 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8896 ConnectRequestHeaders("mail.example.org:443"), 0));
8897 }
Matt Menkeedaf3b82019-03-14 21:39:448898 // This should never be reached.
8899 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8900 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8901
8902 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598903 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448904 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8905 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8906
8907 int original_max_sockets_per_group =
8908 ClientSocketPoolManager::max_sockets_per_group(
8909 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8910 ClientSocketPoolManager::set_max_sockets_per_group(
8911 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8912 int original_max_sockets_per_pool =
8913 ClientSocketPoolManager::max_sockets_per_pool(
8914 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8915 ClientSocketPoolManager::set_max_sockets_per_pool(
8916 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8917 CreateSession();
8918
8919 request_.url = GURL("https://mail.example.org/");
8920 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8921 TestCompletionCallback callback;
8922 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8923 EXPECT_EQ(ERR_IO_PENDING, rv);
8924
8925 HttpRequestInfo request2;
8926 request2.url = GURL("https://mail.example.org/some/other/path/");
8927 request2.traffic_annotation =
8928 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8929
8930 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8931 TestCompletionCallback callback2;
8932 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8933 EXPECT_EQ(ERR_IO_PENDING, rv2);
8934
8935 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8936 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8937
8938 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8939
8940 ClientSocketPoolManager::set_max_sockets_per_pool(
8941 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8942 original_max_sockets_per_pool);
8943 ClientSocketPoolManager::set_max_sockets_per_group(
8944 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8945 original_max_sockets_per_group);
8946}
8947
Yixin Wang46a273ec302018-01-23 17:59:568948// Test the request-challenge-retry sequence for basic auth, over a QUIC
8949// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148950TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568951 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8952 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568953
8954 std::unique_ptr<QuicTestPacketMaker> client_maker;
8955 std::unique_ptr<QuicTestPacketMaker> server_maker;
8956
8957 // On the second pass, the body read of the auth challenge is synchronous, so
8958 // IsConnectedAndIdle returns false. The socket should still be drained and
8959 // reused. See http://crbug.com/544255.
8960 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338961 client_maker.reset(new QuicTestPacketMaker(
Victor Vasiliev7752898d2019-11-14 21:30:228962 version_,
8963 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8964 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338965 client_headers_include_h2_stream_dependency_));
8966 server_maker.reset(new QuicTestPacketMaker(
Victor Vasiliev7752898d2019-11-14 21:30:228967 version_,
8968 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
8969 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
8970 false));
Yixin Wang46a273ec302018-01-23 17:59:568971
8972 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148973 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568974 proxy_resolution_service_ =
8975 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498976 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568977
Ryan Hamiltonabad59e2019-06-06 04:02:598978 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528979 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568980
Renjie Tangaadb84b2019-08-31 01:00:238981 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258982 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238983 mock_quic_data.AddWrite(
8984 SYNCHRONOUS, client_maker->MakeInitialSettingsPacket(packet_num++));
8985 }
Yixin Wang46a273ec302018-01-23 17:59:568986
8987 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438988 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:028989 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238990 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8991 false,
Matt Menke6e879bd2019-03-18 17:26:048992 ConvertRequestPriorityToQuicPriority(
8993 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568994 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:028995 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:568996
Ryan Hamilton0239aac2018-05-19 00:03:138997 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568998 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8999 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9000 headers["content-length"] = "10";
9001 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029002 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339003 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029004 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569005
9006 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:439007 mock_quic_data.AddRead(
9008 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339009 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179010 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569011 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:439012 mock_quic_data.AddRead(
9013 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339014 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:179015 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569016 }
9017 server_data_offset += 10;
9018
Renjie Tangaadb84b2019-08-31 01:00:239019 mock_quic_data.AddWrite(
9020 SYNCHRONOUS, client_maker->MakeAckPacket(packet_num++, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:569021
9022 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339023 SYNCHRONOUS,
9024 client_maker->MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:239025 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:419026 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:189027 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:569028
9029 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
9030 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
9031 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:049032 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029033 client_maker->MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239034 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
9035 false,
Matt Menke6e879bd2019-03-18 17:26:049036 ConvertRequestPriorityToQuicPriority(
9037 HttpProxyConnectJob::kH2QuicTunnelPriority),
9038 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:029039 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569040
9041 // Response to wrong password
9042 headers =
9043 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
9044 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9045 headers["content-length"] = "10";
9046 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029047 ASYNC, server_maker->MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339048 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029049 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569050 mock_quic_data.AddRead(SYNCHRONOUS,
9051 ERR_IO_PENDING); // No more data to read
9052
Fan Yang32c5a112018-12-10 20:06:339053 mock_quic_data.AddWrite(
9054 SYNCHRONOUS,
9055 client_maker->MakeAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:239056 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Fan Yang32c5a112018-12-10 20:06:339057 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:569058
9059 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9060 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
9061
9062 CreateSession();
9063
9064 request_.url = GURL("https://mail.example.org/");
9065 // Ensure that proxy authentication is attempted even
9066 // when the no authentication data flag is set.
9067 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
9068 {
9069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9070 HeadersHandler headers_handler;
9071 trans.SetBeforeHeadersSentCallback(
9072 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
9073 base::Unretained(&headers_handler)));
9074 RunTransaction(&trans);
9075
9076 const HttpResponseInfo* response = trans.GetResponseInfo();
9077 ASSERT_TRUE(response != nullptr);
9078 ASSERT_TRUE(response->headers.get() != nullptr);
9079 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9080 response->headers->GetStatusLine());
9081 EXPECT_TRUE(response->headers->IsKeepAlive());
9082 EXPECT_EQ(407, response->headers->response_code());
9083 EXPECT_EQ(10, response->headers->GetContentLength());
9084 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589085 base::Optional<AuthChallengeInfo> auth_challenge =
9086 response->auth_challenge;
9087 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569088 EXPECT_TRUE(auth_challenge->is_proxy);
9089 EXPECT_EQ("https://proxy.example.org:70",
9090 auth_challenge->challenger.Serialize());
9091 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9092 EXPECT_EQ("basic", auth_challenge->scheme);
9093
9094 TestCompletionCallback callback;
9095 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
9096 callback.callback());
9097 EXPECT_EQ(ERR_IO_PENDING, rv);
9098 EXPECT_EQ(OK, callback.WaitForResult());
9099
9100 response = trans.GetResponseInfo();
9101 ASSERT_TRUE(response != nullptr);
9102 ASSERT_TRUE(response->headers.get() != nullptr);
9103 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9104 response->headers->GetStatusLine());
9105 EXPECT_TRUE(response->headers->IsKeepAlive());
9106 EXPECT_EQ(407, response->headers->response_code());
9107 EXPECT_EQ(10, response->headers->GetContentLength());
9108 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589109 auth_challenge = response->auth_challenge;
9110 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569111 EXPECT_TRUE(auth_challenge->is_proxy);
9112 EXPECT_EQ("https://proxy.example.org:70",
9113 auth_challenge->challenger.Serialize());
9114 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9115 EXPECT_EQ("basic", auth_challenge->scheme);
9116 }
9117 // HttpNetworkTransaction is torn down now that it's out of scope, causing
9118 // the QUIC stream to be cleaned up (since the proxy socket cannot be
9119 // reused because it's not connected).
9120 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9121 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9122 }
9123}
9124
Yixin Wang385652a2018-02-16 02:37:239125TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
9126 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
9127 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:569128 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:239129 !client_headers_include_h2_stream_dependency_) {
9130 return;
9131 }
9132
Victor Vasiliev7da08172019-10-14 06:04:259133 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:289134 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:459135 return;
9136 }
9137
Nick Harper72ade192019-07-17 03:30:429138 session_params_.quic_params.origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:239139 HostPortPair::FromString("mail.example.org:443"));
9140
Fan Yang32c5a112018-12-10 20:06:339141 const quic::QuicStreamId client_stream_0 =
9142 GetNthClientInitiatedBidirectionalStreamId(0);
9143 const quic::QuicStreamId client_stream_1 =
9144 GetNthClientInitiatedBidirectionalStreamId(1);
9145 const quic::QuicStreamId client_stream_2 =
9146 GetNthClientInitiatedBidirectionalStreamId(2);
9147 const quic::QuicStreamId push_stream_0 =
9148 GetNthServerInitiatedUnidirectionalStreamId(0);
9149 const quic::QuicStreamId push_stream_1 =
9150 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:239151
Ryan Hamiltonabad59e2019-06-06 04:02:599152 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239153 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259154 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239155 mock_quic_data.AddWrite(SYNCHRONOUS,
9156 ConstructInitialSettingsPacket(packet_num++));
9157 }
Yixin Wang385652a2018-02-16 02:37:239158
9159 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:239160 mock_quic_data.AddWrite(
9161 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9162 packet_num++, client_stream_0, true, true, HIGHEST,
9163 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:029164 mock_quic_data.AddWrite(
9165 SYNCHRONOUS,
9166 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239167 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029168 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
9169 mock_quic_data.AddWrite(
9170 SYNCHRONOUS,
9171 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239172 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029173 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:239174
9175 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:029176 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9177 1, client_stream_0, false, false,
9178 GetResponseHeaders("200 OK")));
9179 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9180 2, client_stream_1, false, false,
9181 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239182 mock_quic_data.AddWrite(SYNCHRONOUS,
9183 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:029184 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9185 3, client_stream_2, false, false,
9186 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239187
9188 // Server sends two push promises associated with |client_stream_0|; client
9189 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
9190 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:029191 mock_quic_data.AddRead(
9192 ASYNC,
9193 ConstructServerPushPromisePacket(
9194 4, client_stream_0, push_stream_0, false,
9195 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:239196 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439197 SYNCHRONOUS,
9198 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239199 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439200 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:029201 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
9202 mock_quic_data.AddRead(
9203 ASYNC,
9204 ConstructServerPushPromisePacket(
9205 5, client_stream_0, push_stream_1, false,
9206 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
9207 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:239208 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:029209 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:239210
9211 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:439212 mock_quic_data.AddRead(
9213 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029214 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239215 mock_quic_data.AddWrite(SYNCHRONOUS,
9216 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439217 mock_quic_data.AddRead(
9218 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029219 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239220
9221 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
9222 // priority updates to match the request's priority. Client sends PRIORITY
9223 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:439224 mock_quic_data.AddWrite(
9225 SYNCHRONOUS,
9226 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239227 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439228 {{push_stream_1, client_stream_2,
9229 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
9230 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029231 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:239232
9233 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:439234 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:439235 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179236 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419237 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:439238 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179239 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419240 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:239241 mock_quic_data.AddWrite(SYNCHRONOUS,
9242 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439243 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179244 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:419245 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:439246 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:439247 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179248 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419249 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:239250 mock_quic_data.AddWrite(SYNCHRONOUS,
9251 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439252 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179253 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419254 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:239255
Yixin Wang385652a2018-02-16 02:37:239256 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9257 mock_quic_data.AddRead(ASYNC, 0); // EOF
9258 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9259
9260 // The non-alternate protocol job needs to hang in order to guarantee that
9261 // the alternate-protocol job will "win".
9262 AddHangingNonAlternateProtocolSocketData();
9263
9264 CreateSession();
9265
9266 request_.url = GURL("https://mail.example.org/0.jpg");
9267 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
9268 TestCompletionCallback callback_0;
9269 EXPECT_EQ(ERR_IO_PENDING,
9270 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
9271 base::RunLoop().RunUntilIdle();
9272
9273 request_.url = GURL("https://mail.example.org/1.jpg");
9274 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
9275 TestCompletionCallback callback_1;
9276 EXPECT_EQ(ERR_IO_PENDING,
9277 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
9278 base::RunLoop().RunUntilIdle();
9279
9280 request_.url = GURL("https://mail.example.org/2.jpg");
9281 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
9282 TestCompletionCallback callback_2;
9283 EXPECT_EQ(ERR_IO_PENDING,
9284 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
9285 base::RunLoop().RunUntilIdle();
9286
9287 // Client makes request that matches resource pushed in |pushed_stream_0|.
9288 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
9289 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
9290 TestCompletionCallback callback_3;
9291 EXPECT_EQ(ERR_IO_PENDING,
9292 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9293 base::RunLoop().RunUntilIdle();
9294
9295 EXPECT_TRUE(callback_0.have_result());
9296 EXPECT_EQ(OK, callback_0.WaitForResult());
9297 EXPECT_TRUE(callback_1.have_result());
9298 EXPECT_EQ(OK, callback_1.WaitForResult());
9299 EXPECT_TRUE(callback_2.have_result());
9300 EXPECT_EQ(OK, callback_2.WaitForResult());
9301
9302 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9303 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9304 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9305 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9306
9307 mock_quic_data.Resume();
9308 base::RunLoop().RunUntilIdle();
9309 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9310 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9311}
9312
Matt Menke26e41542019-06-05 01:09:519313// Test that NetworkIsolationKey is respected by QUIC connections, when
9314// kPartitionConnectionsByNetworkIsolationKey is enabled.
9315TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279316 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9317 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9318 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9319 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519320
Nick Harper72ade192019-07-17 03:30:429321 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519322 HostPortPair::FromString("mail.example.org:443"));
9323
9324 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9325 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9326 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9327 // the same way as the HTTP over H2 proxy case.
9328 for (bool use_proxy : {false, true}) {
9329 SCOPED_TRACE(use_proxy);
9330
9331 if (use_proxy) {
9332 proxy_resolution_service_ =
9333 ProxyResolutionService::CreateFixedFromPacResult(
9334 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9335 } else {
9336 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
9337 }
9338
9339 GURL url1;
9340 GURL url2;
9341 GURL url3;
9342 if (use_proxy) {
9343 url1 = GURL("http://mail.example.org/1");
9344 url2 = GURL("http://mail.example.org/2");
9345 url3 = GURL("http://mail.example.org/3");
9346 } else {
9347 url1 = GURL("https://mail.example.org/1");
9348 url2 = GURL("https://mail.example.org/2");
9349 url3 = GURL("https://mail.example.org/3");
9350 }
9351
9352 for (bool partition_connections : {false, true}) {
9353 SCOPED_TRACE(partition_connections);
9354
9355 base::test::ScopedFeatureList feature_list;
9356 if (partition_connections) {
9357 feature_list.InitAndEnableFeature(
9358 features::kPartitionConnectionsByNetworkIsolationKey);
9359 } else {
9360 feature_list.InitAndDisableFeature(
9361 features::kPartitionConnectionsByNetworkIsolationKey);
9362 }
9363
9364 // Reads and writes for the unpartitioned case, where only one socket is
9365 // used.
9366
Nick Harper72ade192019-07-17 03:30:429367 session_params_.quic_params.origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519368 HostPortPair::FromString("mail.example.org:443"));
9369
Ryan Hamiltonabad59e2019-06-06 04:02:599370 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519371 QuicTestPacketMaker client_maker1(
9372 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229373 quic::QuicUtils::CreateRandomConnectionId(
9374 context_.random_generator()),
9375 context_.clock(), kDefaultServerHostName,
9376 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519377 client_headers_include_h2_stream_dependency_);
9378 QuicTestPacketMaker server_maker1(
9379 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229380 quic::QuicUtils::CreateRandomConnectionId(
9381 context_.random_generator()),
9382 context_.clock(), kDefaultServerHostName,
9383 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519384
Renjie Tangaadb84b2019-08-31 01:00:239385 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259386 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239387 unpartitioned_mock_quic_data.AddWrite(
9388 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9389 }
Matt Menke26e41542019-06-05 01:09:519390
9391 unpartitioned_mock_quic_data.AddWrite(
9392 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029393 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239394 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9395 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029396 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519397 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029398 ASYNC, server_maker1.MakeResponseHeadersPacket(
9399 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9400 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519401 unpartitioned_mock_quic_data.AddRead(
9402 ASYNC, server_maker1.MakeDataPacket(
9403 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179404 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519405 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239406 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519407
9408 unpartitioned_mock_quic_data.AddWrite(
9409 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029410 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239411 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9412 false, true,
Matt Menke26e41542019-06-05 01:09:519413 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029414 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519415 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029416 ASYNC, server_maker1.MakeResponseHeadersPacket(
9417 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9418 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519419 unpartitioned_mock_quic_data.AddRead(
9420 ASYNC, server_maker1.MakeDataPacket(
9421 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179422 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519423 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239424 SYNCHRONOUS,
9425 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519426
9427 unpartitioned_mock_quic_data.AddWrite(
9428 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029429 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239430 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9431 false, true,
Matt Menke26e41542019-06-05 01:09:519432 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029433 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519434 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029435 ASYNC, server_maker1.MakeResponseHeadersPacket(
9436 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9437 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519438 unpartitioned_mock_quic_data.AddRead(
9439 ASYNC, server_maker1.MakeDataPacket(
9440 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179441 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519442 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239443 SYNCHRONOUS,
9444 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519445
9446 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9447
9448 // Reads and writes for the partitioned case, where two sockets are used.
9449
Ryan Hamiltonabad59e2019-06-06 04:02:599450 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519451 QuicTestPacketMaker client_maker2(
9452 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229453 quic::QuicUtils::CreateRandomConnectionId(
9454 context_.random_generator()),
9455 context_.clock(), kDefaultServerHostName,
9456 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519457 client_headers_include_h2_stream_dependency_);
9458 QuicTestPacketMaker server_maker2(
9459 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229460 quic::QuicUtils::CreateRandomConnectionId(
9461 context_.random_generator()),
9462 context_.clock(), kDefaultServerHostName,
9463 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519464
Renjie Tangaadb84b2019-08-31 01:00:239465 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259466 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239467 partitioned_mock_quic_data1.AddWrite(
9468 SYNCHRONOUS,
9469 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9470 }
Matt Menke26e41542019-06-05 01:09:519471
9472 partitioned_mock_quic_data1.AddWrite(
9473 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029474 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239475 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9476 true, true,
Matt Menke26e41542019-06-05 01:09:519477 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029478 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519479 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029480 ASYNC, server_maker2.MakeResponseHeadersPacket(
9481 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9482 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519483 partitioned_mock_quic_data1.AddRead(
9484 ASYNC, server_maker2.MakeDataPacket(
9485 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179486 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519487 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239488 SYNCHRONOUS,
9489 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519490
9491 partitioned_mock_quic_data1.AddWrite(
9492 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029493 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239494 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9495 false, true,
Matt Menke26e41542019-06-05 01:09:519496 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029497 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519498 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029499 ASYNC, server_maker2.MakeResponseHeadersPacket(
9500 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9501 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519502 partitioned_mock_quic_data1.AddRead(
9503 ASYNC, server_maker2.MakeDataPacket(
9504 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179505 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519506 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239507 SYNCHRONOUS,
9508 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:519509
9510 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9511
Ryan Hamiltonabad59e2019-06-06 04:02:599512 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519513 QuicTestPacketMaker client_maker3(
9514 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229515 quic::QuicUtils::CreateRandomConnectionId(
9516 context_.random_generator()),
9517 context_.clock(), kDefaultServerHostName,
9518 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519519 client_headers_include_h2_stream_dependency_);
9520 QuicTestPacketMaker server_maker3(
9521 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229522 quic::QuicUtils::CreateRandomConnectionId(
9523 context_.random_generator()),
9524 context_.clock(), kDefaultServerHostName,
9525 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519526
Renjie Tangaadb84b2019-08-31 01:00:239527 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259528 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239529 partitioned_mock_quic_data2.AddWrite(
9530 SYNCHRONOUS,
9531 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9532 }
Matt Menke26e41542019-06-05 01:09:519533
9534 partitioned_mock_quic_data2.AddWrite(
9535 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029536 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239537 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9538 true, true,
Matt Menke26e41542019-06-05 01:09:519539 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029540 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519541 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029542 ASYNC, server_maker3.MakeResponseHeadersPacket(
9543 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9544 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519545 partitioned_mock_quic_data2.AddRead(
9546 ASYNC, server_maker3.MakeDataPacket(
9547 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179548 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519549 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239550 SYNCHRONOUS,
9551 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519552
9553 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9554
9555 if (partition_connections) {
9556 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9557 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9558 } else {
9559 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9560 }
9561
9562 CreateSession();
9563
9564 TestCompletionCallback callback;
9565 HttpRequestInfo request1;
9566 request1.method = "GET";
9567 request1.url = GURL(url1);
9568 request1.traffic_annotation =
9569 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9570 request1.network_isolation_key = network_isolation_key1;
9571 HttpNetworkTransaction trans1(LOWEST, session_.get());
9572 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9573 EXPECT_THAT(callback.GetResult(rv), IsOk());
9574 std::string response_data1;
9575 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9576 EXPECT_EQ("1", response_data1);
9577
9578 HttpRequestInfo request2;
9579 request2.method = "GET";
9580 request2.url = GURL(url2);
9581 request2.traffic_annotation =
9582 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9583 request2.network_isolation_key = network_isolation_key2;
9584 HttpNetworkTransaction trans2(LOWEST, session_.get());
9585 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9586 EXPECT_THAT(callback.GetResult(rv), IsOk());
9587 std::string response_data2;
9588 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9589 EXPECT_EQ("2", response_data2);
9590
9591 HttpRequestInfo request3;
9592 request3.method = "GET";
9593 request3.url = GURL(url3);
9594 request3.traffic_annotation =
9595 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9596 request3.network_isolation_key = network_isolation_key1;
9597 HttpNetworkTransaction trans3(LOWEST, session_.get());
9598 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9599 EXPECT_THAT(callback.GetResult(rv), IsOk());
9600 std::string response_data3;
9601 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9602 EXPECT_EQ("3", response_data3);
9603
9604 if (partition_connections) {
9605 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9606 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9607 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9608 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9609 } else {
9610 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9611 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9612 }
9613 }
9614 }
9615}
9616
9617// Test that two requests to the same origin over QUIC tunnels use different
9618// QUIC sessions if their NetworkIsolationKeys don't match, and
9619// kPartitionConnectionsByNetworkIsolationKey is enabled.
9620TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9621 base::test::ScopedFeatureList feature_list;
9622 feature_list.InitAndEnableFeature(
9623 features::kPartitionConnectionsByNetworkIsolationKey);
9624
9625 session_params_.enable_quic = true;
9626 session_params_.enable_quic_proxies_for_https_urls = true;
9627 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9628 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9629
9630 const char kGetRequest[] =
9631 "GET / HTTP/1.1\r\n"
9632 "Host: mail.example.org\r\n"
9633 "Connection: keep-alive\r\n\r\n";
9634 const char kGetResponse[] =
9635 "HTTP/1.1 200 OK\r\n"
9636 "Content-Length: 10\r\n\r\n";
9637
Ryan Hamiltonabad59e2019-06-06 04:02:599638 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9639 std::make_unique<MockQuicData>(version_),
9640 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519641
9642 for (int index : {0, 1}) {
9643 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229644 version_,
9645 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9646 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519647 client_headers_include_h2_stream_dependency_);
9648 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229649 version_,
9650 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9651 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9652 false);
Matt Menke26e41542019-06-05 01:09:519653
Renjie Tangaadb84b2019-08-31 01:00:239654 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259655 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239656 mock_quic_data[index]->AddWrite(
9657 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9658 }
Matt Menke26e41542019-06-05 01:09:519659
Ryan Hamiltonabad59e2019-06-06 04:02:599660 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519661 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029662 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239663 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9664 false,
Matt Menke26e41542019-06-05 01:09:519665 ConvertRequestPriorityToQuicPriority(
9666 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029667 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599668 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029669 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519670 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9671 false, GetResponseHeaders("200 OK"), nullptr));
9672
9673 std::string header = ConstructDataHeader(strlen(kGetRequest));
9674 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599675 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239676 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9677 packet_num++, false,
9678 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9679 1, false, quic::QuicStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519680 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599681 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239682 SYNCHRONOUS, client_maker.MakeAckAndMultipleDataFramesPacket(
9683 packet_num++, false,
9684 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
9685 1, false, {header, std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519686 }
9687
9688 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599689 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519690 ASYNC, server_maker.MakeDataPacket(
9691 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179692 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599693 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179694 SYNCHRONOUS,
9695 server_maker.MakeDataPacket(
9696 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9697 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599698 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239699 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599700 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9701 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519702
Ryan Hamiltonabad59e2019-06-06 04:02:599703 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519704 }
9705
9706 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9707 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9708 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9709
9710 CreateSession();
9711
9712 request_.url = GURL("https://mail.example.org/");
9713 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9715 RunTransaction(&trans);
9716 CheckResponseData(&trans, "0123456789");
9717
9718 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279719 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9720 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519721 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9722 RunTransaction(&trans2);
9723 CheckResponseData(&trans2, "0123456789");
9724
Ryan Hamiltonabad59e2019-06-06 04:02:599725 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9726 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9727 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9728 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519729}
9730
[email protected]61a527782013-02-21 03:58:009731} // namespace test
9732} // namespace net