blob: b5c21eef951e6217f8c8f9ca12106df04cad580c [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"
Zhongyi Shid1c00fc42019-12-14 06:05:0970#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"
71#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5172#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
73#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
74#include "net/third_party/quiche/src/quic/core/quic_framer.h"
75#include "net/third_party/quiche/src/quic/core/quic_utils.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5176#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) {
Zhongyi Shid1c00fc42019-12-14 06:05:09128 return quiche::QuicheStrCat(
David Schinazi09e9a6012019-10-03 17:37:57129 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 }
Zhongyi Shid1c00fc42019-12-14 06:05:09156 return quiche::QuicheStrCat(
David Schinazi09e9a6012019-10-03 17:37:57157 ParsedQuicVersionToString(p.version), "_", destination_string, "_",
158 (p.client_headers_include_h2_stream_dependency ? "" : "No"),
159 "Dependency");
160}
161
Bence Békyb89104962020-01-24 00:05:17162std::string GenerateQuicAltSvcHeader() {
163 std::string altsvc_header = "Alt-Svc: ";
164 std::string version_string;
165 for (const auto& version : quic::AllSupportedVersions()) {
166 if (version.handshake_protocol == quic::PROTOCOL_TLS1_3) {
167 altsvc_header.append(quic::AlpnForVersion(version));
168 altsvc_header.append("=\":443\", ");
169 } else {
170 if (!version_string.empty()) {
171 version_string.append(",");
172 }
173 version_string.append(base::NumberToString(version.transport_version));
174 }
zhongyie537a002017-06-27 16:48:21175 }
Bence Békyb89104962020-01-24 00:05:17176 altsvc_header.append("quic=\":443\"; v=\"");
177 altsvc_header.append(version_string);
178 altsvc_header.append("\"\r\n");
179
180 return altsvc_header;
zhongyie537a002017-06-27 16:48:21181}
182
David Schinazi09e9a6012019-10-03 17:37:57183std::vector<TestParams> GetTestParams() {
184 std::vector<TestParams> params;
185 quic::ParsedQuicVersionVector all_supported_versions =
186 quic::AllSupportedVersions();
187 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43188 params.push_back(TestParams{version, false});
189 params.push_back(TestParams{version, true});
David Schinazi09e9a6012019-10-03 17:37:57190 }
191 return params;
192}
193
bnc359ed2a2016-04-29 20:43:45194std::vector<PoolingTestParams> GetPoolingTestParams() {
195 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56196 quic::ParsedQuicVersionVector all_supported_versions =
Ryan Hamilton93424eb82019-08-23 04:28:40197 quic::AllSupportedVersions();
Nick Harper23290b82019-05-02 00:02:56198 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Renjie Tang3d8a6ddd2019-11-20 00:18:43199 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
200 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
201 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
202 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
203 params.push_back(PoolingTestParams{version, DIFFERENT, false});
204 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45205 }
206 return params;
207}
bncb07c05532015-05-14 19:07:20208
[email protected]61a527782013-02-21 03:58:00209} // namespace
210
ryansturm49a8cb12016-06-15 16:51:09211class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12212 public:
ryansturm49a8cb12016-06-15 16:51:09213 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12214
ryansturm49a8cb12016-06-15 16:51:09215 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12216
ryansturm49a8cb12016-06-15 16:51:09217 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
218 HttpRequestHeaders* request_headers) {
219 if (!proxy_info.is_http() && !proxy_info.is_https() &&
220 !proxy_info.is_quic()) {
221 return;
222 }
223 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12224 }
225
226 private:
ryansturm49a8cb12016-06-15 16:51:09227 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12228};
229
tbansal0f56a39a2016-04-07 22:03:38230class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40231 public:
tbansal180587c2017-02-16 15:13:23232 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
233 bool* rtt_notification_received)
234 : should_notify_updated_rtt_(should_notify_updated_rtt),
235 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38236 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40237
tbansal180587c2017-02-16 15:13:23238 bool ShouldNotifyUpdatedRTT() const override {
239 return *should_notify_updated_rtt_;
240 }
tbansalfdf5665b2015-09-21 22:46:40241
tbansal0f56a39a2016-04-07 22:03:38242 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
243 *rtt_notification_received_ = true;
244 }
245
246 void OnConnectionChanged() override {}
247
248 private:
tbansal180587c2017-02-16 15:13:23249 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38250 bool* rtt_notification_received_;
251
252 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
253};
254
255class TestSocketPerformanceWatcherFactory
256 : public SocketPerformanceWatcherFactory {
257 public:
258 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23259 : watcher_count_(0u),
260 should_notify_updated_rtt_(true),
261 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38262 ~TestSocketPerformanceWatcherFactory() override {}
263
264 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42265 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41266 const Protocol protocol,
267 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51268 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38269 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51270 }
271 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42272 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23273 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
274 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40275 }
276
tbansalc8a94ea2015-11-02 23:58:51277 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40278
tbansalc8a94ea2015-11-02 23:58:51279 bool rtt_notification_received() const { return rtt_notification_received_; }
280
tbansal180587c2017-02-16 15:13:23281 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
282 should_notify_updated_rtt_ = should_notify_updated_rtt;
283 }
284
tbansalc8a94ea2015-11-02 23:58:51285 private:
tbansal0f56a39a2016-04-07 22:03:38286 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23287 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51288 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38289
290 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51291};
292
Ryan Hamilton8d9ee76e2018-05-29 23:52:52293class QuicNetworkTransactionTest
294 : public PlatformTest,
David Schinazi09e9a6012019-10-03 17:37:57295 public ::testing::WithParamInterface<TestParams>,
Gabriel Charette694c3c332019-08-19 14:53:05296 public WithTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00297 protected:
[email protected]1c04f9522013-02-21 20:32:43298 QuicNetworkTransactionTest()
David Schinazi09e9a6012019-10-03 17:37:57299 : version_(GetParam().version),
300 client_headers_include_h2_stream_dependency_(
301 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:56302 supported_versions_(quic::test::SupportedVersions(version_)),
Victor Vasiliev7752898d2019-11-14 21:30:22303 client_maker_(version_,
304 quic::QuicUtils::CreateRandomConnectionId(
305 context_.random_generator()),
306 context_.clock(),
307 kDefaultServerHostName,
308 quic::Perspective::IS_CLIENT,
309 client_headers_include_h2_stream_dependency_),
310 server_maker_(version_,
311 quic::QuicUtils::CreateRandomConnectionId(
312 context_.random_generator()),
313 context_.clock(),
314 kDefaultServerHostName,
315 quic::Perspective::IS_SERVER,
316 false),
317 quic_task_runner_(new TestTaskRunner(context_.mock_clock())),
rtenneti052774e2015-11-24 21:00:12318 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43319 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59320 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11321 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke3233d8f22019-08-20 21:01:49322 http_server_properties_(std::make_unique<HttpServerProperties>()),
rchf114d982015-10-21 01:34:56323 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19324 request_.method = "GET";
rchf114d982015-10-21 01:34:56325 std::string url("https://");
bncb07c05532015-05-14 19:07:20326 url.append(kDefaultServerHostName);
327 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19328 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10329 request_.traffic_annotation =
330 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Victor Vasiliev7752898d2019-11-14 21:30:22331 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56332
333 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29334 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56335 verify_details_.cert_verify_result.verified_cert = cert;
336 verify_details_.cert_verify_result.is_issued_by_known_root = true;
337 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43338 }
[email protected]61a527782013-02-21 03:58:00339
dcheng67be2b1f2014-10-27 21:47:29340 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00341 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55342 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00343 }
344
dcheng67be2b1f2014-10-27 21:47:29345 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00346 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
347 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55348 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00349 PlatformTest::TearDown();
350 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55351 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40352 session_.reset();
[email protected]61a527782013-02-21 03:58:00353 }
354
Ryan Hamilton8d9ee76e2018-05-29 23:52:52355 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23356 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03357 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52358 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30359 }
360
Ryan Hamilton8d9ee76e2018-05-29 23:52:52361 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23362 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03363 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52364 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58365 }
366
Ryan Hamilton8d9ee76e2018-05-29 23:52:52367 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23368 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20370 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58371 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20372 }
373
Ryan Hamilton8d9ee76e2018-05-29 23:52:52374 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23375 uint64_t packet_number,
376 uint64_t largest_received,
377 uint64_t smallest_received,
378 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37379 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49380 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37381 }
382
Ryan Hamilton8d9ee76e2018-05-29 23:52:52383 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23384 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 quic::QuicStreamId stream_id,
386 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23387 uint64_t largest_received,
388 uint64_t smallest_received,
389 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58390 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49391 num, false, stream_id, error_code, largest_received, smallest_received,
392 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20393 }
394
Ryan Hamilton8d9ee76e2018-05-29 23:52:52395 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23396 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52397 quic::QuicStreamId stream_id,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41398 quic::QuicRstStreamErrorCode error_code) {
Yixin Wang46a273ec302018-01-23 17:59:56399 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18400 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56401 }
402
Ryan Hamilton8d9ee76e2018-05-29 23:52:52403 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23404 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
405 uint64_t largest_received,
406 uint64_t smallest_received,
407 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58408 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49409 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20410 }
[email protected]61a527782013-02-21 03:58:00411
Ryan Hamilton8d9ee76e2018-05-29 23:52:52412 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58413 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23414 uint64_t num,
Fan Yangac867502019-01-28 21:10:23415 uint64_t largest_received,
416 uint64_t smallest_received,
417 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52418 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29419 const std::string& quic_error_details,
420 uint64_t frame_type) {
alyssar2adf3ac2016-05-03 17:12:58421 return client_maker_.MakeAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:53422 num, false, largest_received, smallest_received, least_unacked,
423 quic_error, quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12424 }
425
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23427 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12428 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 quic::QuicStreamId stream_id,
430 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58431 return server_maker_.MakeRstPacket(num, include_version, stream_id,
432 error_code);
zhongyica364fbb2015-12-12 03:39:12433 }
434
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:02436 uint64_t packet_number) {
437 return client_maker_.MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:37438 }
439
Ryan Hamilton8d9ee76e2018-05-29 23:52:52440 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23441 uint64_t packet_number,
442 uint64_t largest_received,
443 uint64_t smallest_received,
444 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37445 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49446 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37447 }
448
Ryan Hamilton8d9ee76e2018-05-29 23:52:52449 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23450 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57451 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52452 quic::QuicStreamId id,
453 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02454 RequestPriority request_priority) {
Yixin Wangb470bc882018-02-15 18:43:57455 return client_maker_.MakePriorityPacket(
456 packet_number, should_include_version, id, parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02457 ConvertRequestPriorityToQuicPriority(request_priority));
Yixin Wang385652a2018-02-16 02:37:23458 }
459
Ryan Hamilton8d9ee76e2018-05-29 23:52:52460 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25461 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23462 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23463 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23464 uint64_t largest_received,
465 uint64_t smallest_received,
466 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25467 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
Ryan Hamilton0d65a8c2019-06-07 00:46:02468 priority_frames) {
Yixin Wange7ecc472018-03-06 19:00:25469 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23470 packet_number, should_include_version, largest_received,
Ryan Hamilton0d65a8c2019-06-07 00:46:02471 smallest_received, least_unacked, priority_frames);
Yixin Wangb470bc882018-02-15 18:43:57472 }
473
zhongyi32569c62016-01-08 02:54:30474 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13475 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
476 const std::string& scheme,
477 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58478 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30479 }
480
481 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13482 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
483 const std::string& scheme,
484 const std::string& path,
485 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50486 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00487 }
488
Ryan Hamilton0239aac2018-05-19 00:03:13489 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56490 return client_maker_.ConnectRequestHeaders(host_port);
491 }
492
Ryan Hamilton0239aac2018-05-19 00:03:13493 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58494 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00495 }
496
zhongyi32569c62016-01-08 02:54:30497 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13498 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
499 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58500 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30501 }
502
Ryan Hamilton8d9ee76e2018-05-29 23:52:52503 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23504 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52505 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05506 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00507 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09508 quiche::QuicheStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17509 return server_maker_.MakeDataPacket(packet_number, stream_id,
510 should_include_version, fin, data);
[email protected]61a527782013-02-21 03:58:00511 }
512
Ryan Hamilton8d9ee76e2018-05-29 23:52:52513 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23514 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36516 bool should_include_version,
517 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09518 quiche::QuicheStringPiece data) {
Ryan Hamilton7505eb92019-06-08 00:22:17519 return client_maker_.MakeDataPacket(packet_number, stream_id,
520 should_include_version, fin, data);
ckrasicda193a82016-07-09 00:39:36521 }
522
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23524 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56525 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52526 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23527 uint64_t largest_received,
528 uint64_t smallest_received,
529 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56530 bool fin,
Zhongyi Shid1c00fc42019-12-14 06:05:09531 quiche::QuicheStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56532 return client_maker_.MakeAckAndDataPacket(
533 packet_number, include_version, stream_id, largest_received,
Ryan Hamilton7505eb92019-06-08 00:22:17534 smallest_received, least_unacked, fin, data);
Yixin Wang46a273ec302018-01-23 17:59:56535 }
536
Ryan Hamilton8d9ee76e2018-05-29 23:52:52537 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23538 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52539 quic::QuicStreamId stream_id,
540 bool should_include_version,
541 bool fin,
542 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56543 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
544 should_include_version, fin,
Ryan Hamilton0d65a8c2019-06-07 00:46:02545 std::move(headers), 0);
Yixin Wang46a273ec302018-01-23 17:59:56546 }
547
Ryan Hamilton8d9ee76e2018-05-29 23:52:52548 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23549 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 quic::QuicStreamId stream_id,
551 bool should_include_version,
552 bool fin,
553 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02554 quic::QuicStreamId parent_stream_id) {
Yixin Wang46a273ec302018-01-23 17:59:56555 return ConstructClientRequestHeadersPacket(
556 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:02557 std::move(headers), parent_stream_id);
zhongyi32569c62016-01-08 02:54:30558 }
559
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23561 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52562 quic::QuicStreamId stream_id,
563 bool should_include_version,
564 bool fin,
565 RequestPriority request_priority,
566 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02567 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13568 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56569 ConvertRequestPriorityToQuicPriority(request_priority);
Ryan Hamilton0d65a8c2019-06-07 00:46:02570 return client_maker_.MakeRequestHeadersPacket(
Yixin Wang46a273ec302018-01-23 17:59:56571 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02572 std::move(headers), parent_stream_id, nullptr);
[email protected]61a527782013-02-21 03:58:00573 }
574
Ryan Hamilton8d9ee76e2018-05-29 23:52:52575 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25576 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23577 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25579 bool should_include_version,
580 bool fin,
581 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13582 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52583 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25584 size_t* spdy_headers_frame_length,
585 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13586 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25587 ConvertRequestPriorityToQuicPriority(request_priority);
588 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
589 packet_number, stream_id, should_include_version, fin, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:02590 std::move(headers), parent_stream_id, spdy_headers_frame_length,
Yixin Wange7ecc472018-03-06 19:00:25591 data_writes);
592 }
593
Ryan Hamilton8d9ee76e2018-05-29 23:52:52594 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23595 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 quic::QuicStreamId stream_id,
597 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13598 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13599 spdy::SpdyHeaderBlock headers,
ckrasic769733c2016-06-30 00:42:13600 QuicTestPacketMaker* maker) {
601 return maker->MakePushPromisePacket(
602 packet_number, stream_id, promised_stream_id, should_include_version,
Ryan Hamilton0d65a8c2019-06-07 00:46:02603 false, std::move(headers), nullptr);
ckrasic769733c2016-06-30 00:42:13604 }
605
Ryan Hamilton8d9ee76e2018-05-29 23:52:52606 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23607 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52608 quic::QuicStreamId stream_id,
609 bool should_include_version,
610 bool fin,
611 spdy::SpdyHeaderBlock headers) {
Ryan Hamilton0d65a8c2019-06-07 00:46:02612 return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id,
613 should_include_version, fin,
614 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30615 }
616
Victor Vasiliev076657c2019-03-12 02:46:43617 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56618 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41619 return "";
620 }
Renjief49758b2019-01-11 23:32:41621 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:57622 auto header_length =
623 quic::HttpEncoder::SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43624 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41625 }
626
Nick Harper23290b82019-05-02 00:02:56627 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41628 session_params_.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:38629 context_.params()->supported_versions = supported_versions;
Victor Vasilieva1e66d72019-12-05 17:55:38630 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:05631 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00632
Victor Vasiliev7752898d2019-11-14 21:30:22633 session_context_.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:41634 session_context_.client_socket_factory = &socket_factory_;
635 session_context_.quic_crypto_client_stream_factory =
636 &crypto_client_stream_factory_;
637 session_context_.host_resolver = &host_resolver_;
638 session_context_.cert_verifier = &cert_verifier_;
639 session_context_.transport_security_state = &transport_security_state_;
640 session_context_.cert_transparency_verifier =
641 cert_transparency_verifier_.get();
642 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
643 session_context_.socket_performance_watcher_factory =
644 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59645 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41646 session_context_.ssl_config_service = ssl_config_service_.get();
647 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
Matt Menke3233d8f22019-08-20 21:01:49648 session_context_.http_server_properties = http_server_properties_.get();
mmenke6ddfbea2017-05-31 21:48:41649 session_context_.net_log = net_log_.bound().net_log();
650
651 session_.reset(new HttpNetworkSession(session_params_, session_context_));
Matt Menkeb566c392019-09-11 23:22:43652 session_->quic_stream_factory()
653 ->set_is_quic_known_to_work_on_current_network(true);
Yixin Wang46a273ec302018-01-23 17:59:56654 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
655 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00656 }
657
zhongyi86838d52017-06-30 01:19:44658 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21659
David Schinazif832cb82019-11-08 22:25:27660 void CheckWasQuicResponse(HttpNetworkTransaction* trans,
661 const std::string& status_line) {
[email protected]aa9b14d2013-05-10 23:45:19662 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42663 ASSERT_TRUE(response != nullptr);
664 ASSERT_TRUE(response->headers.get() != nullptr);
David Schinazif832cb82019-11-08 22:25:27665 EXPECT_EQ(status_line, response->headers->GetStatusLine());
[email protected]aa9b14d2013-05-10 23:45:19666 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52667 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:08668 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19669 response->connection_info);
670 }
671
David Schinazif832cb82019-11-08 22:25:27672 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
673 CheckWasQuicResponse(trans, "HTTP/1.1 200 OK");
674 }
675
bnc691fda62016-08-12 00:43:16676 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41677 const HttpResponseInfo* response = trans->GetResponseInfo();
678 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37679 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41680 }
681
bnc691fda62016-08-12 00:43:16682 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19683 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42684 ASSERT_TRUE(response != nullptr);
685 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19686 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
687 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52688 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52689 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19690 response->connection_info);
691 }
692
Yixin Wang46a273ec302018-01-23 17:59:56693 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
694 const HttpResponseInfo* response = trans->GetResponseInfo();
695 ASSERT_TRUE(response != nullptr);
696 ASSERT_TRUE(response->headers.get() != nullptr);
697 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
698 EXPECT_TRUE(response->was_fetched_via_spdy);
699 EXPECT_TRUE(response->was_alpn_negotiated);
700 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
701 response->connection_info);
702 }
703
bnc691fda62016-08-12 00:43:16704 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19705 const std::string& expected) {
706 std::string response_data;
bnc691fda62016-08-12 00:43:16707 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19708 EXPECT_EQ(expected, response_data);
709 }
710
bnc691fda62016-08-12 00:43:16711 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19712 TestCompletionCallback callback;
713 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
715 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19716 }
717
718 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16719 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
720 RunTransaction(&trans);
721 CheckWasHttpResponse(&trans);
722 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19723 }
724
tbansalc3308d72016-08-27 10:25:04725 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
726 bool used_proxy,
727 uint16_t port) {
728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
729 HeadersHandler headers_handler;
730 trans.SetBeforeHeadersSentCallback(
731 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
732 base::Unretained(&headers_handler)));
733 RunTransaction(&trans);
734 CheckWasHttpResponse(&trans);
735 CheckResponsePort(&trans, port);
736 CheckResponseData(&trans, expected);
737 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47738 if (used_proxy) {
739 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
740 } else {
741 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
742 }
tbansalc3308d72016-08-27 10:25:04743 }
David Schinazif832cb82019-11-08 22:25:27744 void SendRequestAndExpectQuicResponse(const std::string& expected,
745 const std::string& status_line) {
746 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443,
747 status_line);
748 }
tbansalc3308d72016-08-27 10:25:04749
[email protected]aa9b14d2013-05-10 23:45:19750 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56751 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12752 }
753
bnc62a44f022015-04-02 15:59:41754 void SendRequestAndExpectQuicResponseFromProxyOnPort(
755 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46756 uint16_t port) {
bnc62a44f022015-04-02 15:59:41757 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19758 }
759
760 void AddQuicAlternateProtocolMapping(
Matt Menkeb32ba5122019-09-10 19:17:05761 MockCryptoClientStream::HandshakeMode handshake_mode,
762 const NetworkIsolationKey& network_isolation_key =
763 NetworkIsolationKey()) {
[email protected]aa9b14d2013-05-10 23:45:19764 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46765 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21766 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12767 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49768 http_server_properties_->SetQuicAlternativeService(
Matt Menkeb32ba5122019-09-10 19:17:05769 server, network_isolation_key, alternative_service, expiration,
Matt Menke9aa86262019-08-21 15:52:07770 supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19771 }
772
rchbe69cb902016-02-11 01:10:48773 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27774 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48775 const HostPortPair& alternative) {
776 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46777 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21778 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48779 alternative.port());
780 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:49781 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:07782 server, NetworkIsolationKey(), alternative_service, expiration,
783 supported_versions_);
rchbe69cb902016-02-11 01:10:48784 }
785
Matt Menkeb32ba5122019-09-10 19:17:05786 void ExpectBrokenAlternateProtocolMapping(
787 const NetworkIsolationKey& network_isolation_key =
788 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46789 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34790 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49791 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05792 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34793 EXPECT_EQ(1u, alternative_service_info_vector.size());
Matt Menke3233d8f22019-08-20 21:01:49794 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05795 alternative_service_info_vector[0].alternative_service(),
796 network_isolation_key));
[email protected]aa9b14d2013-05-10 23:45:19797 }
798
Matt Menkeb32ba5122019-09-10 19:17:05799 void ExpectQuicAlternateProtocolMapping(
800 const NetworkIsolationKey& network_isolation_key =
801 NetworkIsolationKey()) {
zhongyi3d4a55e72016-04-22 20:36:46802 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34803 const AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:49804 http_server_properties_->GetAlternativeServiceInfos(
Matt Menkeb32ba5122019-09-10 19:17:05805 server, network_isolation_key);
zhongyic4de03032017-05-19 04:07:34806 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54807 EXPECT_EQ(
808 kProtoQUIC,
809 alternative_service_info_vector[0].alternative_service().protocol);
Matt Menke3233d8f22019-08-20 21:01:49810 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
Matt Menkeb32ba5122019-09-10 19:17:05811 alternative_service_info_vector[0].alternative_service(),
812 network_isolation_key));
[email protected]4d590c9c2014-05-02 05:14:33813 }
814
[email protected]aa9b14d2013-05-10 23:45:19815 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42816 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30817 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30818 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30819 hanging_data->set_connect_data(hanging_connect);
820 hanging_data_.push_back(std::move(hanging_data));
821 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56822 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19823 }
824
Zhongyi Shia6b68d112018-09-24 07:49:03825 void SetUpTestForRetryConnectionOnAlternateNetwork() {
Victor Vasilieva1e66d72019-12-05 17:55:38826 context_.params()->migrate_sessions_on_network_change_v2 = true;
827 context_.params()->migrate_sessions_early_v2 = true;
828 context_.params()->retry_on_alternate_network_before_handshake = true;
Zhongyi Shia6b68d112018-09-24 07:49:03829 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
830 MockNetworkChangeNotifier* mock_ncn =
831 scoped_mock_change_notifier_->mock_network_change_notifier();
832 mock_ncn->ForceNetworkHandlesSupported();
833 mock_ncn->SetConnectedNetworksList(
834 {kDefaultNetworkForTests, kNewNetworkForTests});
835 }
836
tbansalc3308d72016-08-27 10:25:04837 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
838 // alternative proxy. Verifies that if the alternative proxy job returns
839 // |error_code|, the request is fetched successfully by the main job.
840 void TestAlternativeProxy(int error_code) {
841 // Use a non-cryptographic scheme for the request URL since this request
842 // will be fetched via proxy with QUIC as the alternative service.
843 request_.url = GURL("http://example.org/");
844 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27845 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04846 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27847 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04848 };
849
Ryan Sleevib8d7ea02018-05-07 20:01:01850 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04851 socket_factory_.AddSocketDataProvider(&quic_data);
852
853 // Main job succeeds and the alternative job fails.
854 // Add data for two requests that will be read by the main job.
855 MockRead http_reads_1[] = {
856 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
857 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
858 MockRead(ASYNC, OK)};
859
860 MockRead http_reads_2[] = {
861 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
862 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
863 MockRead(ASYNC, OK)};
864
Ryan Sleevib8d7ea02018-05-07 20:01:01865 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
866 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04867 socket_factory_.AddSocketDataProvider(&http_data_1);
868 socket_factory_.AddSocketDataProvider(&http_data_2);
869 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
870 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
871
872 TestProxyDelegate test_proxy_delegate;
873 // Proxy URL is different from the request URL.
874 test_proxy_delegate.set_alternative_proxy_server(
875 ProxyServer::FromPacString("QUIC myproxy.org:443"));
876
Lily Houghton8c2f97d2018-01-22 05:06:59877 proxy_resolution_service_ =
878 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49879 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52880 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04881
882 CreateSession();
883 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
884
885 // The first request should be fetched via the HTTPS proxy.
886 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
887
Reilly Grant89a7e512018-01-20 01:57:16888 // Since the main job succeeded only the alternative proxy server should be
889 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59890 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16891 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04892
893 // Verify that the second request completes successfully, and the
894 // alternative proxy server job is not started.
895 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
896 }
897
Matt Menkeb32ba5122019-09-10 19:17:05898 // Adds a new socket data provider for an HTTP request, and runs a request,
899 // expecting it to be used.
900 void AddHttpDataAndRunRequest() {
901 MockWrite http_writes[] = {
902 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
903 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
904 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
905
906 MockRead http_reads[] = {
907 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
908 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
909 MockRead(SYNCHRONOUS, 5, "http used"),
910 // Connection closed.
911 MockRead(SYNCHRONOUS, OK, 6)};
912 SequencedSocketData http_data(http_reads, http_writes);
913 socket_factory_.AddSocketDataProvider(&http_data);
914 SSLSocketDataProvider ssl_data(ASYNC, OK);
915 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
916 SendRequestAndExpectHttpResponse("http used");
917 EXPECT_TRUE(http_data.AllWriteDataConsumed());
918 EXPECT_TRUE(http_data.AllReadDataConsumed());
919 }
920
921 // Adds a new socket data provider for a QUIC request, and runs a request,
922 // expecting it to be used. The new QUIC session is not closed.
923 void AddQuicDataAndRunRequest() {
924 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22925 version_,
926 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
927 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menkeb32ba5122019-09-10 19:17:05928 client_headers_include_h2_stream_dependency_);
929 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:22930 version_,
931 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
932 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
933 false);
Matt Menkeb32ba5122019-09-10 19:17:05934 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:56935 int packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:05936 client_maker.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:25937 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:56938 quic_data.AddWrite(
939 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_number++));
940 }
Matt Menkeb32ba5122019-09-10 19:17:05941 quic_data.AddWrite(
942 SYNCHRONOUS,
943 client_maker.MakeRequestHeadersPacket(
Renjie Tang874398a2019-09-13 18:32:56944 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
945 true, true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Matt Menkeb32ba5122019-09-10 19:17:05946 GetRequestHeaders("GET", "https", "/", &client_maker), 0, nullptr));
947 client_maker.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
948 quic_data.AddRead(
949 ASYNC, server_maker.MakeResponseHeadersPacket(
950 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
951 false, server_maker.GetResponseHeaders("200 OK"), nullptr));
952 std::string header = ConstructDataHeader(9);
953 quic_data.AddRead(
954 ASYNC, server_maker.MakeDataPacket(
955 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
956 true, header + "quic used"));
957 // Don't care about the final ack.
958 quic_data.AddWrite(SYNCHRONOUS, ERR_IO_PENDING);
959 // No more data to read.
960 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
961 quic_data.AddSocketDataToFactory(&socket_factory_);
962 SendRequestAndExpectQuicResponse("quic used");
963
964 EXPECT_TRUE(quic_data.AllReadDataConsumed());
965 }
966
Bence Béky6e243aa2019-12-13 19:01:07967 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56968 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
969 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36970 }
971
Bence Béky6e243aa2019-12-13 19:01:07972 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) const {
Nick Harper23290b82019-05-02 00:02:56973 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
974 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36975 }
976
Bence Béky6e243aa2019-12-13 19:01:07977 quic::QuicStreamId GetQpackDecoderStreamId() const {
978 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
979 version_.transport_version, 1);
980 }
981
982 std::string StreamCancellationQpackDecoderInstruction(int n) const {
983 const quic::QuicStreamId cancelled_stream_id =
984 GetNthClientInitiatedBidirectionalStreamId(n);
985 EXPECT_LT(cancelled_stream_id, 63u);
986
987 const unsigned char opcode = 0x40;
988 return {opcode | static_cast<unsigned char>(cancelled_stream_id)};
989 }
990
Bence Béky230ac612017-08-30 19:17:08991 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49992 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08993 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49994 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08995 }
996
Nick Harper23290b82019-05-02 00:02:56997 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05998 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56999 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:011000 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Victor Vasiliev7752898d2019-11-14 21:30:221001 MockQuicContext context_;
alyssar2adf3ac2016-05-03 17:12:581002 QuicTestPacketMaker client_maker_;
1003 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:091004 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:421005 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:001006 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:561007 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:051008 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:431009 MockHostResolver host_resolver_;
1010 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:111011 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:421012 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:231013 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:381014 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:071015 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:591016 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:421017 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke3233d8f22019-08-20 21:01:491018 std::unique_ptr<HttpServerProperties> http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:411019 HttpNetworkSession::Params session_params_;
1020 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:191021 HttpRequestInfo request_;
Matt Muellerd9342e3a2019-11-26 01:41:141022 RecordingBoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:421023 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:561024 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:031025 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:121026
1027 private:
1028 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1029 const std::string& expected,
bnc62a44f022015-04-02 15:59:411030 bool used_proxy,
David Schinazif832cb82019-11-08 22:25:271031 uint16_t port,
1032 const std::string& status_line) {
bnc691fda62016-08-12 00:43:161033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:091034 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:161035 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091036 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
1037 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:161038 RunTransaction(&trans);
David Schinazif832cb82019-11-08 22:25:271039 CheckWasQuicResponse(&trans, status_line);
bnc691fda62016-08-12 00:43:161040 CheckResponsePort(&trans, port);
1041 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091042 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471043 if (used_proxy) {
1044 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1045 } else {
1046 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1047 }
tbansal7cec3812015-02-05 21:25:121048 }
David Schinazif832cb82019-11-08 22:25:271049
1050 void SendRequestAndExpectQuicResponseMaybeFromProxy(
1051 const std::string& expected,
1052 bool used_proxy,
1053 uint16_t port) {
1054 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, used_proxy, port,
1055 "HTTP/1.1 200 OK");
1056 }
[email protected]61a527782013-02-21 03:58:001057};
1058
David Schinazi09e9a6012019-10-03 17:37:571059INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
1060 QuicNetworkTransactionTest,
1061 ::testing::ValuesIn(GetTestParams()),
1062 ::testing::PrintToStringParamName());
[email protected]1e960032013-12-20 19:00:201063
Shivani Sharma8ae506c2019-07-21 21:08:271064// TODO(950069): Add testing for frame_origin in NetworkIsolationKey using
1065// kAppendInitiatingFrameOriginToNetworkIsolationKey.
1066
Ryan Hamiltona64a5bcf2017-11-30 07:35:281067TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Victor Vasilieva1e66d72019-12-05 17:55:381068 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281069 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381070 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281071 HostPortPair::FromString("mail.example.org:443"));
1072 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271073 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281074
Ryan Hamiltonabad59e2019-06-06 04:02:591075 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251076 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231077 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281078 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1079 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1080 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1081
1082 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1083
1084 CreateSession();
1085
1086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1087 TestCompletionCallback callback;
1088 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1089 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1090 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1091
1092 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1093 -ERR_INTERNET_DISCONNECTED, 1);
1094 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1095 -ERR_INTERNET_DISCONNECTED, 1);
1096}
1097
1098TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Victor Vasilieva1e66d72019-12-05 17:55:381099 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281100 base::HistogramTester histograms;
Victor Vasilieva1e66d72019-12-05 17:55:381101 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamiltona64a5bcf2017-11-30 07:35:281102 HostPortPair::FromString("mail.example.org:443"));
1103 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271104 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281105
Ryan Hamiltonabad59e2019-06-06 04:02:591106 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:251107 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231108 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281109 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1110 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1111 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1112
1113 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1114
1115 CreateSession();
1116
1117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1118 TestCompletionCallback callback;
1119 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1121 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1122
1123 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1124 -ERR_INTERNET_DISCONNECTED, 1);
1125 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1126 -ERR_INTERNET_DISCONNECTED, 1);
1127}
1128
tbansal180587c2017-02-16 15:13:231129TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381130 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231131 HostPortPair::FromString("mail.example.org:443"));
1132
Ryan Hamiltonabad59e2019-06-06 04:02:591133 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231134 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251135 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231136 mock_quic_data.AddWrite(SYNCHRONOUS,
1137 ConstructInitialSettingsPacket(packet_num++));
1138 }
rch5cb522462017-04-25 20:18:361139 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231140 SYNCHRONOUS,
1141 ConstructClientRequestHeadersPacket(
1142 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1143 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431144 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331145 ASYNC, ConstructServerResponseHeadersPacket(
1146 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1147 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431148 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331149 mock_quic_data.AddRead(
1150 ASYNC, ConstructServerDataPacket(
1151 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171152 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231153 mock_quic_data.AddWrite(SYNCHRONOUS,
1154 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231155 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1156
1157 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1158
1159 CreateSession();
1160 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1161
1162 EXPECT_FALSE(
1163 test_socket_performance_watcher_factory_.rtt_notification_received());
1164 SendRequestAndExpectQuicResponse("hello!");
1165 EXPECT_TRUE(
1166 test_socket_performance_watcher_factory_.rtt_notification_received());
1167}
1168
1169TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
Victor Vasilieva1e66d72019-12-05 17:55:381170 context_.params()->origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231171 HostPortPair::FromString("mail.example.org:443"));
1172
Ryan Hamiltonabad59e2019-06-06 04:02:591173 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231174 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251175 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231176 mock_quic_data.AddWrite(SYNCHRONOUS,
1177 ConstructInitialSettingsPacket(packet_num++));
1178 }
rch5cb522462017-04-25 20:18:361179 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231180 SYNCHRONOUS,
1181 ConstructClientRequestHeadersPacket(
1182 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1183 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431184 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331185 ASYNC, ConstructServerResponseHeadersPacket(
1186 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1187 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431188 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331189 mock_quic_data.AddRead(
1190 ASYNC, ConstructServerDataPacket(
1191 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171192 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231193 mock_quic_data.AddWrite(SYNCHRONOUS,
1194 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231195 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1196
1197 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1198
1199 CreateSession();
1200 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1201
1202 EXPECT_FALSE(
1203 test_socket_performance_watcher_factory_.rtt_notification_received());
1204 SendRequestAndExpectQuicResponse("hello!");
1205 EXPECT_FALSE(
1206 test_socket_performance_watcher_factory_.rtt_notification_received());
1207}
1208
[email protected]1e960032013-12-20 19:00:201209TEST_P(QuicNetworkTransactionTest, ForceQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:381210 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571211 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471212
Ryan Hamiltonabad59e2019-06-06 04:02:591213 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231214 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251215 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231216 mock_quic_data.AddWrite(SYNCHRONOUS,
1217 ConstructInitialSettingsPacket(packet_num++));
1218 }
rch5cb522462017-04-25 20:18:361219 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231220 SYNCHRONOUS,
1221 ConstructClientRequestHeadersPacket(
1222 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1223 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431224 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331225 ASYNC, ConstructServerResponseHeadersPacket(
1226 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1227 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431228 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331229 mock_quic_data.AddRead(
1230 ASYNC, ConstructServerDataPacket(
1231 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171232 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231233 mock_quic_data.AddWrite(SYNCHRONOUS,
1234 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591235 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471236
rcha5399e02015-04-21 19:32:041237 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471238
[email protected]4dca587c2013-03-07 16:54:471239 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471240
[email protected]aa9b14d2013-05-10 23:45:191241 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471242
[email protected]98b20ce2013-05-10 05:55:261243 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:541244 auto entries = net_log_.GetEntries();
[email protected]98b20ce2013-05-10 05:55:261245 EXPECT_LT(0u, entries.size());
1246
1247 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291248 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001249 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1250 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261251 EXPECT_LT(0, pos);
1252
rchfd527212015-08-25 00:41:261253 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291254 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261255 entries, 0,
mikecirone8b85c432016-09-08 19:11:001256 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1257 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261258 EXPECT_LT(0, pos);
1259
Eric Roman79cc7552019-07-19 02:17:541260 EXPECT_EQ(1, GetIntegerValueFromParams(entries[pos], "packet_number"));
[email protected]98b20ce2013-05-10 05:55:261261
rchfd527212015-08-25 00:41:261262 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1263 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001264 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1265 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261266 EXPECT_LT(0, pos);
1267
[email protected]98b20ce2013-05-10 05:55:261268 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291269 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001270 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1271 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261272 EXPECT_LT(0, pos);
1273
Eric Roman79cc7552019-07-19 02:17:541274 int log_stream_id = GetIntegerValueFromParams(entries[pos], "stream_id");
Victor Vasiliev7da08172019-10-14 06:04:251275 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451276 EXPECT_EQ(GetNthClientInitiatedBidirectionalStreamId(0),
1277 static_cast<quic::QuicStreamId>(log_stream_id));
1278 } else {
1279 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1280 static_cast<quic::QuicStreamId>(log_stream_id));
1281 }
[email protected]4dca587c2013-03-07 16:54:471282}
1283
Bence Békyb6300042020-01-28 21:18:201284// Regression test for https://crbug.com/1043531.
1285TEST_P(QuicNetworkTransactionTest, ResetOnEmptyResponseHeaders) {
1286 if (!quic::VersionUsesHttp3(version_.transport_version)) {
1287 return;
1288 }
1289
1290 context_.params()->origins_to_force_quic_on.insert(
1291 HostPortPair::FromString("mail.example.org:443"));
1292
1293 MockQuicData mock_quic_data(version_);
1294 int write_packet_num = 1;
1295 mock_quic_data.AddWrite(SYNCHRONOUS,
1296 ConstructInitialSettingsPacket(write_packet_num++));
1297 mock_quic_data.AddWrite(
1298 SYNCHRONOUS,
1299 ConstructClientRequestHeadersPacket(
1300 write_packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
1301 true, true, GetRequestHeaders("GET", "https", "/")));
1302
1303 const quic::QuicStreamId request_stream_id =
1304 GetNthClientInitiatedBidirectionalStreamId(0);
1305 spdy::SpdyHeaderBlock empty_response_headers;
1306 const std::string response_data = server_maker_.QpackEncodeHeaders(
1307 request_stream_id, std::move(empty_response_headers), nullptr);
1308 uint64_t read_packet_num = 1;
1309 mock_quic_data.AddRead(
1310 ASYNC, ConstructServerDataPacket(read_packet_num++, request_stream_id,
1311 false, false, response_data));
1312 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1313
1314 mock_quic_data.AddWrite(
1315 ASYNC,
1316 ConstructClientAckAndDataPacket(
1317 write_packet_num++, true, GetQpackDecoderStreamId(), 1, 1, 1, false,
1318 StreamCancellationQpackDecoderInstruction(request_stream_id)));
1319
1320 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1321
1322 CreateSession();
1323
1324 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1325 TestCompletionCallback callback;
1326 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1327 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1328 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_INVALID_RESPONSE));
1329}
1330
rchbd089ab2017-05-26 23:05:041331TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381332 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041333 HostPortPair::FromString("mail.example.org:443"));
1334
Ryan Hamiltonabad59e2019-06-06 04:02:591335 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231336 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251337 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231338 mock_quic_data.AddWrite(SYNCHRONOUS,
1339 ConstructInitialSettingsPacket(packet_num++));
1340 }
rchbd089ab2017-05-26 23:05:041341 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231342 SYNCHRONOUS,
1343 ConstructClientRequestHeadersPacket(
1344 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1345 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0239aac2018-05-19 00:03:131346 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041347 response_headers["key1"] = std::string(30000, 'A');
1348 response_headers["key2"] = std::string(30000, 'A');
1349 response_headers["key3"] = std::string(30000, 'A');
1350 response_headers["key4"] = std::string(30000, 'A');
1351 response_headers["key5"] = std::string(30000, 'A');
1352 response_headers["key6"] = std::string(30000, 'A');
1353 response_headers["key7"] = std::string(30000, 'A');
1354 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451355 quic::QuicStreamId stream_id;
1356 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251357 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451358 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281359 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451360 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451361 } else {
1362 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1363 spdy::SpdyHeadersIR headers_frame(
1364 GetNthClientInitiatedBidirectionalStreamId(0),
1365 std::move(response_headers));
1366 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1367 spdy::SpdySerializedFrame spdy_frame =
1368 response_framer.SerializeFrame(headers_frame);
1369 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1370 }
rchbd089ab2017-05-26 23:05:041371
Fan Yangac867502019-01-28 21:10:231372 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041373 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451374 for (size_t offset = 0; offset < response_data.length();
1375 offset += chunk_size) {
1376 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431377 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451378 ASYNC, ConstructServerDataPacket(
1379 packet_number++, stream_id, false, false,
1380 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041381 }
1382
Victor Vasiliev076657c2019-03-12 02:46:431383 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041384 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331385 ASYNC, ConstructServerDataPacket(
1386 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171387 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041388 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431389 mock_quic_data.AddWrite(ASYNC,
Renjie Tangaadb84b2019-08-31 01:00:231390 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1391 mock_quic_data.AddWrite(
1392 ASYNC, ConstructClientAckPacket(packet_num++, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041393
1394 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1395
1396 CreateSession();
1397
1398 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421399 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1400 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041401}
1402
1403TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Victor Vasilieva1e66d72019-12-05 17:55:381404 context_.params()->retry_without_alt_svc_on_quic_errors = false;
1405 context_.params()->origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041406 HostPortPair::FromString("mail.example.org:443"));
1407
Ryan Hamiltonabad59e2019-06-06 04:02:591408 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231409 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251410 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231411 mock_quic_data.AddWrite(SYNCHRONOUS,
1412 ConstructInitialSettingsPacket(packet_num++));
1413 }
rchbd089ab2017-05-26 23:05:041414 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231415 SYNCHRONOUS,
1416 ConstructClientRequestHeadersPacket(
1417 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1418 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamiltone940bd12019-06-30 02:46:451419
Ryan Hamilton0239aac2018-05-19 00:03:131420 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041421 response_headers["key1"] = std::string(30000, 'A');
1422 response_headers["key2"] = std::string(30000, 'A');
1423 response_headers["key3"] = std::string(30000, 'A');
1424 response_headers["key4"] = std::string(30000, 'A');
1425 response_headers["key5"] = std::string(30000, 'A');
1426 response_headers["key6"] = std::string(30000, 'A');
1427 response_headers["key7"] = std::string(30000, 'A');
1428 response_headers["key8"] = std::string(30000, 'A');
1429 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamiltone940bd12019-06-30 02:46:451430
1431 quic::QuicStreamId stream_id;
1432 std::string response_data;
Victor Vasiliev7da08172019-10-14 06:04:251433 if (quic::VersionUsesHttp3(version_.transport_version)) {
Ryan Hamiltone940bd12019-06-30 02:46:451434 stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Renjie Tangd5133972019-12-06 00:20:281435 response_data = server_maker_.QpackEncodeHeaders(
Ryan Hamiltone940bd12019-06-30 02:46:451436 stream_id, std::move(response_headers), nullptr);
Ryan Hamiltone940bd12019-06-30 02:46:451437 } else {
1438 stream_id = quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1439 spdy::SpdyHeadersIR headers_frame(
1440 GetNthClientInitiatedBidirectionalStreamId(0),
1441 std::move(response_headers));
1442 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1443 spdy::SpdySerializedFrame spdy_frame =
1444 response_framer.SerializeFrame(headers_frame);
1445 response_data = std::string(spdy_frame.data(), spdy_frame.size());
1446 }
rchbd089ab2017-05-26 23:05:041447
Fan Yangac867502019-01-28 21:10:231448 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041449 size_t chunk_size = 1200;
Ryan Hamiltone940bd12019-06-30 02:46:451450 for (size_t offset = 0; offset < response_data.length();
1451 offset += chunk_size) {
1452 size_t len = std::min(chunk_size, response_data.length() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431453 mock_quic_data.AddRead(
Ryan Hamiltone940bd12019-06-30 02:46:451454 ASYNC, ConstructServerDataPacket(
1455 packet_number++, stream_id, false, false,
1456 base::StringPiece(response_data.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041457 }
1458
Victor Vasiliev076657c2019-03-12 02:46:431459 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411460
rchbd089ab2017-05-26 23:05:041461 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331462 ASYNC, ConstructServerDataPacket(
1463 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:171464 false, true, header + "hello!"));
rchbd089ab2017-05-26 23:05:041465 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:231466 mock_quic_data.AddWrite(ASYNC,
1467 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:431468 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331469 ASYNC, ConstructClientAckAndRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:231470 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
Fan Yang32c5a112018-12-10 20:06:331471 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041472
1473 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1474
1475 CreateSession();
1476
1477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1478 TestCompletionCallback callback;
1479 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1481 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1482}
1483
rcha2bd44b2016-07-02 00:42:551484TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
Victor Vasilieva1e66d72019-12-05 17:55:381485 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551486
Ryan Hamilton9835e662018-08-02 05:36:271487 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551488
Ryan Hamiltonabad59e2019-06-06 04:02:591489 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231490 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251491 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231492 mock_quic_data.AddWrite(SYNCHRONOUS,
1493 ConstructInitialSettingsPacket(packet_num++));
1494 }
rch5cb522462017-04-25 20:18:361495 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231496 SYNCHRONOUS,
1497 ConstructClientRequestHeadersPacket(
1498 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1499 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431500 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331501 ASYNC, ConstructServerResponseHeadersPacket(
1502 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1503 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431504 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331505 mock_quic_data.AddRead(
1506 ASYNC, ConstructServerDataPacket(
1507 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171508 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231509 mock_quic_data.AddWrite(SYNCHRONOUS,
1510 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551511 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1512
1513 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1514
1515 CreateSession();
1516
1517 SendRequestAndExpectQuicResponse("hello!");
1518 EXPECT_TRUE(
1519 test_socket_performance_watcher_factory_.rtt_notification_received());
1520}
1521
David Schinazif832cb82019-11-08 22:25:271522// Regression test for https://crbug.com/695225
1523TEST_P(QuicNetworkTransactionTest, 408Response) {
Victor Vasilieva1e66d72019-12-05 17:55:381524 context_.params()->origins_to_force_quic_on.insert(HostPortPair());
David Schinazif832cb82019-11-08 22:25:271525
1526 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
1527
1528 MockQuicData mock_quic_data(version_);
1529 int packet_num = 1;
1530 if (VersionUsesHttp3(version_.transport_version)) {
1531 mock_quic_data.AddWrite(SYNCHRONOUS,
1532 ConstructInitialSettingsPacket(packet_num++));
1533 }
1534 mock_quic_data.AddWrite(
1535 SYNCHRONOUS,
1536 ConstructClientRequestHeadersPacket(
1537 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1538 true, GetRequestHeaders("GET", "https", "/")));
1539 mock_quic_data.AddRead(
1540 ASYNC, ConstructServerResponseHeadersPacket(
1541 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1542 GetResponseHeaders("408 Request Timeout")));
1543 std::string header = ConstructDataHeader(6);
1544 mock_quic_data.AddRead(
1545 ASYNC, ConstructServerDataPacket(
1546 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1547 header + "hello!"));
1548 mock_quic_data.AddWrite(SYNCHRONOUS,
1549 ConstructClientAckPacket(packet_num++, 2, 1, 1));
1550 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1551
1552 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1553
1554 CreateSession();
1555
1556 SendRequestAndExpectQuicResponse("hello!", "HTTP/1.1 408 Request Timeout");
1557}
1558
[email protected]cf3e3cd62014-02-05 16:16:161559TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411560 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591561 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491562 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161563
Ryan Hamiltonabad59e2019-06-06 04:02:591564 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231565 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251566 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231567 mock_quic_data.AddWrite(SYNCHRONOUS,
1568 ConstructInitialSettingsPacket(packet_num++));
1569 }
rch5cb522462017-04-25 20:18:361570 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231571 SYNCHRONOUS,
1572 ConstructClientRequestHeadersPacket(
1573 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1574 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431575 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331576 ASYNC, ConstructServerResponseHeadersPacket(
1577 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1578 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431579 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331580 mock_quic_data.AddRead(
1581 ASYNC, ConstructServerDataPacket(
1582 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171583 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231584 mock_quic_data.AddWrite(SYNCHRONOUS,
1585 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501586 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591587 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161588
rcha5399e02015-04-21 19:32:041589 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161590
tbansal0f56a39a2016-04-07 22:03:381591 EXPECT_FALSE(
1592 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161593 // There is no need to set up an alternate protocol job, because
1594 // no attempt will be made to speak to the proxy over TCP.
1595
rch9ae5b3b2016-02-11 00:36:291596 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161597 CreateSession();
1598
bnc62a44f022015-04-02 15:59:411599 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381600 EXPECT_TRUE(
1601 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161602}
1603
bnc313ba9c2015-06-11 15:42:311604// Regression test for https://crbug.com/492458. Test that for an HTTP
1605// connection through a QUIC proxy, the certificate exhibited by the proxy is
1606// checked against the proxy hostname, not the origin hostname.
1607TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291608 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311609 const std::string proxy_host = "www.example.org";
1610
mmenke6ddfbea2017-05-31 21:48:411611 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591612 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491613 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311614
alyssar2adf3ac2016-05-03 17:12:581615 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591616 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231617 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251618 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231619 mock_quic_data.AddWrite(SYNCHRONOUS,
1620 ConstructInitialSettingsPacket(packet_num++));
1621 }
rch5cb522462017-04-25 20:18:361622 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231623 SYNCHRONOUS,
1624 ConstructClientRequestHeadersPacket(
1625 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1626 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431627 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331628 ASYNC, ConstructServerResponseHeadersPacket(
1629 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1630 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431631 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331632 mock_quic_data.AddRead(
1633 ASYNC, ConstructServerDataPacket(
1634 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171635 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231636 mock_quic_data.AddWrite(SYNCHRONOUS,
1637 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:501638 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591639 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311640 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1641
1642 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291643 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311644 ASSERT_TRUE(cert.get());
1645 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241646 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1647 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311648 ProofVerifyDetailsChromium verify_details;
1649 verify_details.cert_verify_result.verified_cert = cert;
1650 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561651 ProofVerifyDetailsChromium verify_details2;
1652 verify_details2.cert_verify_result.verified_cert = cert;
1653 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311654
1655 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091656 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321657 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271658 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311659 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1660}
1661
rchbe69cb902016-02-11 01:10:481662TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Victor Vasilieva1e66d72019-12-05 17:55:381663 context_.params()->allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481664 HostPortPair origin("www.example.org", 443);
1665 HostPortPair alternative("mail.example.org", 443);
1666
1667 base::FilePath certs_dir = GetTestCertsDirectory();
1668 scoped_refptr<X509Certificate> cert(
1669 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1670 ASSERT_TRUE(cert.get());
1671 // TODO(rch): the connection should be "to" the origin, so if the cert is
1672 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241673 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1674 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481675 ProofVerifyDetailsChromium verify_details;
1676 verify_details.cert_verify_result.verified_cert = cert;
1677 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1678
alyssar2adf3ac2016-05-03 17:12:581679 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591680 MockQuicData mock_quic_data(version_);
Ryan Hamilton0d65a8c2019-06-07 00:46:021681
Renjie Tangaadb84b2019-08-31 01:00:231682 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251683 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231684 mock_quic_data.AddWrite(SYNCHRONOUS,
1685 ConstructInitialSettingsPacket(packet_num++));
1686 }
rch5cb522462017-04-25 20:18:361687 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231688 SYNCHRONOUS,
1689 ConstructClientRequestHeadersPacket(
1690 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1691 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431692 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331693 ASYNC, ConstructServerResponseHeadersPacket(
1694 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1695 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431696 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331697 mock_quic_data.AddRead(
1698 ASYNC, ConstructServerDataPacket(
1699 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171700 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231701 mock_quic_data.AddWrite(SYNCHRONOUS,
1702 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481703 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1704 mock_quic_data.AddRead(ASYNC, 0);
1705 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1706
1707 request_.url = GURL("https://" + origin.host());
1708 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271709 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091710 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321711 CreateSession();
rchbe69cb902016-02-11 01:10:481712
1713 SendRequestAndExpectQuicResponse("hello!");
1714}
1715
zhongyief3f4ce52017-07-05 23:53:281716TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561717 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
Bence Békyb89104962020-01-24 00:05:171718 // Add support for another QUIC version besides |version_|. Also find an
zhongyief3f4ce52017-07-05 23:53:281719 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561720 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281721 if (version == version_)
1722 continue;
1723 if (supported_versions_.size() != 2) {
1724 supported_versions_.push_back(version);
1725 continue;
1726 }
1727 unsupported_version = version;
1728 break;
1729 }
Bence Békyb89104962020-01-24 00:05:171730 ASSERT_EQ(2u, supported_versions_.size());
1731 ASSERT_NE(quic::UnsupportedQuicVersion(), unsupported_version);
zhongyief3f4ce52017-07-05 23:53:281732
1733 // Set up alternative service to use QUIC with a version that is not
1734 // supported.
1735 url::SchemeHostPort server(request_.url);
1736 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1737 443);
1738 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491739 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071740 server, NetworkIsolationKey(), alternative_service, expiration,
1741 {unsupported_version});
zhongyief3f4ce52017-07-05 23:53:281742
1743 AlternativeServiceInfoVector alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491744 http_server_properties_->GetAlternativeServiceInfos(
1745 server, NetworkIsolationKey());
zhongyief3f4ce52017-07-05 23:53:281746 EXPECT_EQ(1u, alt_svc_info_vector.size());
1747 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1748 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1749 EXPECT_EQ(unsupported_version,
1750 alt_svc_info_vector[0].advertised_versions()[0]);
1751
1752 // First request should still be sent via TCP as the QUIC version advertised
1753 // in the stored AlternativeService is not supported by the client. However,
1754 // the response from the server will advertise new Alt-Svc with supported
1755 // versions.
Bence Békyb89104962020-01-24 00:05:171756 std::string altsvc_header = GenerateQuicAltSvcHeader();
zhongyief3f4ce52017-07-05 23:53:281757 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:171758 MockRead("HTTP/1.1 200 OK\r\n"),
1759 MockRead(altsvc_header.c_str()),
1760 MockRead("\r\n"),
zhongyief3f4ce52017-07-05 23:53:281761 MockRead("hello world"),
1762 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1763 MockRead(ASYNC, OK)};
1764
Ryan Sleevib8d7ea02018-05-07 20:01:011765 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281766 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081767 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281768 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1769
1770 // Second request should be sent via QUIC as a new list of verions supported
1771 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591772 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231773 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251774 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231775 mock_quic_data.AddWrite(SYNCHRONOUS,
1776 ConstructInitialSettingsPacket(packet_num++));
1777 }
zhongyief3f4ce52017-07-05 23:53:281778 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231779 SYNCHRONOUS,
1780 ConstructClientRequestHeadersPacket(
1781 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1782 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431783 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331784 ASYNC, ConstructServerResponseHeadersPacket(
1785 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1786 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431787 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331788 mock_quic_data.AddRead(
1789 ASYNC, ConstructServerDataPacket(
1790 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:171791 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:231792 mock_quic_data.AddWrite(SYNCHRONOUS,
1793 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281794 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1795 mock_quic_data.AddRead(ASYNC, 0); // EOF
1796
1797 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1798
1799 AddHangingNonAlternateProtocolSocketData();
1800
1801 CreateSession(supported_versions_);
1802
1803 SendRequestAndExpectHttpResponse("hello world");
1804 SendRequestAndExpectQuicResponse("hello!");
1805
1806 // Check alternative service list is updated with new versions.
1807 alt_svc_info_vector =
Matt Menke3233d8f22019-08-20 21:01:491808 session_->http_server_properties()->GetAlternativeServiceInfos(
1809 server, NetworkIsolationKey());
Bence Békyb89104962020-01-24 00:05:171810 // All PROTOCOL_QUIC_CRYPTO versions are sent in a single Alt-Svc entry,
1811 // therefore they aer accumulated in a single AlternativeServiceInfo, whereas
1812 // each PROTOCOL_TLS1_3 version has its own Alt-Svc entry and
1813 // AlternativeServiceInfo entry. Flatten to compare.
1814 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
1815 for (const auto& alt_svc_info : alt_svc_info_vector) {
1816 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
1817 for (const auto& version : alt_svc_info.advertised_versions()) {
1818 alt_svc_negotiated_versions.push_back(version);
1819 }
1820 }
1821
1822 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
1823 auto version_compare = [](const quic::ParsedQuicVersion& a,
1824 const quic::ParsedQuicVersion& b) {
1825 return std::tie(a.transport_version, a.handshake_protocol) <
1826 std::tie(b.transport_version, b.handshake_protocol);
1827 };
1828 std::sort(supported_versions_.begin(), supported_versions_.end(),
1829 version_compare);
1830 std::sort(alt_svc_negotiated_versions.begin(),
1831 alt_svc_negotiated_versions.end(), version_compare);
1832 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
1833 alt_svc_negotiated_versions.begin()));
zhongyief3f4ce52017-07-05 23:53:281834}
1835
bncaccd4962017-04-06 21:00:261836// Regression test for https://crbug.com/546991.
1837// The server might not be able to serve a request on an alternative connection,
1838// and might send a 421 Misdirected Request response status to indicate this.
1839// HttpNetworkTransaction should reset the request and retry without using
1840// alternative services.
1841TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1842 // Set up alternative service to use QUIC.
1843 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1844 // that overrides |enable_alternative_services|.
1845 url::SchemeHostPort server(request_.url);
1846 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1847 443);
1848 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:491849 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:071850 server, NetworkIsolationKey(), alternative_service, expiration,
1851 supported_versions_);
bncaccd4962017-04-06 21:00:261852
davidbena4449722017-05-05 23:30:531853 // First try: The alternative job uses QUIC and reports an HTTP 421
1854 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1855 // paused at Connect(), so it will never exit the socket pool. This ensures
1856 // that the alternate job always wins the race and keeps whether the
1857 // |http_data| exits the socket pool before the main job is aborted
1858 // deterministic. The first main job gets aborted without the socket pool ever
1859 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591860 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231861 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251862 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231863 mock_quic_data.AddWrite(SYNCHRONOUS,
1864 ConstructInitialSettingsPacket(packet_num++));
1865 }
rch5cb522462017-04-25 20:18:361866 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231867 SYNCHRONOUS,
1868 ConstructClientRequestHeadersPacket(
1869 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1870 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:331871 mock_quic_data.AddRead(
1872 ASYNC, ConstructServerResponseHeadersPacket(
1873 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton0d65a8c2019-06-07 00:46:021874 GetResponseHeaders("421")));
bncaccd4962017-04-06 21:00:261875 mock_quic_data.AddRead(ASYNC, OK);
1876 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1877
davidbena4449722017-05-05 23:30:531878 // Second try: The main job uses TCP, and there is no alternate job. Once the
1879 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1880 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261881 // Note that if there was an alternative QUIC Job created for the second try,
1882 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1883 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531884 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1885 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1886 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1887 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1888 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1889 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011890 reads, writes);
bncaccd4962017-04-06 21:00:261891 socket_factory_.AddSocketDataProvider(&http_data);
1892 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1893
bncaccd4962017-04-06 21:00:261894 CreateSession();
1895 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531896
1897 // Run until |mock_quic_data| has failed and |http_data| has paused.
1898 TestCompletionCallback callback;
1899 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1901 base::RunLoop().RunUntilIdle();
1902
1903 // |mock_quic_data| must have run to completion.
1904 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1905 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1906
1907 // Now that the QUIC data has been consumed, unblock |http_data|.
1908 http_data.socket()->OnConnectComplete(MockConnect());
1909
1910 // The retry logic must hide the 421 status. The transaction succeeds on
1911 // |http_data|.
1912 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261913 CheckWasHttpResponse(&trans);
1914 CheckResponsePort(&trans, 443);
1915 CheckResponseData(&trans, "hello!");
1916}
1917
[email protected]1e960032013-12-20 19:00:201918TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
Victor Vasilieva1e66d72019-12-05 17:55:381919 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571920 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301921
Ryan Hamiltonabad59e2019-06-06 04:02:591922 MockQuicData mock_quic_data1(version_);
Victor Vasiliev7da08172019-10-14 06:04:251923 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231924 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
tbansalfdf5665b2015-09-21 22:46:401925 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamilton0d65a8c2019-06-07 00:46:021926 client_maker_.Reset();
Ryan Hamiltonabad59e2019-06-06 04:02:591927 MockQuicData mock_quic_data2(version_);
Victor Vasiliev7da08172019-10-14 06:04:251928 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:231929 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
zhongyi32569c62016-01-08 02:54:301930 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401931 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431932 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401933
1934 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1935 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301936
1937 CreateSession();
1938
tbansal0f56a39a2016-04-07 22:03:381939 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401940 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401942 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161943 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1945 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381946 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531947
1948 NetErrorDetails details;
1949 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521950 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401951 }
[email protected]cebe3282013-05-22 23:49:301952}
1953
tbansalc8a94ea2015-11-02 23:58:511954TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1955 // Attempt to "force" quic on 443, which will not be honored.
Victor Vasilieva1e66d72019-12-05 17:55:381956 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571957 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511958
1959 MockRead http_reads[] = {
1960 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1961 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1962 MockRead(ASYNC, OK)};
1963
Ryan Sleevib8d7ea02018-05-07 20:01:011964 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511965 socket_factory_.AddSocketDataProvider(&data);
1966 SSLSocketDataProvider ssl(ASYNC, OK);
1967 socket_factory_.AddSSLSocketDataProvider(&ssl);
1968
1969 CreateSession();
1970
1971 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381972 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511973}
1974
bncc958faa2015-07-31 18:14:521975TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521976 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561977 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1978 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521979 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1980 MockRead(ASYNC, OK)};
1981
Ryan Sleevib8d7ea02018-05-07 20:01:011982 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521983 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081984 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561985 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521986
Ryan Hamiltonabad59e2019-06-06 04:02:591987 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:231988 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:251989 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:231990 mock_quic_data.AddWrite(SYNCHRONOUS,
1991 ConstructInitialSettingsPacket(packet_num++));
1992 }
rch5cb522462017-04-25 20:18:361993 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:231994 SYNCHRONOUS,
1995 ConstructClientRequestHeadersPacket(
1996 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
1997 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:431998 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331999 ASYNC, ConstructServerResponseHeadersPacket(
2000 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2001 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432002 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332003 mock_quic_data.AddRead(
2004 ASYNC, ConstructServerDataPacket(
2005 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172006 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232007 mock_quic_data.AddWrite(SYNCHRONOUS,
2008 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:522009 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592010 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:522011
2012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2013
rtennetib8e80fb2016-05-16 00:12:092014 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322015 CreateSession();
bncc958faa2015-07-31 18:14:522016
2017 SendRequestAndExpectHttpResponse("hello world");
2018 SendRequestAndExpectQuicResponse("hello!");
2019}
2020
Ryan Hamilton64f21d52019-08-31 07:10:512021TEST_P(QuicNetworkTransactionTest, UseIetfAlternativeServiceForQuic) {
2022 std::string alt_svc_header =
2023 "Alt-Svc: " + quic::AlpnForVersion(version_) + "=\":443\"\r\n\r\n";
2024 MockRead http_reads[] = {
2025 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(alt_svc_header.data()),
2026 MockRead("hello world"),
2027 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2028 MockRead(ASYNC, OK)};
2029
2030 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
2031 socket_factory_.AddSocketDataProvider(&http_data);
2032 AddCertificate(&ssl_data_);
2033 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2034
2035 MockQuicData mock_quic_data(version_);
2036 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252037 if (VersionUsesHttp3(version_.transport_version)) {
Ryan Hamilton64f21d52019-08-31 07:10:512038 mock_quic_data.AddWrite(SYNCHRONOUS,
2039 ConstructInitialSettingsPacket(packet_num++));
2040 }
2041 mock_quic_data.AddWrite(
2042 SYNCHRONOUS,
2043 ConstructClientRequestHeadersPacket(
2044 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2045 true, GetRequestHeaders("GET", "https", "/")));
2046 mock_quic_data.AddRead(
2047 ASYNC, ConstructServerResponseHeadersPacket(
2048 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2049 GetResponseHeaders("200 OK")));
2050 std::string header = ConstructDataHeader(6);
2051 mock_quic_data.AddRead(
2052 ASYNC, ConstructServerDataPacket(
2053 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2054 header + "hello!"));
2055 mock_quic_data.AddWrite(SYNCHRONOUS,
2056 ConstructClientAckPacket(packet_num++, 2, 1, 1));
2057 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2058 mock_quic_data.AddRead(ASYNC, 0); // EOF
2059
2060 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2061
2062 AddHangingNonAlternateProtocolSocketData();
2063 CreateSession();
2064
2065 SendRequestAndExpectHttpResponse("hello world");
2066 SendRequestAndExpectQuicResponse("hello!");
2067}
2068
Matt Menke3233d8f22019-08-20 21:01:492069// Much like above, but makes sure NetworkIsolationKey is respected.
2070TEST_P(QuicNetworkTransactionTest,
2071 UseAlternativeServiceForQuicWithNetworkIsolationKey) {
2072 base::test::ScopedFeatureList feature_list;
Matt Menkeb32ba5122019-09-10 19:17:052073 feature_list.InitWithFeatures(
2074 // enabled_features
2075 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2076 features::kPartitionConnectionsByNetworkIsolationKey},
2077 // disabled_features
2078 {});
Matt Menke3233d8f22019-08-20 21:01:492079 // Since HttpServerProperties caches the feature value, have to create a new
2080 // one.
2081 http_server_properties_ = std::make_unique<HttpServerProperties>();
2082
2083 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2084 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2085 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2086 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2087
2088 MockRead http_reads[] = {
2089 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
2090 MockRead("hello world"),
2091 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2092 MockRead(ASYNC, OK)};
2093
2094 AddCertificate(&ssl_data_);
2095
2096 // Request with empty NetworkIsolationKey.
2097 StaticSocketDataProvider http_data1(http_reads, base::span<MockWrite>());
2098 socket_factory_.AddSocketDataProvider(&http_data1);
2099 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2100
2101 // First request with kNetworkIsolationKey1.
2102 StaticSocketDataProvider http_data2(http_reads, base::span<MockWrite>());
2103 socket_factory_.AddSocketDataProvider(&http_data2);
2104 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2105
2106 // Request with kNetworkIsolationKey2.
2107 StaticSocketDataProvider http_data3(http_reads, base::span<MockWrite>());
2108 socket_factory_.AddSocketDataProvider(&http_data3);
2109 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2110
2111 // Second request with kNetworkIsolationKey1, can finally use QUIC, since
2112 // alternative service infrmation has been received in this context before.
2113 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232114 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252115 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232116 mock_quic_data.AddWrite(SYNCHRONOUS,
2117 ConstructInitialSettingsPacket(packet_num++));
2118 }
Matt Menke3233d8f22019-08-20 21:01:492119 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232120 SYNCHRONOUS,
2121 ConstructClientRequestHeadersPacket(
2122 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2123 true, GetRequestHeaders("GET", "https", "/")));
Matt Menke3233d8f22019-08-20 21:01:492124 mock_quic_data.AddRead(
2125 ASYNC, ConstructServerResponseHeadersPacket(
2126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2127 GetResponseHeaders("200 OK")));
2128 std::string header = ConstructDataHeader(6);
2129 mock_quic_data.AddRead(
2130 ASYNC, ConstructServerDataPacket(
2131 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2132 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232133 mock_quic_data.AddWrite(SYNCHRONOUS,
2134 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke3233d8f22019-08-20 21:01:492135 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2136 mock_quic_data.AddRead(ASYNC, 0); // EOF
2137
2138 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2139
2140 AddHangingNonAlternateProtocolSocketData();
2141 CreateSession();
2142
2143 // This is first so that the test fails if alternative service info is
2144 // written with the right NetworkIsolationKey, but always queried with an
2145 // empty one.
2146 request_.network_isolation_key = NetworkIsolationKey();
2147 SendRequestAndExpectHttpResponse("hello world");
2148 request_.network_isolation_key = kNetworkIsolationKey1;
2149 SendRequestAndExpectHttpResponse("hello world");
2150 request_.network_isolation_key = kNetworkIsolationKey2;
2151 SendRequestAndExpectHttpResponse("hello world");
2152
2153 // Only use QUIC when using a NetworkIsolationKey which has been used when
2154 // alternative service information was received.
2155 request_.network_isolation_key = kNetworkIsolationKey1;
2156 SendRequestAndExpectQuicResponse("hello!");
2157}
2158
zhongyia00ca012017-07-06 23:36:392159TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
2160 // Both server advertises and client supports two QUIC versions.
2161 // Only |version_| is advertised and supported.
2162 // The QuicStreamFactoy will pick up |version_|, which is verified as the
2163 // PacketMakers are using |version_|.
2164
2165 // Add support for another QUIC version besides |version_| on the client side.
2166 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:562167 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
2168 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392169 if (version == version_)
2170 continue;
2171 if (supported_versions_.size() != 2) {
2172 supported_versions_.push_back(version);
2173 continue;
2174 }
2175 advertised_version_2 = version;
2176 break;
2177 }
Bence Békyb89104962020-01-24 00:05:172178 ASSERT_EQ(2u, supported_versions_.size());
2179 ASSERT_NE(quic::UnsupportedQuicVersion(), advertised_version_2);
zhongyia00ca012017-07-06 23:36:392180
Bence Békyb89104962020-01-24 00:05:172181 std::string QuicAltSvcWithVersionHeader =
2182 base::StringPrintf("Alt-Svc: %s=\":443\", %s=\":443\"\r\n\r\n",
2183 quic::AlpnForVersion(advertised_version_2).c_str(),
2184 quic::AlpnForVersion(version_).c_str());
zhongyia00ca012017-07-06 23:36:392185
2186 MockRead http_reads[] = {
2187 MockRead("HTTP/1.1 200 OK\r\n"),
2188 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2189 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2190 MockRead(ASYNC, OK)};
2191
Ryan Sleevib8d7ea02018-05-07 20:01:012192 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392193 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082194 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392195 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2196
Ryan Hamiltonabad59e2019-06-06 04:02:592197 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232198 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252199 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232200 mock_quic_data.AddWrite(SYNCHRONOUS,
2201 ConstructInitialSettingsPacket(packet_num++));
2202 }
zhongyia00ca012017-07-06 23:36:392203 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232204 SYNCHRONOUS,
2205 ConstructClientRequestHeadersPacket(
2206 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2207 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432208 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332209 ASYNC, ConstructServerResponseHeadersPacket(
2210 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2211 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432212 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332213 mock_quic_data.AddRead(
2214 ASYNC, ConstructServerDataPacket(
2215 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172216 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232217 mock_quic_data.AddWrite(SYNCHRONOUS,
2218 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392219 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2220 mock_quic_data.AddRead(ASYNC, 0); // EOF
2221
2222 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2223
2224 AddHangingNonAlternateProtocolSocketData();
2225 CreateSession(supported_versions_);
2226
2227 SendRequestAndExpectHttpResponse("hello world");
2228 SendRequestAndExpectQuicResponse("hello!");
2229}
2230
2231TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
Bence Békyb89104962020-01-24 00:05:172232 if (version_.handshake_protocol != quic::PROTOCOL_QUIC_CRYPTO) {
2233 // Only QUIC_CRYPTO versions can be encoded with Google-style AltSvc.
2234 // Currently client preference is not observed with IETF-style AltSvc.
2235 // TODO(https://crbug.com/1044691): Fix that and add test.
2236 return;
2237 }
2238
zhongyia00ca012017-07-06 23:36:392239 // Client and server mutually support more than one QUIC_VERSION.
2240 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
2241 // which is verified as the PacketMakers are using |version_|.
2242
Nick Harper23290b82019-05-02 00:02:562243 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
2244 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:392245 if (version == version_)
2246 continue;
2247 common_version_2 = version;
2248 break;
2249 }
Bence Békyb89104962020-01-24 00:05:172250 ASSERT_NE(quic::UnsupportedQuicVersion(), common_version_2);
zhongyia00ca012017-07-06 23:36:392251
2252 supported_versions_.push_back(
2253 common_version_2); // Supported but unpreferred.
2254
2255 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:562256 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
2257 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:392258
2259 MockRead http_reads[] = {
2260 MockRead("HTTP/1.1 200 OK\r\n"),
2261 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
2262 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2263 MockRead(ASYNC, OK)};
2264
Ryan Sleevib8d7ea02018-05-07 20:01:012265 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:392266 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082267 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:392268 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2269
Ryan Hamiltonabad59e2019-06-06 04:02:592270 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232271 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252272 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232273 mock_quic_data.AddWrite(SYNCHRONOUS,
2274 ConstructInitialSettingsPacket(packet_num++));
2275 }
zhongyia00ca012017-07-06 23:36:392276 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232277 SYNCHRONOUS,
2278 ConstructClientRequestHeadersPacket(
2279 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2280 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432281 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332282 ASYNC, ConstructServerResponseHeadersPacket(
2283 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2284 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432285 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332286 mock_quic_data.AddRead(
2287 ASYNC, ConstructServerDataPacket(
2288 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172289 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232290 mock_quic_data.AddWrite(SYNCHRONOUS,
2291 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:392292 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2293 mock_quic_data.AddRead(ASYNC, 0); // EOF
2294
2295 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2296
2297 AddHangingNonAlternateProtocolSocketData();
2298 CreateSession(supported_versions_);
2299
2300 SendRequestAndExpectHttpResponse("hello world");
2301 SendRequestAndExpectQuicResponse("hello!");
2302}
2303
rchf47265dc2016-03-21 21:33:122304TEST_P(QuicNetworkTransactionTest,
2305 UseAlternativeServiceWithProbabilityForQuic) {
2306 MockRead http_reads[] = {
2307 MockRead("HTTP/1.1 200 OK\r\n"),
2308 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
2309 MockRead("hello world"),
2310 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2311 MockRead(ASYNC, OK)};
2312
Ryan Sleevib8d7ea02018-05-07 20:01:012313 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:122314 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082315 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:122316 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2317
Ryan Hamiltonabad59e2019-06-06 04:02:592318 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232319 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252320 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232321 mock_quic_data.AddWrite(SYNCHRONOUS,
2322 ConstructInitialSettingsPacket(packet_num++));
2323 }
rch5cb522462017-04-25 20:18:362324 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232325 SYNCHRONOUS,
2326 ConstructClientRequestHeadersPacket(
2327 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2328 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432329 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332330 ASYNC, ConstructServerResponseHeadersPacket(
2331 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2332 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432333 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332334 mock_quic_data.AddRead(
2335 ASYNC, ConstructServerDataPacket(
2336 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172337 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232338 mock_quic_data.AddWrite(SYNCHRONOUS,
2339 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchf47265dc2016-03-21 21:33:122340 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2341 mock_quic_data.AddRead(ASYNC, 0); // EOF
2342
2343 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2344
rtennetib8e80fb2016-05-16 00:12:092345 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:122346 CreateSession();
2347
2348 SendRequestAndExpectHttpResponse("hello world");
2349 SendRequestAndExpectQuicResponse("hello!");
2350}
2351
zhongyi3d4a55e72016-04-22 20:36:462352TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2353 MockRead http_reads[] = {
2354 MockRead("HTTP/1.1 200 OK\r\n"),
2355 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2356 MockRead("hello world"),
2357 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2358 MockRead(ASYNC, OK)};
2359
Ryan Sleevib8d7ea02018-05-07 20:01:012360 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462361 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082362 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462363 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2364
2365 CreateSession();
bncb26024382016-06-29 02:39:452366 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462367 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452368 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462369 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402370 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462371 session_->http_server_properties();
2372 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2373 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2374 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462375 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492376 2u, http_server_properties
2377 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2378 .size());
bncb26024382016-06-29 02:39:452379 EXPECT_TRUE(
Matt Menke3233d8f22019-08-20 21:01:492380 http_server_properties
2381 ->GetAlternativeServiceInfos(http_server, NetworkIsolationKey())
2382 .empty());
zhongyi3d4a55e72016-04-22 20:36:462383}
2384
2385TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2386 MockRead http_reads[] = {
2387 MockRead("HTTP/1.1 200 OK\r\n"),
2388 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2389 MockRead("hello world"),
2390 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2391 MockRead(ASYNC, OK)};
2392
Ryan Sleevib8d7ea02018-05-07 20:01:012393 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082394 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462395
2396 socket_factory_.AddSocketDataProvider(&http_data);
2397 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2398 socket_factory_.AddSocketDataProvider(&http_data);
2399 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2400
2401 CreateSession();
2402
2403 // Send https request and set alternative services if response header
2404 // advertises alternative service for mail.example.org.
2405 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402406 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462407 session_->http_server_properties();
2408
2409 const url::SchemeHostPort https_server(request_.url);
2410 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342411 EXPECT_EQ(
Matt Menke3233d8f22019-08-20 21:01:492412 2u, http_server_properties
2413 ->GetAlternativeServiceInfos(https_server, NetworkIsolationKey())
2414 .size());
zhongyi3d4a55e72016-04-22 20:36:462415
2416 // Send http request to the same origin but with diffrent scheme, should not
2417 // use QUIC.
2418 request_.url = GURL("http://mail.example.org:443");
2419 SendRequestAndExpectHttpResponse("hello world");
2420}
2421
zhongyie537a002017-06-27 16:48:212422TEST_P(QuicNetworkTransactionTest,
2423 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442424 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562425 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
Bence Békyb89104962020-01-24 00:05:172426 if (version != version_) {
2427 supported_versions_.push_back(version);
2428 break;
2429 }
zhongyi86838d52017-06-30 01:19:442430 }
2431
Bence Békyb89104962020-01-24 00:05:172432 std::string altsvc_header = GenerateQuicAltSvcHeader();
zhongyie537a002017-06-27 16:48:212433 MockRead http_reads[] = {
Bence Békyb89104962020-01-24 00:05:172434 MockRead("HTTP/1.1 200 OK\r\n"),
2435 MockRead(altsvc_header.c_str()),
2436 MockRead("\r\n"),
zhongyie537a002017-06-27 16:48:212437 MockRead("hello world"),
2438 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2439 MockRead(ASYNC, OK)};
2440
Ryan Sleevib8d7ea02018-05-07 20:01:012441 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212442 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082443 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212444 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2445
Ryan Hamiltonabad59e2019-06-06 04:02:592446 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232447 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252448 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232449 mock_quic_data.AddWrite(SYNCHRONOUS,
2450 ConstructInitialSettingsPacket(packet_num++));
2451 }
zhongyie537a002017-06-27 16:48:212452 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232453 SYNCHRONOUS,
2454 ConstructClientRequestHeadersPacket(
2455 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2456 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432457 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332458 ASYNC, ConstructServerResponseHeadersPacket(
2459 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2460 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432461 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332462 mock_quic_data.AddRead(
2463 ASYNC, ConstructServerDataPacket(
2464 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172465 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232466 mock_quic_data.AddWrite(SYNCHRONOUS,
2467 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212468 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2469 mock_quic_data.AddRead(ASYNC, 0); // EOF
2470
2471 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2472
2473 AddHangingNonAlternateProtocolSocketData();
2474
zhongyi86838d52017-06-30 01:19:442475 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212476
2477 SendRequestAndExpectHttpResponse("hello world");
2478 SendRequestAndExpectQuicResponse("hello!");
2479
Bence Békyb89104962020-01-24 00:05:172480 // Alt-Svc header contains all possible versions, so alternative services
2481 // should contain all of |supported_versions_|.
zhongyie537a002017-06-27 16:48:212482 const url::SchemeHostPort https_server(request_.url);
2483 const AlternativeServiceInfoVector alt_svc_info_vector =
2484 session_->http_server_properties()->GetAlternativeServiceInfos(
Matt Menke3233d8f22019-08-20 21:01:492485 https_server, NetworkIsolationKey());
Bence Békyb89104962020-01-24 00:05:172486 // However, all PROTOCOL_QUIC_CRYPTO versions are sent in a single Alt-Svc
2487 // entry, therefore they aer accumulated in a single AlternativeServiceInfo,
2488 // whereas each PROTOCOL_TLS1_3 version has its own Alt-Svc entry and
2489 // AlternativeServiceInfo entry. Flatten to compare.
2490 quic::ParsedQuicVersionVector alt_svc_negotiated_versions;
2491 for (const auto& alt_svc_info : alt_svc_info_vector) {
2492 EXPECT_EQ(kProtoQUIC, alt_svc_info.alternative_service().protocol);
2493 for (const auto& version : alt_svc_info.advertised_versions()) {
2494 alt_svc_negotiated_versions.push_back(version);
2495 }
2496 }
2497
2498 ASSERT_EQ(supported_versions_.size(), alt_svc_negotiated_versions.size());
2499 auto version_compare = [](const quic::ParsedQuicVersion& a,
2500 const quic::ParsedQuicVersion& b) {
2501 return std::tie(a.transport_version, a.handshake_protocol) <
2502 std::tie(b.transport_version, b.handshake_protocol);
2503 };
2504 std::sort(supported_versions_.begin(), supported_versions_.end(),
2505 version_compare);
2506 std::sort(alt_svc_negotiated_versions.begin(),
2507 alt_svc_negotiated_versions.end(), version_compare);
2508 EXPECT_TRUE(std::equal(supported_versions_.begin(), supported_versions_.end(),
2509 alt_svc_negotiated_versions.begin()));
zhongyie537a002017-06-27 16:48:212510}
2511
danzh3134c2562016-08-12 14:07:522512TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562513 std::string altsvc_header = base::StringPrintf(
Bence Békyb89104962020-01-24 00:05:172514 "Alt-Svc: %s=\":443\"\r\n\r\n", quic::AlpnForVersion(version_).c_str());
bnc8be55ebb2015-10-30 14:12:072515 MockRead http_reads[] = {
2516 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2517 MockRead("hello world"),
2518 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2519 MockRead(ASYNC, OK)};
2520
Ryan Sleevib8d7ea02018-05-07 20:01:012521 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072522 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082523 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072524 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2525
Ryan Hamiltonabad59e2019-06-06 04:02:592526 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232527 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252528 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232529 mock_quic_data.AddWrite(SYNCHRONOUS,
2530 ConstructInitialSettingsPacket(packet_num++));
2531 }
rch5cb522462017-04-25 20:18:362532 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232533 SYNCHRONOUS,
2534 ConstructClientRequestHeadersPacket(
2535 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2536 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:432537 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332538 ASYNC, ConstructServerResponseHeadersPacket(
2539 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2540 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432541 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332542 mock_quic_data.AddRead(
2543 ASYNC, ConstructServerDataPacket(
2544 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:172545 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232546 mock_quic_data.AddWrite(SYNCHRONOUS,
2547 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072548 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592549 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072550
2551 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2552
rtennetib8e80fb2016-05-16 00:12:092553 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322554 CreateSession();
bnc8be55ebb2015-10-30 14:12:072555
2556 SendRequestAndExpectHttpResponse("hello world");
2557 SendRequestAndExpectQuicResponse("hello!");
2558}
2559
zhongyi6b5a3892016-03-12 04:46:202560TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562561 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjie Tangba21e032019-09-27 21:52:282562 // GoAway is not available under version 99
Frank Kastenholz6e4c5382018-06-21 23:00:092563 return;
2564 }
Ryan Hamiltonabad59e2019-06-06 04:02:592565 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:232566 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:252567 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:232568 mock_quic_data.AddWrite(SYNCHRONOUS,
2569 ConstructInitialSettingsPacket(packet_num++));
2570 }
rch5cb522462017-04-25 20:18:362571 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:232572 SYNCHRONOUS,
2573 ConstructClientRequestHeadersPacket(
2574 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
2575 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:332576 mock_quic_data.AddRead(
2577 ASYNC, ConstructServerResponseHeadersPacket(
2578 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2579 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202580 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522581 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432582 mock_quic_data.AddRead(SYNCHRONOUS,
2583 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522584 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432585 "connection migration with port change only"));
Renjie Tangaadb84b2019-08-31 01:00:232586 mock_quic_data.AddWrite(SYNCHRONOUS,
2587 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432588 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332589 mock_quic_data.AddRead(
2590 SYNCHRONOUS, ConstructServerDataPacket(
2591 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:172592 true, header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:232593 mock_quic_data.AddWrite(
2594 SYNCHRONOUS,
2595 ConstructClientAckAndRstPacket(
2596 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
2597 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202598 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2599 mock_quic_data.AddRead(ASYNC, 0); // EOF
2600
2601 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2602
2603 // The non-alternate protocol job needs to hang in order to guarantee that
2604 // the alternate-protocol job will "win".
2605 AddHangingNonAlternateProtocolSocketData();
2606
2607 // In order for a new QUIC session to be established via alternate-protocol
2608 // without racing an HTTP connection, we need the host resolution to happen
2609 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2610 // connection to the the server, in this test we require confirmation
2611 // before encrypting so the HTTP job will still start.
2612 host_resolver_.set_synchronous_mode(true);
2613 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2614 "");
zhongyi6b5a3892016-03-12 04:46:202615
2616 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432617 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2618 false);
Ryan Hamilton9835e662018-08-02 05:36:272619 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202620
bnc691fda62016-08-12 00:43:162621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202622 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362623 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202625
2626 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:002627 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012628 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202629
2630 // Check whether this transaction is correctly marked as received a go-away
2631 // because of migrating port.
2632 NetErrorDetails details;
2633 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162634 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202635 EXPECT_TRUE(details.quic_port_migration_detected);
2636}
2637
Zhongyi Shia6b68d112018-09-24 07:49:032638// This test verifies that a new QUIC connection will be attempted on the
2639// alternate network if the original QUIC connection fails with idle timeout
2640// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2641// alternate network as well, QUIC is marked as broken and the brokenness will
2642// not expire when default network changes.
2643TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432644 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2645 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2646 return;
2647 }
Zhongyi Shia6b68d112018-09-24 07:49:032648 SetUpTestForRetryConnectionOnAlternateNetwork();
2649
Michael Warres167db3e2019-03-01 21:38:032650 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032651
2652 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592653 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032654 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2655 int packet_num = 1;
2656 quic_data.AddWrite(SYNCHRONOUS,
2657 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2658 // Retranmit the handshake messages.
2659 quic_data.AddWrite(SYNCHRONOUS,
2660 client_maker_.MakeDummyCHLOPacket(packet_num++));
2661 quic_data.AddWrite(SYNCHRONOUS,
2662 client_maker_.MakeDummyCHLOPacket(packet_num++));
2663 quic_data.AddWrite(SYNCHRONOUS,
2664 client_maker_.MakeDummyCHLOPacket(packet_num++));
2665 quic_data.AddWrite(SYNCHRONOUS,
2666 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032667 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2668 quic_data.AddWrite(SYNCHRONOUS,
2669 client_maker_.MakeConnectionClosePacket(
2670 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2671 "No recent network activity."));
2672 quic_data.AddSocketDataToFactory(&socket_factory_);
2673
2674 // Add successful TCP data so that TCP job will succeed.
2675 MockWrite http_writes[] = {
2676 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2677 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2678 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2679
2680 MockRead http_reads[] = {
2681 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2682 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2683 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2684 SequencedSocketData http_data(http_reads, http_writes);
2685 socket_factory_.AddSocketDataProvider(&http_data);
2686 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2687
2688 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592689 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032690 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2691 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2692 quic_data2.AddSocketDataToFactory(&socket_factory_);
2693
2694 // Resolve the host resolution synchronously.
2695 host_resolver_.set_synchronous_mode(true);
2696 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2697 "");
Zhongyi Shia6b68d112018-09-24 07:49:032698
2699 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432700 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2701 false);
Zhongyi Shia6b68d112018-09-24 07:49:032702 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032703 QuicStreamFactoryPeer::SetAlarmFactory(
2704 session_->quic_stream_factory(),
2705 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222706 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032707 // Add alternate protocol mapping to race QUIC and TCP.
2708 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2709 // peer.
2710 AddQuicAlternateProtocolMapping(
2711 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2712
2713 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2714 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362715 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2717
2718 // Pump the message loop to get the request started.
2719 // Request will be served with TCP job.
2720 base::RunLoop().RunUntilIdle();
2721 EXPECT_THAT(callback.WaitForResult(), IsOk());
2722 CheckResponseData(&trans, "TCP succeeds");
2723
Zhongyi Shia6b68d112018-09-24 07:49:032724 // Fast forward to idle timeout the original connection. A new connection will
2725 // be kicked off on the alternate network.
2726 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2727 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2728 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2729
2730 // Run the message loop to execute posted tasks, which will report job status.
2731 base::RunLoop().RunUntilIdle();
2732
2733 // Verify that QUIC is marked as broken.
2734 ExpectBrokenAlternateProtocolMapping();
2735
2736 // Deliver a message to notify the new network becomes default, the brokenness
2737 // will not expire as QUIC is broken on both networks.
2738 scoped_mock_change_notifier_->mock_network_change_notifier()
2739 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2740 ExpectBrokenAlternateProtocolMapping();
2741
2742 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2743 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2744}
2745
2746// This test verifies that a new QUIC connection will be attempted on the
2747// alternate network if the original QUIC connection fails with idle timeout
2748// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2749// alternate network, QUIC is marked as broken. The brokenness will expire when
2750// the default network changes.
2751TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432752 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2753 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2754 return;
2755 }
2756
Zhongyi Shia6b68d112018-09-24 07:49:032757 SetUpTestForRetryConnectionOnAlternateNetwork();
2758
Michael Warres167db3e2019-03-01 21:38:032759 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032760
2761 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592762 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032763 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2764 int packet_num = 1;
2765 quic_data.AddWrite(SYNCHRONOUS,
2766 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2767 // Retranmit the handshake messages.
2768 quic_data.AddWrite(SYNCHRONOUS,
2769 client_maker_.MakeDummyCHLOPacket(packet_num++));
2770 quic_data.AddWrite(SYNCHRONOUS,
2771 client_maker_.MakeDummyCHLOPacket(packet_num++));
2772 quic_data.AddWrite(SYNCHRONOUS,
2773 client_maker_.MakeDummyCHLOPacket(packet_num++));
2774 quic_data.AddWrite(SYNCHRONOUS,
2775 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:032776 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2777 quic_data.AddWrite(SYNCHRONOUS,
2778 client_maker_.MakeConnectionClosePacket(
2779 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2780 "No recent network activity."));
2781 quic_data.AddSocketDataToFactory(&socket_factory_);
2782
2783 // Add successful TCP data so that TCP job will succeed.
2784 MockWrite http_writes[] = {
2785 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2786 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2787 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2788
2789 MockRead http_reads[] = {
2790 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2791 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2792 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2793 SequencedSocketData http_data(http_reads, http_writes);
2794 socket_factory_.AddSocketDataProvider(&http_data);
2795 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2796
2797 // Quic connection will be retried on the alternate network after the initial
2798 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592799 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032800 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2801 quic_data2.AddWrite(SYNCHRONOUS,
2802 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2803
2804 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252805 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:232806 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
Zhongyi Shia6b68d112018-09-24 07:49:032807 quic_data2.AddSocketDataToFactory(&socket_factory_);
2808
2809 // Resolve the host resolution synchronously.
2810 host_resolver_.set_synchronous_mode(true);
2811 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2812 "");
Zhongyi Shia6b68d112018-09-24 07:49:032813
2814 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432815 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2816 false);
Zhongyi Shia6b68d112018-09-24 07:49:032817 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032818 QuicStreamFactoryPeer::SetAlarmFactory(
2819 session_->quic_stream_factory(),
2820 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222821 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:032822 // Add alternate protocol mapping to race QUIC and TCP.
2823 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2824 // peer.
2825 AddQuicAlternateProtocolMapping(
2826 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2827
2828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2829 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362830 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032831 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2832
2833 // Pump the message loop to get the request started.
2834 // Request will be served with TCP job.
2835 base::RunLoop().RunUntilIdle();
2836 EXPECT_THAT(callback.WaitForResult(), IsOk());
2837 CheckResponseData(&trans, "TCP succeeds");
2838
Zhongyi Shia6b68d112018-09-24 07:49:032839 // Fast forward to idle timeout the original connection. A new connection will
2840 // be kicked off on the alternate network.
2841 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2842 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2843 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2844
2845 // The second connection hasn't finish handshake, verify that QUIC is not
2846 // marked as broken.
2847 ExpectQuicAlternateProtocolMapping();
2848 // Explicitly confirm the handshake on the second connection.
2849 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:002850 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Zhongyi Shia6b68d112018-09-24 07:49:032851 // Run message loop to execute posted tasks, which will notify JoController
2852 // about the orphaned job status.
2853 base::RunLoop().RunUntilIdle();
2854
2855 // Verify that QUIC is marked as broken.
2856 ExpectBrokenAlternateProtocolMapping();
2857
2858 // Deliver a message to notify the new network becomes default, the previous
2859 // brokenness will be clear as the brokenness is bond with old default
2860 // network.
2861 scoped_mock_change_notifier_->mock_network_change_notifier()
2862 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2863 ExpectQuicAlternateProtocolMapping();
2864
2865 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2866 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2867}
2868
Matt Menkeb32ba5122019-09-10 19:17:052869// Much like above test, but verifies NetworkIsolationKeys are respected.
2870TEST_P(QuicNetworkTransactionTest,
2871 RetryOnAlternateNetworkWhileTCPSucceedsWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:432872 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
2873 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
2874 return;
2875 }
2876
Matt Menkeb32ba5122019-09-10 19:17:052877 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
2878 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
2879 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
2880 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
2881
2882 base::test::ScopedFeatureList feature_list;
2883 feature_list.InitWithFeatures(
2884 // enabled_features
2885 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
2886 // Need to partition connections by NetworkIsolationKey for
2887 // QuicSessionAliasKey to include NetworkIsolationKeys.
2888 features::kPartitionConnectionsByNetworkIsolationKey},
2889 // disabled_features
2890 {});
2891 // Since HttpServerProperties caches the feature value, have to create a new
2892 // one.
2893 http_server_properties_ = std::make_unique<HttpServerProperties>();
2894
2895 SetUpTestForRetryConnectionOnAlternateNetwork();
2896
2897 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
2898
2899 // The request will initially go out over QUIC.
2900 MockQuicData quic_data(version_);
2901 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2902 int packet_num = 1;
2903 quic_data.AddWrite(SYNCHRONOUS,
2904 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2905 // Retranmit the handshake messages.
2906 quic_data.AddWrite(SYNCHRONOUS,
2907 client_maker_.MakeDummyCHLOPacket(packet_num++));
2908 quic_data.AddWrite(SYNCHRONOUS,
2909 client_maker_.MakeDummyCHLOPacket(packet_num++));
2910 quic_data.AddWrite(SYNCHRONOUS,
2911 client_maker_.MakeDummyCHLOPacket(packet_num++));
2912 quic_data.AddWrite(SYNCHRONOUS,
2913 client_maker_.MakeDummyCHLOPacket(packet_num++));
Matt Menkeb32ba5122019-09-10 19:17:052914 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2915 quic_data.AddWrite(SYNCHRONOUS,
2916 client_maker_.MakeConnectionClosePacket(
2917 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2918 "No recent network activity."));
2919 quic_data.AddSocketDataToFactory(&socket_factory_);
2920
2921 // Add successful TCP data so that TCP job will succeed.
2922 MockWrite http_writes[] = {
2923 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2924 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2925 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2926
2927 MockRead http_reads[] = {
2928 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2929 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2930 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2931 SequencedSocketData http_data(http_reads, http_writes);
2932 socket_factory_.AddSocketDataProvider(&http_data);
2933 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2934
2935 // Quic connection will be retried on the alternate network after the initial
2936 // one fails on the default network.
2937 MockQuicData quic_data2(version_);
2938 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2939 quic_data2.AddWrite(SYNCHRONOUS,
2940 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2941
2942 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:252943 if (VersionUsesHttp3(version_.transport_version))
Matt Menkeb32ba5122019-09-10 19:17:052944 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(2));
2945 quic_data2.AddSocketDataToFactory(&socket_factory_);
2946
2947 // Resolve the host resolution synchronously.
2948 host_resolver_.set_synchronous_mode(true);
2949 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2950 "");
2951
2952 CreateSession();
Matt Menkeb566c392019-09-11 23:22:432953 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
2954 false);
Matt Menkeb32ba5122019-09-10 19:17:052955 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2956 QuicStreamFactoryPeer::SetAlarmFactory(
2957 session_->quic_stream_factory(),
2958 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:222959 context_.clock()));
Matt Menkeb32ba5122019-09-10 19:17:052960 // Add alternate protocol mapping to race QUIC and TCP.
2961 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2962 // peer.
2963 AddQuicAlternateProtocolMapping(
2964 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
2965 AddQuicAlternateProtocolMapping(
2966 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
2967
2968 request_.network_isolation_key = kNetworkIsolationKey1;
2969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2970 TestCompletionCallback callback;
2971 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2972 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2973
2974 // Pump the message loop to get the request started.
2975 // Request will be served with TCP job.
2976 base::RunLoop().RunUntilIdle();
2977 EXPECT_THAT(callback.WaitForResult(), IsOk());
2978 CheckResponseData(&trans, "TCP succeeds");
2979
2980 // Fast forward to idle timeout the original connection. A new connection will
2981 // be kicked off on the alternate network.
2982 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2983 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2984 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2985
2986 // The second connection hasn't finish handshake, verify that QUIC is not
2987 // marked as broken.
2988 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
2989 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
2990 // Explicitly confirm the handshake on the second connection.
2991 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:002992 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Matt Menkeb32ba5122019-09-10 19:17:052993 // Run message loop to execute posted tasks, which will notify JoController
2994 // about the orphaned job status.
2995 base::RunLoop().RunUntilIdle();
2996
2997 // Verify that QUIC is marked as broken for kNetworkIsolationKey1 only.
2998 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
2999 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3000
3001 // Deliver a message to notify the new network becomes default, the previous
3002 // brokenness will be clear as the brokenness is bond with old default
3003 // network.
3004 scoped_mock_change_notifier_->mock_network_change_notifier()
3005 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3006 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey1);
3007 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3008
3009 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3010 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3011}
3012
Zhongyi Shia6b68d112018-09-24 07:49:033013// This test verifies that a new QUIC connection will be attempted on the
3014// alternate network if the original QUIC connection fails with idle timeout
3015// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
3016// alternative network succeeds, QUIC is not marked as broken.
3017TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433018 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3019 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3020 return;
3021 }
3022
Zhongyi Shia6b68d112018-09-24 07:49:033023 SetUpTestForRetryConnectionOnAlternateNetwork();
3024
Michael Warres167db3e2019-03-01 21:38:033025 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:033026
3027 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593028 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:033029 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
3030 int packet_num = 1;
3031 quic_data.AddWrite(SYNCHRONOUS,
3032 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
3033 // Retranmit the handshake messages.
3034 quic_data.AddWrite(SYNCHRONOUS,
3035 client_maker_.MakeDummyCHLOPacket(packet_num++));
3036 quic_data.AddWrite(SYNCHRONOUS,
3037 client_maker_.MakeDummyCHLOPacket(packet_num++));
3038 quic_data.AddWrite(SYNCHRONOUS,
3039 client_maker_.MakeDummyCHLOPacket(packet_num++));
3040 quic_data.AddWrite(SYNCHRONOUS,
3041 client_maker_.MakeDummyCHLOPacket(packet_num++));
Zhongyi Shia6b68d112018-09-24 07:49:033042 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
3043 quic_data.AddWrite(SYNCHRONOUS,
3044 client_maker_.MakeConnectionClosePacket(
3045 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3046 "No recent network activity."));
3047 quic_data.AddSocketDataToFactory(&socket_factory_);
3048
3049 // Add hanging TCP data so that TCP job will never succeeded.
3050 AddHangingNonAlternateProtocolSocketData();
3051
3052 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593053 MockQuicData quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:233054 packet_num = 1;
Zhongyi Shia6b68d112018-09-24 07:49:033055 quic_data2.AddWrite(SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:233056 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
Zhongyi Shia6b68d112018-09-24 07:49:033057
Victor Vasiliev076657c2019-03-12 02:46:433058 const std::string body = "hello!";
3059 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:413060
Zhongyi Shia6b68d112018-09-24 07:49:033061 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253062 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:233063 quic_data2.AddWrite(SYNCHRONOUS,
3064 ConstructInitialSettingsPacket(packet_num++));
3065 }
Zhongyi Shia6b68d112018-09-24 07:49:033066 quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:233067 SYNCHRONOUS,
3068 ConstructClientRequestHeadersPacket(
3069 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3070 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shia6b68d112018-09-24 07:49:033071 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333072 ASYNC, ConstructServerResponseHeadersPacket(
3073 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
3074 GetResponseHeaders("200 OK")));
3075 quic_data2.AddRead(
3076 ASYNC, ConstructServerDataPacket(
3077 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:173078 header + body));
Renjie Tangaadb84b2019-08-31 01:00:233079 quic_data2.AddWrite(SYNCHRONOUS,
3080 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia6b68d112018-09-24 07:49:033081 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
3082 quic_data2.AddSocketDataToFactory(&socket_factory_);
3083
3084 // Resolve the host resolution synchronously.
3085 host_resolver_.set_synchronous_mode(true);
3086 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3087 "");
Zhongyi Shia6b68d112018-09-24 07:49:033088
3089 CreateSession();
Matt Menkeb566c392019-09-11 23:22:433090 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
3091 false);
Zhongyi Shia6b68d112018-09-24 07:49:033092 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:033093 QuicStreamFactoryPeer::SetAlarmFactory(
3094 session_->quic_stream_factory(),
3095 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223096 context_.clock()));
Zhongyi Shia6b68d112018-09-24 07:49:033097 // Add alternate protocol mapping to race QUIC and TCP.
3098 // QUIC connection requires handshake to be confirmed and sends CHLO to the
3099 // peer.
3100 AddQuicAlternateProtocolMapping(
3101 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
3102
3103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3104 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363105 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:033106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3107
3108 // Pump the message loop to get the request started.
3109 base::RunLoop().RunUntilIdle();
Zhongyi Shia6b68d112018-09-24 07:49:033110
3111 // Fast forward to idle timeout the original connection. A new connection will
3112 // be kicked off on the alternate network.
3113 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
3114 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3115 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3116
3117 // Verify that QUIC is not marked as broken.
3118 ExpectQuicAlternateProtocolMapping();
3119 // Explicitly confirm the handshake on the second connection.
3120 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003121 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Zhongyi Shia6b68d112018-09-24 07:49:033122
3123 // Read the response.
3124 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:413125 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:033126 // Verify that QUIC is not marked as broken.
3127 ExpectQuicAlternateProtocolMapping();
3128
3129 // Deliver a message to notify the new network becomes default.
3130 scoped_mock_change_notifier_->mock_network_change_notifier()
3131 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3132 ExpectQuicAlternateProtocolMapping();
3133 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
3134 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
3135}
3136
rch9ecde09b2017-04-08 00:18:233137// Verify that if a QUIC connection times out, the QuicHttpStream will
3138// return QUIC_PROTOCOL_ERROR.
3139TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433140 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3141 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3142 return;
3143 }
3144
Victor Vasilieva1e66d72019-12-05 17:55:383145 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3146 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch9ecde09b2017-04-08 00:18:233147
3148 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593149 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133150 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233151 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3152
Ryan Hamiltone940bd12019-06-30 02:46:453153 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033154 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493155 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253156 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493157 quic_data.AddWrite(SYNCHRONOUS,
3158 ConstructInitialSettingsPacket(packet_num++));
3159 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023160 quic_data.AddWrite(
3161 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453162 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493163 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3164 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453165
3166 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233167
Victor Vasiliev7da08172019-10-14 06:04:253168 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493169 // 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 2, packet_num++, true));
3175 // RTO 1
3176 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3177 1, packet_num++, true));
3178 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3179 2, packet_num++, true));
3180 // RTO 2
3181 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3182 1, packet_num++, true));
3183 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3184 2, packet_num++, true));
3185 // RTO 3
3186 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3187 1, packet_num++, true));
3188 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3189 2, packet_num++, true));
Ryan Hamilton3cc2c152019-07-09 19:36:013190
Findit2403b85d2019-11-19 05:06:373191 quic_data.AddWrite(SYNCHRONOUS,
3192 client_maker_.MakeConnectionClosePacket(
3193 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3194 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493195 } else {
3196 // Settings were sent in the request packet so there is only 1 packet to
3197 // retransmit.
3198 // TLP 1
3199 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3200 1, packet_num++, true));
3201 // TLP 2
3202 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3203 1, packet_num++, true));
3204 // RTO 1
3205 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3206 1, packet_num++, true));
3207 // RTO 2
3208 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3209 1, packet_num++, true));
3210 // RTO 3
3211 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3212 1, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373213
Nick Harper057264a82019-09-12 23:33:493214 quic_data.AddWrite(SYNCHRONOUS,
3215 client_maker_.MakeConnectionClosePacket(
3216 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3217 "No recent network activity."));
3218 }
Fan Yang928f1632017-12-14 18:55:223219
rch9ecde09b2017-04-08 00:18:233220 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3221 quic_data.AddRead(ASYNC, OK);
3222 quic_data.AddSocketDataToFactory(&socket_factory_);
3223
3224 // In order for a new QUIC session to be established via alternate-protocol
3225 // without racing an HTTP connection, we need the host resolution to happen
3226 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3227 // connection to the the server, in this test we require confirmation
3228 // before encrypting so the HTTP job will still start.
3229 host_resolver_.set_synchronous_mode(true);
3230 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3231 "");
rch9ecde09b2017-04-08 00:18:233232
3233 CreateSession();
3234 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233235 QuicStreamFactoryPeer::SetAlarmFactory(
3236 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193237 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223238 context_.clock()));
rch9ecde09b2017-04-08 00:18:233239
Ryan Hamilton9835e662018-08-02 05:36:273240 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233241
3242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3243 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363244 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233245 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3246
3247 // Pump the message loop to get the request started.
3248 base::RunLoop().RunUntilIdle();
3249 // Explicitly confirm the handshake.
3250 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003251 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233252
3253 // Run the QUIC session to completion.
3254 quic_task_runner_->RunUntilIdle();
3255
3256 ExpectQuicAlternateProtocolMapping();
3257 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3258 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3259}
3260
3261// Verify that if a QUIC connection RTOs, the QuicHttpStream will
3262// return QUIC_PROTOCOL_ERROR.
3263TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433264 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3265 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3266 return;
3267 }
3268
Victor Vasilieva1e66d72019-12-05 17:55:383269 context_.params()->retry_without_alt_svc_on_quic_errors = false;
3270 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233271
3272 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593273 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133274 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233275 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3276
Ryan Hamiltone940bd12019-06-30 02:46:453277 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033278 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493279 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253280 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493281 quic_data.AddWrite(
3282 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3283 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023284 quic_data.AddWrite(
3285 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453286 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493287 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3288 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453289
3290 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253291 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493292 // TLP 1
3293 quic_data.AddWrite(SYNCHRONOUS,
3294 client_maker_.MakeRetransmissionPacket(1, 3, true));
3295 // TLP 2
3296 quic_data.AddWrite(SYNCHRONOUS,
3297 client_maker_.MakeRetransmissionPacket(2, 4, true));
3298 // RTO 1
3299 quic_data.AddWrite(SYNCHRONOUS,
3300 client_maker_.MakeRetransmissionPacket(1, 5, true));
3301 quic_data.AddWrite(SYNCHRONOUS,
3302 client_maker_.MakeRetransmissionPacket(2, 6, true));
3303 // RTO 2
3304 quic_data.AddWrite(SYNCHRONOUS,
3305 client_maker_.MakeRetransmissionPacket(1, 7, true));
3306 quic_data.AddWrite(SYNCHRONOUS,
3307 client_maker_.MakeRetransmissionPacket(2, 8, true));
3308 // RTO 3
3309 quic_data.AddWrite(SYNCHRONOUS,
3310 client_maker_.MakeRetransmissionPacket(1, 9, true));
3311 quic_data.AddWrite(SYNCHRONOUS,
3312 client_maker_.MakeRetransmissionPacket(2, 10, true));
3313 // RTO 4
3314 quic_data.AddWrite(SYNCHRONOUS,
3315 client_maker_.MakeRetransmissionPacket(1, 11, true));
3316 quic_data.AddWrite(SYNCHRONOUS,
3317 client_maker_.MakeRetransmissionPacket(2, 12, true));
3318 // RTO 5
3319 quic_data.AddWrite(SYNCHRONOUS,
3320 client_maker_.MakeConnectionClosePacket(
3321 13, true, quic::QUIC_TOO_MANY_RTOS,
3322 "5 consecutive retransmission timeouts"));
3323 } else {
3324 // TLP 1
3325 quic_data.AddWrite(SYNCHRONOUS,
3326 client_maker_.MakeRetransmissionPacket(1, 2, true));
3327 // TLP 2
3328 quic_data.AddWrite(SYNCHRONOUS,
3329 client_maker_.MakeRetransmissionPacket(1, 3, true));
3330 // RTO 1
3331 quic_data.AddWrite(SYNCHRONOUS,
3332 client_maker_.MakeRetransmissionPacket(1, 4, true));
3333 // RTO 2
3334 quic_data.AddWrite(SYNCHRONOUS,
3335 client_maker_.MakeRetransmissionPacket(1, 5, true));
3336 // RTO 3
3337 quic_data.AddWrite(SYNCHRONOUS,
3338 client_maker_.MakeRetransmissionPacket(1, 6, true));
3339 // RTO 4
3340 quic_data.AddWrite(SYNCHRONOUS,
3341 client_maker_.MakeRetransmissionPacket(1, 7, true));
3342 // RTO 5
3343 quic_data.AddWrite(SYNCHRONOUS,
3344 client_maker_.MakeConnectionClosePacket(
3345 8, true, quic::QUIC_TOO_MANY_RTOS,
3346 "5 consecutive retransmission timeouts"));
3347 }
rch9ecde09b2017-04-08 00:18:233348
3349 quic_data.AddRead(ASYNC, OK);
3350 quic_data.AddSocketDataToFactory(&socket_factory_);
3351
3352 // In order for a new QUIC session to be established via alternate-protocol
3353 // without racing an HTTP connection, we need the host resolution to happen
3354 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3355 // connection to the the server, in this test we require confirmation
3356 // before encrypting so the HTTP job will still start.
3357 host_resolver_.set_synchronous_mode(true);
3358 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3359 "");
rch9ecde09b2017-04-08 00:18:233360
3361 CreateSession();
3362 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233363 QuicStreamFactoryPeer::SetAlarmFactory(
3364 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193365 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223366 context_.clock()));
rch9ecde09b2017-04-08 00:18:233367
Ryan Hamilton9835e662018-08-02 05:36:273368 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233369
3370 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3371 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363372 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3374
3375 // Pump the message loop to get the request started.
3376 base::RunLoop().RunUntilIdle();
3377 // Explicitly confirm the handshake.
3378 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003379 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233380
3381 // Run the QUIC session to completion.
3382 quic_task_runner_->RunUntilIdle();
3383
3384 ExpectQuicAlternateProtocolMapping();
3385 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3386 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3387}
3388
3389// Verify that if a QUIC connection RTOs, while there are no active streams
3390// QUIC will not be marked as broken.
3391TEST_P(QuicNetworkTransactionTest,
3392 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433393 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3394 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3395 return;
3396 }
3397
Victor Vasilieva1e66d72019-12-05 17:55:383398 context_.params()->connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233399
3400 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593401 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133402 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233403 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3404
Ryan Hamiltone940bd12019-06-30 02:46:453405 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033406 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493407 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:253408 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493409 quic_data.AddWrite(
3410 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
3411 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023412 quic_data.AddWrite(
3413 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453414 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493415 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3416 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453417
3418 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch9ecde09b2017-04-08 00:18:233419
Victor Vasiliev7da08172019-10-14 06:04:253420 if (!VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493421 quic_data.AddWrite(SYNCHRONOUS,
3422 client_maker_.MakeRstPacket(
3423 packet_number++, true,
3424 GetNthClientInitiatedBidirectionalStreamId(0),
3425 quic::QUIC_STREAM_CANCELLED));
3426 // TLP 1
Bence Béky6e243aa2019-12-13 19:01:073427 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3428 1, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493429 // TLP 2
Bence Béky6e243aa2019-12-13 19:01:073430 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3431 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493432 // RTO 1
Bence Béky6e243aa2019-12-13 19:01:073433 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3434 1, packet_number++, true));
3435 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3436 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493437 // RTO 2
Bence Béky6e243aa2019-12-13 19:01:073438 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3439 1, packet_number++, true));
3440 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3441 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493442 // RTO 3
Bence Béky6e243aa2019-12-13 19:01:073443 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3444 1, packet_number++, true));
3445 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3446 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493447 // RTO 4
Bence Béky6e243aa2019-12-13 19:01:073448 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3449 1, packet_number++, true));
3450 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3451 2, packet_number++, true));
Nick Harper057264a82019-09-12 23:33:493452 // RTO 5
3453 quic_data.AddWrite(SYNCHRONOUS,
3454 client_maker_.MakeConnectionClosePacket(
Bence Béky6e243aa2019-12-13 19:01:073455 packet_number++, true, quic::QUIC_TOO_MANY_RTOS,
Nick Harper057264a82019-09-12 23:33:493456 "5 consecutive retransmission timeouts"));
Renjie Tang33f43ce2019-09-23 22:11:423457 } else {
3458 quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:073459 SYNCHRONOUS, ConstructClientDataPacket(
3460 packet_number++, GetQpackDecoderStreamId(), true,
3461 false, StreamCancellationQpackDecoderInstruction(0)));
3462 quic_data.AddWrite(SYNCHRONOUS,
3463 client_maker_.MakeRstPacket(
3464 packet_number++, true,
3465 GetNthClientInitiatedBidirectionalStreamId(0),
3466 quic::QUIC_STREAM_CANCELLED));
Renjie Tang33f43ce2019-09-23 22:11:423467 client_maker_.RemoveSavedStreamFrames(
3468 GetNthClientInitiatedBidirectionalStreamId(0));
Bence Béky6e243aa2019-12-13 19:01:073469
Bence Béky6e243aa2019-12-13 19:01:073470 // TLP 1
3471 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3472 1, packet_number++, true));
3473 // TLP 2
3474 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3475 2, packet_number++, true));
3476 // RTO 1
3477 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3478 3, packet_number++, true));
3479 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3480 4, packet_number++, true));
3481 // RTO 2
3482 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3483 1, packet_number++, true));
3484 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3485 2, packet_number++, true));
3486 // RTO 3
3487 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3488 3, packet_number++, true));
3489 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3490 4, packet_number++, true));
3491 // RTO 4
3492 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3493 1, packet_number++, true));
3494 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3495 2, packet_number++, true));
3496 // RTO 5
3497 quic_data.AddWrite(SYNCHRONOUS,
3498 client_maker_.MakeConnectionClosePacket(
3499 packet_number++, true, quic::QUIC_TOO_MANY_RTOS,
3500 "5 consecutive retransmission timeouts"));
Nick Harper057264a82019-09-12 23:33:493501 }
rch9ecde09b2017-04-08 00:18:233502
3503 quic_data.AddRead(ASYNC, OK);
3504 quic_data.AddSocketDataToFactory(&socket_factory_);
3505
3506 // In order for a new QUIC session to be established via alternate-protocol
3507 // without racing an HTTP connection, we need the host resolution to happen
3508 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3509 // connection to the the server, in this test we require confirmation
3510 // before encrypting so the HTTP job will still start.
3511 host_resolver_.set_synchronous_mode(true);
3512 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3513 "");
rch9ecde09b2017-04-08 00:18:233514
3515 CreateSession();
3516 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233517 QuicStreamFactoryPeer::SetAlarmFactory(
3518 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193519 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223520 context_.clock()));
rch9ecde09b2017-04-08 00:18:233521
Ryan Hamilton9835e662018-08-02 05:36:273522 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233523
Jeremy Roman0579ed62017-08-29 15:56:193524 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233525 session_.get());
3526 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363527 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233528 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3529
3530 // Pump the message loop to get the request started.
3531 base::RunLoop().RunUntilIdle();
3532 // Explicitly confirm the handshake.
3533 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003534 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233535
3536 // Now cancel the request.
3537 trans.reset();
3538
3539 // Run the QUIC session to completion.
3540 quic_task_runner_->RunUntilIdle();
3541
3542 ExpectQuicAlternateProtocolMapping();
3543
3544 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3545}
3546
rch2f2991c2017-04-13 19:28:173547// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3548// the request fails with QUIC_PROTOCOL_ERROR.
3549TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433550 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3551 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3552 return;
3553 }
3554
Victor Vasilieva1e66d72019-12-05 17:55:383555 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173556 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593557 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033558 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493559 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253560 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493561 quic_data.AddWrite(SYNCHRONOUS,
3562 ConstructInitialSettingsPacket(packet_num++));
3563 }
3564 quic_data.AddWrite(
3565 SYNCHRONOUS,
3566 ConstructClientRequestHeadersPacket(
3567 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3568 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023569 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553570 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch2f2991c2017-04-13 19:28:173571 // Peer sending data from an non-existing stream causes this end to raise
3572 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333573 quic_data.AddRead(
3574 ASYNC, ConstructServerRstPacket(
3575 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3576 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173577 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373578 quic_data.AddWrite(SYNCHRONOUS,
3579 ConstructClientAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:533580 packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
3581 quic_error_details, quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173582 quic_data.AddSocketDataToFactory(&socket_factory_);
3583
3584 // In order for a new QUIC session to be established via alternate-protocol
3585 // without racing an HTTP connection, we need the host resolution to happen
3586 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3587 // connection to the the server, in this test we require confirmation
3588 // before encrypting so the HTTP job will still start.
3589 host_resolver_.set_synchronous_mode(true);
3590 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3591 "");
rch2f2991c2017-04-13 19:28:173592
3593 CreateSession();
3594
Ryan Hamilton9835e662018-08-02 05:36:273595 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173596
3597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3598 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363599 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173600 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3601
3602 // Pump the message loop to get the request started.
3603 base::RunLoop().RunUntilIdle();
3604 // Explicitly confirm the handshake.
3605 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003606 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173607
3608 ASSERT_FALSE(quic_data.AllReadDataConsumed());
Ryan Hamiltonb01f886f2019-07-10 02:25:553609 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173610
3611 // Run the QUIC session to completion.
3612 base::RunLoop().RunUntilIdle();
3613 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3614 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3615
3616 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3617 ExpectQuicAlternateProtocolMapping();
3618 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3619}
3620
rch2f2991c2017-04-13 19:28:173621// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3622// connection times out, then QUIC will be marked as broken and the request
3623// retried over TCP.
3624TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433625 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3626 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3627 return;
3628 }
3629
Victor Vasilieva1e66d72019-12-05 17:55:383630 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173631
3632 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593633 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:133634 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173635 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3636
Ryan Hamiltone940bd12019-06-30 02:46:453637 client_maker_.set_save_packet_frames(true);
Michael Warres167db3e2019-03-01 21:38:033638 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493639 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253640 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493641 quic_data.AddWrite(SYNCHRONOUS,
3642 client_maker_.MakeInitialSettingsPacket(packet_num++));
3643 }
Ryan Hamilton0d65a8c2019-06-07 00:46:023644 quic_data.AddWrite(
3645 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:453646 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:493647 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3648 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:453649
3650 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Victor Vasiliev7da08172019-10-14 06:04:253651 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493652 // TLP 1
3653 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3654 1, packet_num++, true));
3655 // TLP 2
3656 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3657 2, packet_num++, true));
3658 // RTO 1
3659 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3660 1, packet_num++, true));
3661 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3662 2, packet_num++, true));
3663 // RTO 2
3664 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3665 1, packet_num++, true));
3666 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3667 2, packet_num++, true));
3668 // RTO 3
3669 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3670 1, packet_num++, true));
3671 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3672 2, packet_num++, true));
Findit2403b85d2019-11-19 05:06:373673
3674 quic_data.AddWrite(SYNCHRONOUS,
3675 client_maker_.MakeConnectionClosePacket(
3676 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3677 "No recent network activity."));
Nick Harper057264a82019-09-12 23:33:493678 } else {
3679 // TLP 1
3680 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3681 1, packet_num++, true));
3682 // TLP 2
3683 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3684 1, packet_num++, true));
3685 // RTO 1
3686 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3687 1, packet_num++, true));
3688 // RTO 2
3689 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3690 1, packet_num++, true));
3691 // RTO 3
3692 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRetransmissionPacket(
3693 1, packet_num++, true));
3694
3695 quic_data.AddWrite(SYNCHRONOUS,
3696 client_maker_.MakeConnectionClosePacket(
3697 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
3698 "No recent network activity."));
3699 }
Fan Yang928f1632017-12-14 18:55:223700
rch2f2991c2017-04-13 19:28:173701 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3702 quic_data.AddRead(ASYNC, OK);
3703 quic_data.AddSocketDataToFactory(&socket_factory_);
3704
3705 // After that fails, it will be resent via TCP.
3706 MockWrite http_writes[] = {
3707 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3708 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3709 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3710
3711 MockRead http_reads[] = {
3712 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3713 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3714 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013715 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173716 socket_factory_.AddSocketDataProvider(&http_data);
3717 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3718
3719 // In order for a new QUIC session to be established via alternate-protocol
3720 // without racing an HTTP connection, we need the host resolution to happen
3721 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3722 // connection to the the server, in this test we require confirmation
3723 // before encrypting so the HTTP job will still start.
3724 host_resolver_.set_synchronous_mode(true);
3725 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3726 "");
rch2f2991c2017-04-13 19:28:173727
3728 CreateSession();
3729 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173730 QuicStreamFactoryPeer::SetAlarmFactory(
3731 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193732 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:223733 context_.clock()));
rch2f2991c2017-04-13 19:28:173734
Ryan Hamilton9835e662018-08-02 05:36:273735 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173736
3737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3738 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363739 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3741
3742 // Pump the message loop to get the request started.
3743 base::RunLoop().RunUntilIdle();
3744 // Explicitly confirm the handshake.
3745 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003746 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173747
3748 // Run the QUIC session to completion.
3749 quic_task_runner_->RunUntilIdle();
3750 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3751
3752 ExpectQuicAlternateProtocolMapping();
3753
3754 // Let the transaction proceed which will result in QUIC being marked
3755 // as broken and the request falling back to TCP.
3756 EXPECT_THAT(callback.WaitForResult(), IsOk());
3757
3758 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3759 ASSERT_FALSE(http_data.AllReadDataConsumed());
3760
3761 // Read the response body over TCP.
3762 CheckResponseData(&trans, "hello world");
3763 ExpectBrokenAlternateProtocolMapping();
3764 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3765 ASSERT_TRUE(http_data.AllReadDataConsumed());
3766}
3767
rch2f2991c2017-04-13 19:28:173768// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3769// protocol error occurs after the handshake is confirmed, the request
3770// retried over TCP and the QUIC will be marked as broken.
3771TEST_P(QuicNetworkTransactionTest,
3772 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433773 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3774 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3775 return;
3776 }
3777
Victor Vasilieva1e66d72019-12-05 17:55:383778 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
rch2f2991c2017-04-13 19:28:173779
3780 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593781 MockQuicData quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:033782 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:493783 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:253784 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:493785 quic_data.AddWrite(SYNCHRONOUS,
3786 ConstructInitialSettingsPacket(packet_num++));
3787 }
3788 quic_data.AddWrite(
3789 SYNCHRONOUS,
3790 ConstructClientRequestHeadersPacket(
3791 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3792 true, GetRequestHeaders("GET", "https", "/")));
Ryan Hamilton0d65a8c2019-06-07 00:46:023793 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:553794 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3795
rch2f2991c2017-04-13 19:28:173796 // Peer sending data from an non-existing stream causes this end to raise
3797 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333798 quic_data.AddRead(
3799 ASYNC, ConstructServerRstPacket(
3800 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3801 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173802 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:373803 quic_data.AddWrite(SYNCHRONOUS,
3804 ConstructClientAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:533805 packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
3806 quic_error_details, quic::IETF_RST_STREAM));
rch2f2991c2017-04-13 19:28:173807 quic_data.AddSocketDataToFactory(&socket_factory_);
3808
3809 // After that fails, it will be resent via TCP.
3810 MockWrite http_writes[] = {
3811 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3812 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3813 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3814
3815 MockRead http_reads[] = {
3816 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3817 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3818 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013819 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173820 socket_factory_.AddSocketDataProvider(&http_data);
3821 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3822
3823 // In order for a new QUIC session to be established via alternate-protocol
3824 // without racing an HTTP connection, we need the host resolution to happen
3825 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3826 // connection to the the server, in this test we require confirmation
3827 // before encrypting so the HTTP job will still start.
3828 host_resolver_.set_synchronous_mode(true);
3829 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3830 "");
rch2f2991c2017-04-13 19:28:173831
3832 CreateSession();
3833
Ryan Hamilton9835e662018-08-02 05:36:273834 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173835
3836 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3837 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363838 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3840
3841 // Pump the message loop to get the request started.
3842 base::RunLoop().RunUntilIdle();
3843 // Explicitly confirm the handshake.
3844 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003845 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:553846 quic_data.Resume();
rch2f2991c2017-04-13 19:28:173847
3848 // Run the QUIC session to completion.
3849 base::RunLoop().RunUntilIdle();
3850 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3851
3852 ExpectQuicAlternateProtocolMapping();
3853
3854 // Let the transaction proceed which will result in QUIC being marked
3855 // as broken and the request falling back to TCP.
3856 EXPECT_THAT(callback.WaitForResult(), IsOk());
3857
3858 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3859 ASSERT_FALSE(http_data.AllReadDataConsumed());
3860
3861 // Read the response body over TCP.
3862 CheckResponseData(&trans, "hello world");
3863 ExpectBrokenAlternateProtocolMapping();
3864 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3865 ASSERT_TRUE(http_data.AllReadDataConsumed());
3866}
3867
Matt Menkeb32ba5122019-09-10 19:17:053868// Much like above test, but verifies that NetworkIsolationKey is respected.
3869TEST_P(QuicNetworkTransactionTest,
3870 ProtocolErrorAfterHandshakeConfirmedThenBrokenWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:433871 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
3872 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
3873 return;
3874 }
3875
Matt Menkeb32ba5122019-09-10 19:17:053876 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
3877 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
3878 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
3879 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
3880
3881 base::test::ScopedFeatureList feature_list;
3882 feature_list.InitWithFeatures(
3883 // enabled_features
3884 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
3885 features::kPartitionConnectionsByNetworkIsolationKey},
3886 // disabled_features
3887 {});
3888 // Since HttpServerProperties caches the feature value, have to create a new
3889 // one.
3890 http_server_properties_ = std::make_unique<HttpServerProperties>();
3891
Victor Vasilieva1e66d72019-12-05 17:55:383892 context_.params()->idle_connection_timeout = base::TimeDelta::FromSeconds(5);
Matt Menkeb32ba5122019-09-10 19:17:053893
3894 // The request will initially go out over QUIC.
3895 MockQuicData quic_data(version_);
Renjie Tang874398a2019-09-13 18:32:563896 uint64_t packet_number = 1;
Matt Menkeb32ba5122019-09-10 19:17:053897 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:253898 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tang874398a2019-09-13 18:32:563899 quic_data.AddWrite(SYNCHRONOUS,
3900 ConstructInitialSettingsPacket(packet_number++));
3901 }
3902 quic_data.AddWrite(
3903 SYNCHRONOUS,
3904 ConstructClientRequestHeadersPacket(
3905 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
3906 true, GetRequestHeaders("GET", "https", "/")));
Matt Menkeb32ba5122019-09-10 19:17:053907 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Matt Menkeb32ba5122019-09-10 19:17:053908 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3909
3910 // Peer sending data from an non-existing stream causes this end to raise
3911 // error and close connection.
3912 quic_data.AddRead(
3913 ASYNC, ConstructServerRstPacket(
3914 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3915 quic::QUIC_STREAM_LAST_ERROR));
3916 std::string quic_error_details = "Data for nonexistent stream";
Bence Békyde6290f2019-12-19 15:21:533917 quic_data.AddWrite(SYNCHRONOUS,
3918 ConstructClientAckAndConnectionClosePacket(
3919 packet_number++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
3920 quic_error_details, quic::IETF_RST_STREAM));
Matt Menkeb32ba5122019-09-10 19:17:053921 quic_data.AddSocketDataToFactory(&socket_factory_);
3922
3923 // After that fails, it will be resent via TCP.
3924 MockWrite http_writes[] = {
3925 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3926 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3927 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3928
3929 MockRead http_reads[] = {
3930 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3931 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3932 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
3933 SequencedSocketData http_data(http_reads, http_writes);
3934 socket_factory_.AddSocketDataProvider(&http_data);
3935 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3936
3937 // In order for a new QUIC session to be established via alternate-protocol
3938 // without racing an HTTP connection, we need the host resolution to happen
3939 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3940 // connection to the the server, in this test we require confirmation
3941 // before encrypting so the HTTP job will still start.
3942 host_resolver_.set_synchronous_mode(true);
3943 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3944 "");
3945
3946 CreateSession();
3947
3948 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3949 kNetworkIsolationKey1);
3950 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
3951 kNetworkIsolationKey2);
3952
3953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3954 TestCompletionCallback callback;
3955 request_.network_isolation_key = kNetworkIsolationKey1;
3956 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
3957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3958
3959 // Pump the message loop to get the request started.
3960 base::RunLoop().RunUntilIdle();
3961 // Explicitly confirm the handshake.
3962 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:003963 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Matt Menkeb32ba5122019-09-10 19:17:053964 quic_data.Resume();
3965
3966 // Run the QUIC session to completion.
3967 base::RunLoop().RunUntilIdle();
3968 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3969
3970 // Let the transaction proceed which will result in QUIC being marked
3971 // as broken and the request falling back to TCP.
3972 EXPECT_THAT(callback.WaitForResult(), IsOk());
3973 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3974 ASSERT_FALSE(http_data.AllReadDataConsumed());
3975
3976 // Read the response body over TCP.
3977 CheckResponseData(&trans, "hello world");
3978 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3979 ASSERT_TRUE(http_data.AllReadDataConsumed());
3980
3981 // The alternative service shouldhave been marked as broken under
3982 // kNetworkIsolationKey1 but not kNetworkIsolationKey2.
3983 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3984 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3985
3986 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
3987 AddHttpDataAndRunRequest();
3988 // Requests using other NetworkIsolationKeys can still use QUIC.
3989 request_.network_isolation_key = kNetworkIsolationKey2;
3990 AddQuicDataAndRunRequest();
3991
3992 // The last two requests should not have changed the alternative service
3993 // mappings.
3994 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
3995 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
3996}
3997
rch30943ee2017-06-12 21:28:443998// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3999// request is reset from, then QUIC will be marked as broken and the request
4000// retried over TCP.
4001TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
Renjie Tang3d8a6ddd2019-11-20 00:18:434002 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
4003 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
4004 return;
4005 }
4006
rch30943ee2017-06-12 21:28:444007 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:594008 MockQuicData quic_data(version_);
Ryan Hamilton0239aac2018-05-19 00:03:134009 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:444010 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
4011
Michael Warres167db3e2019-03-01 21:38:034012 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:494013 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254014 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:494015 quic_data.AddWrite(SYNCHRONOUS,
4016 ConstructInitialSettingsPacket(packet_num++));
4017 }
Ryan Hamilton0d65a8c2019-06-07 00:46:024018 quic_data.AddWrite(
4019 SYNCHRONOUS,
Ryan Hamiltone940bd12019-06-30 02:46:454020 client_maker_.MakeRequestHeadersPacket(
Nick Harper057264a82019-09-12 23:33:494021 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4022 true, priority, GetRequestHeaders("GET", "https", "/"), 0, nullptr));
Ryan Hamiltone940bd12019-06-30 02:46:454023
4024 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Ryan Hamiltonb01f886f2019-07-10 02:25:554025 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
rch30943ee2017-06-12 21:28:444026
Fan Yang32c5a112018-12-10 20:06:334027 quic_data.AddRead(ASYNC,
4028 ConstructServerRstPacket(
4029 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
4030 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444031
Bence Béky6e243aa2019-12-13 19:01:074032 if (VersionUsesHttp3(version_.transport_version)) {
4033 quic_data.AddWrite(SYNCHRONOUS,
4034 ConstructClientDataPacket(
4035 packet_num++, GetQpackDecoderStreamId(), true, false,
4036 StreamCancellationQpackDecoderInstruction(0)));
4037 }
4038
rch30943ee2017-06-12 21:28:444039 quic_data.AddRead(ASYNC, OK);
4040 quic_data.AddSocketDataToFactory(&socket_factory_);
4041
4042 // After that fails, it will be resent via TCP.
4043 MockWrite http_writes[] = {
4044 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4045 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
4046 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4047
4048 MockRead http_reads[] = {
4049 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4050 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4051 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014052 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444053 socket_factory_.AddSocketDataProvider(&http_data);
4054 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4055
4056 // In order for a new QUIC session to be established via alternate-protocol
4057 // without racing an HTTP connection, we need the host resolution to happen
4058 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4059 // connection to the the server, in this test we require confirmation
4060 // before encrypting so the HTTP job will still start.
4061 host_resolver_.set_synchronous_mode(true);
4062 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
4063 "");
rch30943ee2017-06-12 21:28:444064
4065 CreateSession();
4066
Ryan Hamilton9835e662018-08-02 05:36:274067 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:444068
4069 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
4070 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364071 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:444072 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
4073
4074 // Pump the message loop to get the request started.
4075 base::RunLoop().RunUntilIdle();
4076 // Explicitly confirm the handshake.
4077 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:004078 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Ryan Hamiltonb01f886f2019-07-10 02:25:554079 quic_data.Resume();
rch30943ee2017-06-12 21:28:444080
4081 // Run the QUIC session to completion.
4082 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4083
4084 ExpectQuicAlternateProtocolMapping();
4085
4086 // Let the transaction proceed which will result in QUIC being marked
4087 // as broken and the request falling back to TCP.
4088 EXPECT_THAT(callback.WaitForResult(), IsOk());
4089
4090 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4091 ASSERT_FALSE(http_data.AllReadDataConsumed());
4092
4093 // Read the response body over TCP.
4094 CheckResponseData(&trans, "hello world");
4095 ExpectBrokenAlternateProtocolMapping();
4096 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4097 ASSERT_TRUE(http_data.AllReadDataConsumed());
4098}
4099
Ryan Hamilton6c2a2a82017-12-15 02:06:284100// Verify that when an origin has two alt-svc advertisements, one local and one
4101// remote, that when the local is broken the request will go over QUIC via
4102// the remote Alt-Svc.
4103// This is a regression test for crbug/825646.
4104TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384105 context_.params()->allow_remote_alt_svc = true;
Ryan Hamilton6c2a2a82017-12-15 02:06:284106
4107 GURL origin1 = request_.url; // mail.example.org
4108 GURL origin2("https://www.example.org/");
4109 ASSERT_NE(origin1.host(), origin2.host());
4110
4111 scoped_refptr<X509Certificate> cert(
4112 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244113 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4114 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284115
4116 ProofVerifyDetailsChromium verify_details;
4117 verify_details.cert_verify_result.verified_cert = cert;
4118 verify_details.cert_verify_result.is_issued_by_known_root = true;
4119 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4120
Ryan Hamiltonabad59e2019-06-06 04:02:594121 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234122 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254123 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234124 mock_quic_data.AddWrite(SYNCHRONOUS,
4125 ConstructInitialSettingsPacket(packet_num++));
4126 }
Ryan Hamilton6c2a2a82017-12-15 02:06:284127 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234128 SYNCHRONOUS,
4129 ConstructClientRequestHeadersPacket(
4130 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4131 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434132 mock_quic_data.AddRead(
4133 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334134 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024135 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434136 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434137 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334138 ASYNC, ConstructServerDataPacket(
4139 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174140 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234141 mock_quic_data.AddWrite(SYNCHRONOUS,
4142 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284143 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4144 mock_quic_data.AddRead(ASYNC, 0); // EOF
4145
4146 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594147 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284148 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4149 AddHangingNonAlternateProtocolSocketData();
4150
4151 CreateSession();
4152
4153 // Set up alternative service for |origin1|.
4154 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4155 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4156 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4157 AlternativeServiceInfoVector alternative_services;
4158 alternative_services.push_back(
4159 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4160 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384161 context_.params()->supported_versions));
Ryan Hamilton6c2a2a82017-12-15 02:06:284162 alternative_services.push_back(
4163 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4164 remote_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384165 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494166 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4167 NetworkIsolationKey(),
4168 alternative_services);
Ryan Hamilton6c2a2a82017-12-15 02:06:284169
Matt Menkeb32ba5122019-09-10 19:17:054170 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4171 NetworkIsolationKey());
Ryan Hamilton6c2a2a82017-12-15 02:06:284172
4173 SendRequestAndExpectQuicResponse("hello!");
4174}
4175
Ryan Hamilton899c2e082019-11-14 01:22:024176// Verify that when multiple alternatives are broken,
4177// ALTERNATE_PROTOCOL_USAGE_BROKEN is only logged once.
4178// This is a regression test for crbug/1024613.
4179TEST_P(QuicNetworkTransactionTest, BrokenAlternativeOnlyRecordedOnce) {
4180 base::HistogramTester histogram_tester;
4181
4182 MockRead http_reads[] = {
4183 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4184 MockRead("hello world"),
4185 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4186 MockRead(ASYNC, OK)};
4187
4188 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4189 socket_factory_.AddSocketDataProvider(&http_data);
4190 AddCertificate(&ssl_data_);
4191 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4192
4193 GURL origin1 = request_.url; // mail.example.org
4194
4195 scoped_refptr<X509Certificate> cert(
4196 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
4197 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
4198
4199 ProofVerifyDetailsChromium verify_details;
4200 verify_details.cert_verify_result.verified_cert = cert;
4201 verify_details.cert_verify_result.is_issued_by_known_root = true;
4202 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4203
4204 CreateSession();
4205
4206 // Set up alternative service for |origin1|.
4207 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4208 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4209 AlternativeServiceInfoVector alternative_services;
4210 alternative_services.push_back(
4211 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4212 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384213 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024214 alternative_services.push_back(
4215 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4216 local_alternative, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384217 context_.params()->supported_versions));
Ryan Hamilton899c2e082019-11-14 01:22:024218 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin1),
4219 NetworkIsolationKey(),
4220 alternative_services);
4221
4222 http_server_properties_->MarkAlternativeServiceBroken(local_alternative,
4223 NetworkIsolationKey());
4224
4225 SendRequestAndExpectHttpResponse("hello world");
4226
4227 histogram_tester.ExpectBucketCount("Net.AlternateProtocolUsage",
4228 ALTERNATE_PROTOCOL_USAGE_BROKEN, 1);
4229}
4230
rch30943ee2017-06-12 21:28:444231// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4232// request is reset from, then QUIC will be marked as broken and the request
Matt Menkeb32ba5122019-09-10 19:17:054233// retried over TCP. Then, subsequent requests will go over a new TCP
rch30943ee2017-06-12 21:28:444234// connection instead of going back to the broken QUIC connection.
4235// This is a regression tests for crbug/731303.
4236TEST_P(QuicNetworkTransactionTest,
4237 ResetPooledAfterHandshakeConfirmedThenBroken) {
Victor Vasilieva1e66d72019-12-05 17:55:384238 context_.params()->allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444239
4240 GURL origin1 = request_.url;
4241 GURL origin2("https://www.example.org/");
4242 ASSERT_NE(origin1.host(), origin2.host());
4243
Ryan Hamiltonabad59e2019-06-06 04:02:594244 MockQuicData mock_quic_data(version_);
rch30943ee2017-06-12 21:28:444245
4246 scoped_refptr<X509Certificate> cert(
4247 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244248 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4249 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444250
4251 ProofVerifyDetailsChromium verify_details;
4252 verify_details.cert_verify_result.verified_cert = cert;
4253 verify_details.cert_verify_result.is_issued_by_known_root = true;
4254 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4255
Renjie Tangaadb84b2019-08-31 01:00:234256 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254257 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234258 mock_quic_data.AddWrite(SYNCHRONOUS,
4259 ConstructInitialSettingsPacket(packet_num++));
4260 }
rch30943ee2017-06-12 21:28:444261 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434262 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234263 SYNCHRONOUS,
4264 ConstructClientRequestHeadersPacket(
4265 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4266 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434267 mock_quic_data.AddRead(
4268 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334269 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024270 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434271 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434272 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334273 ASYNC, ConstructServerDataPacket(
4274 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174275 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234276 mock_quic_data.AddWrite(SYNCHRONOUS,
4277 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rch30943ee2017-06-12 21:28:444278
4279 // Second request will go over the pooled QUIC connection, but will be
4280 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054281 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224282 version_,
4283 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4284 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054285 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174286 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224287 version_,
4288 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4289 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434290 mock_quic_data.AddWrite(
4291 SYNCHRONOUS,
4292 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234293 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4294 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024295 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:334296 mock_quic_data.AddRead(
4297 ASYNC, ConstructServerRstPacket(
4298 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4299 quic::QUIC_HEADERS_TOO_LARGE));
Bence Béky6e243aa2019-12-13 19:01:074300
4301 if (VersionUsesHttp3(version_.transport_version)) {
4302 mock_quic_data.AddWrite(
4303 SYNCHRONOUS, ConstructClientDataPacket(
4304 packet_num++, GetQpackDecoderStreamId(), true, false,
4305 StreamCancellationQpackDecoderInstruction(1)));
4306 }
4307
rch30943ee2017-06-12 21:28:444308 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4309 mock_quic_data.AddRead(ASYNC, 0); // EOF
4310
4311 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4312
4313 // After that fails, it will be resent via TCP.
4314 MockWrite http_writes[] = {
4315 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4316 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4317 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4318
4319 MockRead http_reads[] = {
4320 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4321 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4322 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014323 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444324 socket_factory_.AddSocketDataProvider(&http_data);
4325 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4326
Ryan Hamilton6c2a2a82017-12-15 02:06:284327 // Then the next request to the second origin will be sent over TCP.
4328 socket_factory_.AddSocketDataProvider(&http_data);
4329 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444330
4331 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564332 QuicStreamFactoryPeer::SetAlarmFactory(
4333 session_->quic_stream_factory(),
4334 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224335 context_.clock()));
rch30943ee2017-06-12 21:28:444336
4337 // Set up alternative service for |origin1|.
4338 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244339 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494340 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074341 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative1,
4342 expiration, supported_versions_);
rch30943ee2017-06-12 21:28:444343
4344 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244345 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
Matt Menke3233d8f22019-08-20 21:01:494346 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074347 url::SchemeHostPort(origin2), NetworkIsolationKey(), alternative2,
4348 expiration, supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344349
rch30943ee2017-06-12 21:28:444350 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524351 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444352 SendRequestAndExpectQuicResponse("hello!");
4353
4354 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524355 // because certificate matches, even though quic::QuicServerId is different.
Matt Menkeb32ba5122019-09-10 19:17:054356 // After it is reset, it will fail back to TCP and mark QUIC as broken.
rch30943ee2017-06-12 21:28:444357 request_.url = origin2;
4358 SendRequestAndExpectHttpResponse("hello world");
Matt Menkeb32ba5122019-09-10 19:17:054359 EXPECT_FALSE(http_server_properties_->IsAlternativeServiceBroken(
4360 alternative1, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244361 << alternative1.ToString();
Matt Menkeb32ba5122019-09-10 19:17:054362 EXPECT_TRUE(http_server_properties_->IsAlternativeServiceBroken(
4363 alternative2, NetworkIsolationKey()))
Ryan Hamiltoncec1cee82017-12-15 00:00:244364 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444365
Matt Menkeb32ba5122019-09-10 19:17:054366 // The third request should use a new TCP connection, not the broken
rch30943ee2017-06-12 21:28:444367 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284368 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444369}
4370
bnc8be55ebb2015-10-30 14:12:074371TEST_P(QuicNetworkTransactionTest,
4372 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564373 std::string altsvc_header =
4374 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4375 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074376 MockRead http_reads[] = {
4377 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4378 MockRead("hello world"),
4379 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4380 MockRead(ASYNC, OK)};
4381
Ryan Sleevib8d7ea02018-05-07 20:01:014382 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074383 socket_factory_.AddSocketDataProvider(&http_data);
4384 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4385 socket_factory_.AddSocketDataProvider(&http_data);
4386 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4387
rch3f4b8452016-02-23 16:59:324388 CreateSession();
bnc8be55ebb2015-10-30 14:12:074389
4390 SendRequestAndExpectHttpResponse("hello world");
4391 SendRequestAndExpectHttpResponse("hello world");
4392}
4393
Xida Chen9bfe0b62018-04-24 19:52:214394// When multiple alternative services are advertised, HttpStreamFactory should
4395// select the alternative service which uses existing QUIC session if available.
4396// If no existing QUIC session can be used, use the first alternative service
4397// from the list.
zhongyi32569c62016-01-08 02:54:304398TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Victor Vasilieva1e66d72019-12-05 17:55:384399 context_.params()->allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524400 MockRead http_reads[] = {
4401 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294402 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524403 MockRead("hello world"),
4404 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4405 MockRead(ASYNC, OK)};
4406
Ryan Sleevib8d7ea02018-05-07 20:01:014407 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524408 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084409 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564410 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524411
zhongyi32569c62016-01-08 02:54:304412 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294413 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304414 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594415 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234416 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254417 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234418 mock_quic_data.AddWrite(SYNCHRONOUS,
4419 ConstructInitialSettingsPacket(packet_num++));
4420 }
rch5cb522462017-04-25 20:18:364421 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234422 SYNCHRONOUS,
4423 ConstructClientRequestHeadersPacket(
4424 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4425 true, GetRequestHeaders("GET", "https", "/")));
zhongyi32569c62016-01-08 02:54:304426
4427 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294428 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4429 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434430 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024431 ASYNC, ConstructServerResponseHeadersPacket(
4432 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4433 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434434 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434435 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334436 ASYNC, ConstructServerDataPacket(
4437 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174438 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234439 mock_quic_data.AddWrite(SYNCHRONOUS,
4440 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304441
4442 // Second QUIC request data.
4443 // Connection pooling, using existing session, no need to include version
4444 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584445 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234446 SYNCHRONOUS,
4447 ConstructClientRequestHeadersPacket(
4448 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4449 true, GetRequestHeaders("GET", "https", "/"),
4450 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434451 mock_quic_data.AddRead(
4452 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334453 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024454 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434455 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334456 ASYNC, ConstructServerDataPacket(
4457 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174458 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434459 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234460 SYNCHRONOUS,
4461 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bncc958faa2015-07-31 18:14:524462 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594463 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524464
4465 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4466
rtennetib8e80fb2016-05-16 00:12:094467 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324468 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564469 QuicStreamFactoryPeer::SetAlarmFactory(
4470 session_->quic_stream_factory(),
4471 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224472 context_.clock()));
bncc958faa2015-07-31 18:14:524473
4474 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304475
bnc359ed2a2016-04-29 20:43:454476 SendRequestAndExpectQuicResponse("hello!");
4477 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304478}
4479
tbansal6490783c2016-09-20 17:55:274480// Check that an existing QUIC connection to an alternative proxy server is
4481// used.
4482TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4483 base::HistogramTester histogram_tester;
4484
tbansal6490783c2016-09-20 17:55:274485 // First QUIC request data.
4486 // Open a session to foo.example.org:443 using the first entry of the
4487 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594488 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234489 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254490 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234491 mock_quic_data.AddWrite(SYNCHRONOUS,
4492 ConstructInitialSettingsPacket(packet_num++));
4493 }
rch5cb522462017-04-25 20:18:364494 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234495 SYNCHRONOUS,
4496 ConstructClientRequestHeadersPacket(
4497 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4498 true, GetRequestHeaders("GET", "http", "/")));
tbansal6490783c2016-09-20 17:55:274499
4500 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434501 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:024502 ASYNC, ConstructServerResponseHeadersPacket(
4503 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4504 GetResponseHeaders("200 OK", alt_svc_list)));
Victor Vasiliev076657c2019-03-12 02:46:434505 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434506 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334507 ASYNC, ConstructServerDataPacket(
4508 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174509 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234510 mock_quic_data.AddWrite(SYNCHRONOUS,
4511 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274512
4513 // Second QUIC request data.
4514 // Connection pooling, using existing session, no need to include version
4515 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274516 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234517 SYNCHRONOUS,
4518 ConstructClientRequestHeadersPacket(
4519 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4520 true, GetRequestHeaders("GET", "http", "/"),
4521 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434522 mock_quic_data.AddRead(
4523 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334524 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024525 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434526 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334527 ASYNC, ConstructServerDataPacket(
4528 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174529 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434530 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234531 SYNCHRONOUS,
4532 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274533 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4534 mock_quic_data.AddRead(ASYNC, 0); // EOF
4535
4536 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4537
4538 AddHangingNonAlternateProtocolSocketData();
4539
4540 TestProxyDelegate test_proxy_delegate;
4541
Lily Houghton8c2f97d2018-01-22 05:06:594542 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494543 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274544
4545 test_proxy_delegate.set_alternative_proxy_server(
4546 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524547 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274548
4549 request_.url = GURL("http://mail.example.org/");
4550
4551 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564552 QuicStreamFactoryPeer::SetAlarmFactory(
4553 session_->quic_stream_factory(),
4554 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224555 context_.clock()));
tbansal6490783c2016-09-20 17:55:274556
4557 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4558 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4559 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4560 1);
4561
4562 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4563 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4564 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4565 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4566 1);
4567}
4568
Ryan Hamilton8d9ee76e2018-05-29 23:52:524569// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454570// even if alternative service destination is different.
4571TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Victor Vasilieva1e66d72019-12-05 17:55:384572 context_.params()->allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594573 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454574
Renjie Tangaadb84b2019-08-31 01:00:234575 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254576 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234577 mock_quic_data.AddWrite(SYNCHRONOUS,
4578 ConstructInitialSettingsPacket(packet_num++));
4579 }
bnc359ed2a2016-04-29 20:43:454580 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434581 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234582 SYNCHRONOUS,
4583 ConstructClientRequestHeadersPacket(
4584 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4585 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434586 mock_quic_data.AddRead(
4587 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334588 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024589 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434590 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434591 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334592 ASYNC, ConstructServerDataPacket(
4593 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174594 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234595 mock_quic_data.AddWrite(SYNCHRONOUS,
4596 ConstructClientAckPacket(packet_num++, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304597
bnc359ed2a2016-04-29 20:43:454598 // Second request.
alyssar2adf3ac2016-05-03 17:12:584599 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234600 SYNCHRONOUS,
4601 ConstructClientRequestHeadersPacket(
4602 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4603 true, GetRequestHeaders("GET", "https", "/"),
4604 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434605 mock_quic_data.AddRead(
4606 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334607 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024608 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434609 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334610 ASYNC, ConstructServerDataPacket(
4611 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174612 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434613 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234614 SYNCHRONOUS,
4615 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304616 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4617 mock_quic_data.AddRead(ASYNC, 0); // EOF
4618
4619 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454620
4621 AddHangingNonAlternateProtocolSocketData();
4622 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304623
rch3f4b8452016-02-23 16:59:324624 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564625 QuicStreamFactoryPeer::SetAlarmFactory(
4626 session_->quic_stream_factory(),
4627 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224628 context_.clock()));
zhongyi32569c62016-01-08 02:54:304629
bnc359ed2a2016-04-29 20:43:454630 const char destination1[] = "first.example.com";
4631 const char destination2[] = "second.example.com";
4632
4633 // Set up alternative service entry to destination1.
4634 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214635 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454636 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494637 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074638 server, NetworkIsolationKey(), alternative_service, expiration,
4639 supported_versions_);
bnc359ed2a2016-04-29 20:43:454640 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524641 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454642 SendRequestAndExpectQuicResponse("hello!");
4643
4644 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214645 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
Matt Menke3233d8f22019-08-20 21:01:494646 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074647 server, NetworkIsolationKey(), alternative_service, expiration,
4648 supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524649 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454650 // even though alternative service destination is different.
4651 SendRequestAndExpectQuicResponse("hello!");
4652}
4653
4654// Pool to existing session with matching destination and matching certificate
4655// even if origin is different, and even if the alternative service with
4656// matching destination is not the first one on the list.
4657TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Victor Vasilieva1e66d72019-12-05 17:55:384658 context_.params()->allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454659 GURL origin1 = request_.url;
4660 GURL origin2("https://www.example.org/");
4661 ASSERT_NE(origin1.host(), origin2.host());
4662
Ryan Hamiltonabad59e2019-06-06 04:02:594663 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:454664
Renjie Tangaadb84b2019-08-31 01:00:234665 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254666 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234667 mock_quic_data.AddWrite(SYNCHRONOUS,
4668 ConstructInitialSettingsPacket(packet_num++));
4669 }
bnc359ed2a2016-04-29 20:43:454670 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434671 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234672 SYNCHRONOUS,
4673 ConstructClientRequestHeadersPacket(
4674 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4675 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434676 mock_quic_data.AddRead(
4677 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334678 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024679 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434680 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434681 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334682 ASYNC, ConstructServerDataPacket(
4683 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174684 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234685 mock_quic_data.AddWrite(SYNCHRONOUS,
4686 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454687
4688 // Second request.
Yixin Wang079ad542018-01-11 04:06:054689 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224690 version_,
4691 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4692 context_.clock(), origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054693 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174694 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:224695 version_,
4696 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4697 context_.clock(), origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584698 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434699 SYNCHRONOUS,
4700 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234701 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4702 true, GetRequestHeaders("GET", "https", "/", &client_maker2),
Ryan Hamilton0d65a8c2019-06-07 00:46:024703 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434704 mock_quic_data.AddRead(
4705 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334706 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024707 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:434708 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334709 ASYNC, ConstructServerDataPacket(
4710 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174711 header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434712 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234713 SYNCHRONOUS,
4714 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454715 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4716 mock_quic_data.AddRead(ASYNC, 0); // EOF
4717
4718 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4719
4720 AddHangingNonAlternateProtocolSocketData();
4721 AddHangingNonAlternateProtocolSocketData();
4722
4723 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564724 QuicStreamFactoryPeer::SetAlarmFactory(
4725 session_->quic_stream_factory(),
4726 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224727 context_.clock()));
bnc359ed2a2016-04-29 20:43:454728
4729 const char destination1[] = "first.example.com";
4730 const char destination2[] = "second.example.com";
4731
4732 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214733 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454734 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Matt Menke3233d8f22019-08-20 21:01:494735 http_server_properties_->SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:074736 url::SchemeHostPort(origin1), NetworkIsolationKey(), alternative_service1,
4737 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454738
4739 // Set up multiple alternative service entries for |origin2|,
4740 // the first one with a different destination as for |origin1|,
4741 // the second one with the same. The second one should be used,
4742 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214743 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454744 AlternativeServiceInfoVector alternative_services;
4745 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214746 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4747 alternative_service2, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384748 context_.params()->supported_versions));
bnc359ed2a2016-04-29 20:43:454749 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214750 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4751 alternative_service1, expiration,
Victor Vasilieva1e66d72019-12-05 17:55:384752 context_.params()->supported_versions));
Matt Menke3233d8f22019-08-20 21:01:494753 http_server_properties_->SetAlternativeServices(url::SchemeHostPort(origin2),
4754 NetworkIsolationKey(),
4755 alternative_services);
bnc359ed2a2016-04-29 20:43:454756 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524757 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454758 SendRequestAndExpectQuicResponse("hello!");
4759
4760 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524761 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454762 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584763
bnc359ed2a2016-04-29 20:43:454764 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304765}
4766
4767// Multiple origins have listed the same alternative services. When there's a
4768// existing QUIC session opened by a request to other origin,
4769// if the cert is valid, should select this QUIC session to make the request
4770// if this is also the first existing QUIC session.
4771TEST_P(QuicNetworkTransactionTest,
4772 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Victor Vasilieva1e66d72019-12-05 17:55:384773 context_.params()->allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294774 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304775
rch9ae5b3b2016-02-11 00:36:294776 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304777 MockRead http_reads[] = {
4778 MockRead("HTTP/1.1 200 OK\r\n"),
4779 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294780 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304781 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4782 MockRead(ASYNC, OK)};
4783
Ryan Sleevib8d7ea02018-05-07 20:01:014784 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304785 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084786 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304787 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4788
4789 // HTTP data for request to mail.example.org.
4790 MockRead http_reads2[] = {
4791 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294792 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304793 MockRead("hello world from mail.example.org"),
4794 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4795 MockRead(ASYNC, OK)};
4796
Ryan Sleevib8d7ea02018-05-07 20:01:014797 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304798 socket_factory_.AddSocketDataProvider(&http_data2);
4799 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4800
Yixin Wang079ad542018-01-11 04:06:054801 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:224802 version_,
4803 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
4804 context_.clock(), "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054805 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584806 server_maker_.set_hostname("www.example.org");
4807 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594808 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234809 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254810 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234811 mock_quic_data.AddWrite(SYNCHRONOUS,
4812 ConstructInitialSettingsPacket(packet_num++));
4813 }
zhongyi32569c62016-01-08 02:54:304814 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584815 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234816 SYNCHRONOUS,
4817 ConstructClientRequestHeadersPacket(
4818 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4819 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434820
4821 mock_quic_data.AddRead(
4822 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334823 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024824 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434825 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334826 mock_quic_data.AddRead(
4827 ASYNC, ConstructServerDataPacket(
4828 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174829 header + "hello from mail QUIC!"));
Renjie Tangaadb84b2019-08-31 01:00:234830 mock_quic_data.AddWrite(SYNCHRONOUS,
4831 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:434832 // Second QUIC request data.
4833 mock_quic_data.AddWrite(
4834 SYNCHRONOUS,
4835 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:234836 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
4837 true, GetRequestHeaders("GET", "https", "/", &client_maker),
Ryan Hamilton0d65a8c2019-06-07 00:46:024838 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:434839 mock_quic_data.AddRead(
4840 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334841 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:024842 GetResponseHeaders("200 OK")));
Fan Yang32c5a112018-12-10 20:06:334843 mock_quic_data.AddRead(
4844 ASYNC, ConstructServerDataPacket(
4845 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174846 header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434847 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234848 SYNCHRONOUS,
4849 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304850 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4851 mock_quic_data.AddRead(ASYNC, 0); // EOF
4852
4853 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304854
rtennetib8e80fb2016-05-16 00:12:094855 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324856 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564857 QuicStreamFactoryPeer::SetAlarmFactory(
4858 session_->quic_stream_factory(),
4859 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:224860 context_.clock()));
zhongyi32569c62016-01-08 02:54:304861
4862 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294863 request_.url = GURL("https://www.example.org/");
4864 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304865 request_.url = GURL("https://mail.example.org/");
4866 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4867
rch9ae5b3b2016-02-11 00:36:294868 // Open a QUIC session to mail.example.org:443 when making request
4869 // to mail.example.org.
4870 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454871 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304872
rch9ae5b3b2016-02-11 00:36:294873 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304874 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454875 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524876}
4877
4878TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524879 MockRead http_reads[] = {
4880 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564881 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524882 MockRead("hello world"),
4883 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4884 MockRead(ASYNC, OK)};
4885
Ryan Sleevib8d7ea02018-05-07 20:01:014886 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524887 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084888 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564889 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524890
rtennetib8e80fb2016-05-16 00:12:094891 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324892 CreateSession();
bncc958faa2015-07-31 18:14:524893
4894 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454895
4896 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344897 AlternativeServiceInfoVector alternative_service_info_vector =
Matt Menke3233d8f22019-08-20 21:01:494898 http_server_properties_->GetAlternativeServiceInfos(
4899 http_server, NetworkIsolationKey());
zhongyic4de03032017-05-19 04:07:344900 ASSERT_EQ(1u, alternative_service_info_vector.size());
4901 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544902 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344903 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4904 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4905 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524906}
4907
4908TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524909 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564910 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4911 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524912 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4913 MockRead(ASYNC, OK)};
4914
Ryan Sleevib8d7ea02018-05-07 20:01:014915 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524916 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084917 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564918 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524919
Ryan Hamiltonabad59e2019-06-06 04:02:594920 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:234921 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:254922 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:234923 mock_quic_data.AddWrite(SYNCHRONOUS,
4924 ConstructInitialSettingsPacket(packet_num++));
4925 }
rch5cb522462017-04-25 20:18:364926 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:234927 SYNCHRONOUS,
4928 ConstructClientRequestHeadersPacket(
4929 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
4930 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434931 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334932 ASYNC, ConstructServerResponseHeadersPacket(
4933 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4934 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434935 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334936 mock_quic_data.AddRead(
4937 ASYNC, ConstructServerDataPacket(
4938 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:174939 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:234940 mock_quic_data.AddWrite(SYNCHRONOUS,
4941 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:524942 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4943 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524944
4945 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4946
rtennetib8e80fb2016-05-16 00:12:094947 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324948 CreateSession();
bncc958faa2015-07-31 18:14:524949
bnc3472afd2016-11-17 15:27:214950 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524951 HostPortPair::FromURL(request_.url));
Matt Menke3233d8f22019-08-20 21:01:494952 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054953 alternative_service, NetworkIsolationKey());
Matt Menke3233d8f22019-08-20 21:01:494954 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054955 alternative_service, NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524956
4957 SendRequestAndExpectHttpResponse("hello world");
4958 SendRequestAndExpectQuicResponse("hello!");
4959
mmenkee24011922015-12-17 22:12:594960 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524961
Matt Menke3233d8f22019-08-20 21:01:494962 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
Matt Menkeb32ba5122019-09-10 19:17:054963 alternative_service, NetworkIsolationKey()));
Matt Menke19475f72019-08-21 18:57:444964 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
4965 url::SchemeHostPort("https", request_.url.host(), 443),
4966 NetworkIsolationKey()));
bncc958faa2015-07-31 18:14:524967}
4968
Matt Menkeb32ba5122019-09-10 19:17:054969TEST_P(QuicNetworkTransactionTest,
4970 ConfirmAlternativeServiceWithNetworkIsolationKey) {
4971 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
4972 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
4973 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
4974 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
4975
4976 base::test::ScopedFeatureList feature_list;
4977 feature_list.InitWithFeatures(
4978 // enabled_features
4979 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
4980 features::kPartitionConnectionsByNetworkIsolationKey},
4981 // disabled_features
4982 {});
4983 // Since HttpServerProperties caches the feature value, have to create a new
4984 // one.
4985 http_server_properties_ = std::make_unique<HttpServerProperties>();
4986
4987 MockRead http_reads[] = {
4988 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4989 MockRead("hello world"),
4990 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4991 MockRead(ASYNC, OK)};
4992
4993 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
4994 socket_factory_.AddSocketDataProvider(&http_data);
4995 AddCertificate(&ssl_data_);
4996 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4997
4998 MockQuicData mock_quic_data(version_);
4999 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255000 if (VersionUsesHttp3(version_.transport_version)) {
Matt Menkeb32ba5122019-09-10 19:17:055001 mock_quic_data.AddWrite(SYNCHRONOUS,
5002 ConstructInitialSettingsPacket(packet_num++));
5003 }
5004 mock_quic_data.AddWrite(
5005 SYNCHRONOUS,
5006 ConstructClientRequestHeadersPacket(
5007 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5008 true, GetRequestHeaders("GET", "https", "/")));
5009 mock_quic_data.AddRead(
5010 ASYNC, ConstructServerResponseHeadersPacket(
5011 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5012 GetResponseHeaders("200 OK")));
5013 std::string header = ConstructDataHeader(6);
5014 mock_quic_data.AddRead(
5015 ASYNC, ConstructServerDataPacket(
5016 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5017 header + "hello!"));
5018 mock_quic_data.AddWrite(SYNCHRONOUS,
5019 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5020 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5021 mock_quic_data.AddRead(ASYNC, 0); // EOF
5022
5023 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5024
5025 CreateSession();
5026
5027 AlternativeService alternative_service(kProtoQUIC,
5028 HostPortPair::FromURL(request_.url));
5029 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5030 alternative_service, kNetworkIsolationKey1);
5031 http_server_properties_->MarkAlternativeServiceRecentlyBroken(
5032 alternative_service, kNetworkIsolationKey2);
5033 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5034 alternative_service, kNetworkIsolationKey1));
5035 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5036 alternative_service, kNetworkIsolationKey2));
5037
5038 request_.network_isolation_key = kNetworkIsolationKey1;
5039 SendRequestAndExpectHttpResponse("hello world");
5040 SendRequestAndExpectQuicResponse("hello!");
5041
5042 mock_quic_data.Resume();
5043
5044 EXPECT_FALSE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5045 alternative_service, kNetworkIsolationKey1));
5046 EXPECT_NE(nullptr, http_server_properties_->GetServerNetworkStats(
5047 url::SchemeHostPort("https", request_.url.host(), 443),
5048 kNetworkIsolationKey1));
5049 EXPECT_TRUE(http_server_properties_->WasAlternativeServiceRecentlyBroken(
5050 alternative_service, kNetworkIsolationKey2));
5051 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5052 url::SchemeHostPort("https", request_.url.host(), 443),
5053 kNetworkIsolationKey2));
5054}
5055
bncc958faa2015-07-31 18:14:525056TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:525057 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565058 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5059 MockRead("hello world"),
bncc958faa2015-07-31 18:14:525060 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5061 MockRead(ASYNC, OK)};
5062
Ryan Sleevib8d7ea02018-05-07 20:01:015063 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:525064 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565065 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:525066
Ryan Hamiltonabad59e2019-06-06 04:02:595067 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235068 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255069 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235070 mock_quic_data.AddWrite(SYNCHRONOUS,
5071 ConstructInitialSettingsPacket(packet_num++));
5072 }
rch5cb522462017-04-25 20:18:365073 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235074 SYNCHRONOUS,
5075 ConstructClientRequestHeadersPacket(
5076 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5077 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435078 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335079 ASYNC, ConstructServerResponseHeadersPacket(
5080 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5081 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435082 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335083 mock_quic_data.AddRead(
5084 ASYNC, ConstructServerDataPacket(
5085 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175086 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235087 mock_quic_data.AddWrite(SYNCHRONOUS,
5088 ConstructClientAckPacket(packet_num++, 2, 1, 1));
bncc958faa2015-07-31 18:14:525089 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
5090
5091 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5092
5093 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325094 CreateSession();
bncc958faa2015-07-31 18:14:525095
5096 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
5097 SendRequestAndExpectHttpResponse("hello world");
5098}
5099
tbansalc3308d72016-08-27 10:25:045100// Tests that the connection to an HTTPS proxy is raced with an available
5101// alternative proxy server.
5102TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:275103 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595104 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495105 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045106
Ryan Hamiltonabad59e2019-06-06 04:02:595107 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235108 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255109 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235110 mock_quic_data.AddWrite(SYNCHRONOUS,
5111 ConstructInitialSettingsPacket(packet_num++));
5112 }
rch5cb522462017-04-25 20:18:365113 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235114 SYNCHRONOUS,
5115 ConstructClientRequestHeadersPacket(
5116 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5117 true, GetRequestHeaders("GET", "http", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435118 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335119 ASYNC, ConstructServerResponseHeadersPacket(
5120 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5121 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435122 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335123 mock_quic_data.AddRead(
5124 ASYNC, ConstructServerDataPacket(
5125 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175126 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235127 mock_quic_data.AddWrite(SYNCHRONOUS,
5128 ConstructClientAckPacket(packet_num++, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:045129 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5130 mock_quic_data.AddRead(ASYNC, 0); // EOF
5131
5132 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5133
5134 // There is no need to set up main job, because no attempt will be made to
5135 // speak to the proxy over TCP.
5136 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:045137 TestProxyDelegate test_proxy_delegate;
5138 const HostPortPair host_port_pair("mail.example.org", 443);
5139
5140 test_proxy_delegate.set_alternative_proxy_server(
5141 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525142 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045143 CreateSession();
5144 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5145
5146 // The main job needs to hang in order to guarantee that the alternative
5147 // proxy server job will "win".
5148 AddHangingNonAlternateProtocolSocketData();
5149
5150 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
5151
5152 // Verify that the alternative proxy server is not marked as broken.
5153 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5154
5155 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595156 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275157
5158 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5159 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5160 1);
tbansalc3308d72016-08-27 10:25:045161}
5162
bnc1c196c6e2016-05-28 13:51:485163TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:305164 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275165 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:305166
5167 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:565168 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:295169 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565170 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:305171
5172 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565173 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485174 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565175 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:305176
Ryan Sleevib8d7ea02018-05-07 20:01:015177 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505178 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:085179 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:505180 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305181
5182 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:455183 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:305184 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:455185 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:305186 };
Ryan Sleevib8d7ea02018-05-07 20:01:015187 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:505188 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:305189
5190 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:015191 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:505192 socket_factory_.AddSocketDataProvider(&http_data2);
5193 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:305194
bnc912a04b2016-04-20 14:19:505195 CreateSession();
[email protected]dda75ab2013-06-22 22:43:305196
5197 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:305198 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:175199 ASSERT_TRUE(http_data.AllReadDataConsumed());
5200 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305201
5202 // Now run the second request in which the QUIC socket hangs,
5203 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:305204 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:455205 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:305206
rch37de576c2015-05-17 20:28:175207 ASSERT_TRUE(http_data2.AllReadDataConsumed());
5208 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:455209 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:305210}
5211
[email protected]1e960032013-12-20 19:00:205212TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435213 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5214 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5215 return;
5216 }
5217
Ryan Hamiltonabad59e2019-06-06 04:02:595218 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035219 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495220 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:255221 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495222 mock_quic_data.AddWrite(SYNCHRONOUS,
5223 ConstructInitialSettingsPacket(packet_num++));
5224 }
Zhongyi Shi32f2fd02018-04-16 18:23:435225 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495226 SYNCHRONOUS,
5227 ConstructClientRequestHeadersPacket(
5228 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5229 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435230 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335231 ASYNC, ConstructServerResponseHeadersPacket(
5232 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5233 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435234 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335235 mock_quic_data.AddRead(
5236 ASYNC, ConstructServerDataPacket(
5237 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175238 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495239 mock_quic_data.AddWrite(SYNCHRONOUS,
5240 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505241 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595242 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:485243
rcha5399e02015-04-21 19:32:045244 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:485245
rtennetib8e80fb2016-05-16 00:12:095246 // The non-alternate protocol job needs to hang in order to guarantee that
5247 // the alternate-protocol job will "win".
5248 AddHangingNonAlternateProtocolSocketData();
5249
rch3f4b8452016-02-23 16:59:325250 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275251 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:195252 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:305253
Matt Menke19475f72019-08-21 18:57:445254 EXPECT_EQ(nullptr, http_server_properties_->GetServerNetworkStats(
5255 url::SchemeHostPort("https", request_.url.host(), 443),
5256 NetworkIsolationKey()));
[email protected]8ba81212013-05-03 13:11:485257}
5258
[email protected]1e960032013-12-20 19:00:205259TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435260 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5261 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5262 return;
5263 }
5264
Ryan Hamiltonabad59e2019-06-06 04:02:595265 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035266 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:495267 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:255268 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495269 mock_quic_data.AddWrite(
5270 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5271 }
Fan Yang32c5a112018-12-10 20:06:335272 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:495273 SYNCHRONOUS,
5274 ConstructClientRequestHeadersPacket(
5275 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5276 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435277 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335278 ASYNC, ConstructServerResponseHeadersPacket(
5279 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5280 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435281 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335282 mock_quic_data.AddRead(
5283 ASYNC, ConstructServerDataPacket(
5284 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175285 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:495286 mock_quic_data.AddWrite(SYNCHRONOUS,
5287 ConstructClientAckPacket(packet_number++, 2, 1, 1));
rchb27683c2015-07-29 23:53:505288 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595289 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045290 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275291
5292 // In order for a new QUIC session to be established via alternate-protocol
5293 // without racing an HTTP connection, we need the host resolution to happen
5294 // synchronously.
5295 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295296 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565297 "");
[email protected]3a120a6b2013-06-25 01:08:275298
rtennetib8e80fb2016-05-16 00:12:095299 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325300 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275301 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275302 SendRequestAndExpectQuicResponse("hello!");
5303}
5304
[email protected]0fc924b2014-03-31 04:34:155305TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495306 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5307 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155308
5309 // Since we are using a proxy, the QUIC job will not succeed.
5310 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295311 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5312 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565313 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155314
5315 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565316 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485317 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565318 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155319
Ryan Sleevib8d7ea02018-05-07 20:01:015320 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155321 socket_factory_.AddSocketDataProvider(&http_data);
5322
5323 // In order for a new QUIC session to be established via alternate-protocol
5324 // without racing an HTTP connection, we need the host resolution to happen
5325 // synchronously.
5326 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295327 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565328 "");
[email protected]0fc924b2014-03-31 04:34:155329
rch9ae5b3b2016-02-11 00:36:295330 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325331 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275332 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155333 SendRequestAndExpectHttpResponse("hello world");
5334}
5335
[email protected]1e960032013-12-20 19:00:205336TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435337 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5338 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5339 return;
5340 }
5341
Ryan Hamiltonabad59e2019-06-06 04:02:595342 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235343 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495344 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255345 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235346 mock_quic_data.AddWrite(SYNCHRONOUS,
5347 ConstructInitialSettingsPacket(packet_num++));
5348 }
Nick Harper057264a82019-09-12 23:33:495349 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365350 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235351 SYNCHRONOUS,
5352 ConstructClientRequestHeadersPacket(
5353 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5354 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435355 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335356 ASYNC, ConstructServerResponseHeadersPacket(
5357 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5358 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435359 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335360 mock_quic_data.AddRead(
5361 ASYNC, ConstructServerDataPacket(
5362 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175363 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:235364 mock_quic_data.AddWrite(SYNCHRONOUS,
5365 ConstructClientAckPacket(packet_num++, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595366 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045367 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125368
rtennetib8e80fb2016-05-16 00:12:095369 // The non-alternate protocol job needs to hang in order to guarantee that
5370 // the alternate-protocol job will "win".
5371 AddHangingNonAlternateProtocolSocketData();
5372
[email protected]11c05872013-08-20 02:04:125373 // In order for a new QUIC session to be established via alternate-protocol
5374 // without racing an HTTP connection, we need the host resolution to happen
5375 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5376 // connection to the the server, in this test we require confirmation
5377 // before encrypting so the HTTP job will still start.
5378 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295379 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565380 "");
[email protected]11c05872013-08-20 02:04:125381
rch3f4b8452016-02-23 16:59:325382 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435383 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5384 false);
Ryan Hamilton9835e662018-08-02 05:36:275385 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125386
bnc691fda62016-08-12 00:43:165387 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125388 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365389 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125391
5392 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:005393 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015394 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505395
bnc691fda62016-08-12 00:43:165396 CheckWasQuicResponse(&trans);
5397 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125398}
5399
Steven Valdez58097ec32018-07-16 18:29:045400TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435401 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5402 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5403 return;
5404 }
5405
Ryan Hamilton3cc2c152019-07-09 19:36:015406 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595407 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035408 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255409 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495410 mock_quic_data.AddWrite(
5411 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
5412 }
Steven Valdez58097ec32018-07-16 18:29:045413 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015414 SYNCHRONOUS,
5415 ConstructClientRequestHeadersPacket(
5416 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5417 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335418 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025419 ASYNC, ConstructServerResponseHeadersPacket(
5420 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5421 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075422 if (VersionUsesHttp3(version_.transport_version)) {
5423 mock_quic_data.AddWrite(
5424 SYNCHRONOUS,
5425 ConstructClientAckAndDataPacket(
5426 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5427 StreamCancellationQpackDecoderInstruction(0)));
5428 mock_quic_data.AddWrite(SYNCHRONOUS,
5429 client_maker_.MakeRstPacket(
5430 packet_number++, false,
5431 GetNthClientInitiatedBidirectionalStreamId(0),
5432 quic::QUIC_STREAM_CANCELLED));
5433 } else {
5434 mock_quic_data.AddWrite(
5435 SYNCHRONOUS,
5436 ConstructClientAckAndRstPacket(
5437 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5438 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5439 }
Steven Valdez58097ec32018-07-16 18:29:045440
5441 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5442
Steven Valdez58097ec32018-07-16 18:29:045443 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015444 SYNCHRONOUS,
5445 ConstructClientRequestHeadersPacket(
5446 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5447 true, GetRequestHeaders("GET", "https", "/"),
5448 GetNthClientInitiatedBidirectionalStreamId(0)));
Steven Valdez58097ec32018-07-16 18:29:045449 mock_quic_data.AddRead(
5450 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335451 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:025452 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435453 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045454 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335455 ASYNC, ConstructServerDataPacket(
5456 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:175457 header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045458 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015459 SYNCHRONOUS,
5460 ConstructClientAckAndConnectionClosePacket(packet_number++, 3, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045461 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5462 mock_quic_data.AddRead(ASYNC, 0); // EOF
5463
5464 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5465
5466 // In order for a new QUIC session to be established via alternate-protocol
5467 // without racing an HTTP connection, we need the host resolution to happen
5468 // synchronously.
5469 host_resolver_.set_synchronous_mode(true);
5470 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5471 "");
Steven Valdez58097ec32018-07-16 18:29:045472
5473 AddHangingNonAlternateProtocolSocketData();
5474 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275475 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565476 QuicStreamFactoryPeer::SetAlarmFactory(
5477 session_->quic_stream_factory(),
5478 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225479 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045480
5481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5482 TestCompletionCallback callback;
5483 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5484 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5485
5486 // Confirm the handshake after the 425 Too Early.
5487 base::RunLoop().RunUntilIdle();
5488
5489 // The handshake hasn't been confirmed yet, so the retry should not have
5490 // succeeded.
5491 EXPECT_FALSE(callback.have_result());
5492
5493 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:005494 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Steven Valdez58097ec32018-07-16 18:29:045495
5496 EXPECT_THAT(callback.WaitForResult(), IsOk());
5497 CheckWasQuicResponse(&trans);
5498 CheckResponseData(&trans, "hello!");
5499}
5500
5501TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435502 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5503 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5504 return;
5505 }
5506
Ryan Hamilton3cc2c152019-07-09 19:36:015507 uint64_t packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595508 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:035509 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255510 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:495511 mock_quic_data.AddWrite(
5512 SYNCHRONOUS, client_maker_.MakeInitialSettingsPacket(packet_number++));
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(0), true,
5518 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335519 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025520 ASYNC, ConstructServerResponseHeadersPacket(
5521 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5522 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075523 if (VersionUsesHttp3(version_.transport_version)) {
5524 mock_quic_data.AddWrite(
5525 SYNCHRONOUS,
5526 ConstructClientAckAndDataPacket(
5527 packet_number++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
5528 StreamCancellationQpackDecoderInstruction(0)));
5529 mock_quic_data.AddWrite(SYNCHRONOUS,
5530 client_maker_.MakeRstPacket(
5531 packet_number++, false,
5532 GetNthClientInitiatedBidirectionalStreamId(0),
5533 quic::QUIC_STREAM_CANCELLED));
5534 } else {
5535 mock_quic_data.AddWrite(
5536 SYNCHRONOUS,
5537 ConstructClientAckAndRstPacket(
5538 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
5539 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5540 }
Steven Valdez58097ec32018-07-16 18:29:045541
5542 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5543
Steven Valdez58097ec32018-07-16 18:29:045544 mock_quic_data.AddWrite(
Ryan Hamilton3cc2c152019-07-09 19:36:015545 SYNCHRONOUS,
5546 ConstructClientRequestHeadersPacket(
5547 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1), false,
5548 true, GetRequestHeaders("GET", "https", "/"),
5549 GetNthClientInitiatedBidirectionalStreamId(0)));
Fan Yang32c5a112018-12-10 20:06:335550 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:025551 ASYNC, ConstructServerResponseHeadersPacket(
5552 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5553 GetResponseHeaders("425 TOO_EARLY")));
Bence Béky6e243aa2019-12-13 19:01:075554 if (VersionUsesHttp3(version_.transport_version)) {
5555 mock_quic_data.AddWrite(
5556 SYNCHRONOUS,
5557 ConstructClientAckAndDataPacket(
5558 packet_number++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
5559 StreamCancellationQpackDecoderInstruction(1)));
5560 mock_quic_data.AddWrite(SYNCHRONOUS,
5561 client_maker_.MakeRstPacket(
5562 packet_number++, false,
5563 GetNthClientInitiatedBidirectionalStreamId(1),
5564 quic::QUIC_STREAM_CANCELLED));
5565 } else {
5566 mock_quic_data.AddWrite(
5567 SYNCHRONOUS,
5568 ConstructClientAckAndRstPacket(
5569 packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
5570 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
5571 }
Steven Valdez58097ec32018-07-16 18:29:045572 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5573 mock_quic_data.AddRead(ASYNC, 0); // EOF
5574
5575 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5576
5577 // In order for a new QUIC session to be established via alternate-protocol
5578 // without racing an HTTP connection, we need the host resolution to happen
5579 // synchronously.
5580 host_resolver_.set_synchronous_mode(true);
5581 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5582 "");
Steven Valdez58097ec32018-07-16 18:29:045583
5584 AddHangingNonAlternateProtocolSocketData();
5585 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275586 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565587 QuicStreamFactoryPeer::SetAlarmFactory(
5588 session_->quic_stream_factory(),
5589 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
Victor Vasiliev7752898d2019-11-14 21:30:225590 context_.clock()));
Steven Valdez58097ec32018-07-16 18:29:045591
5592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5593 TestCompletionCallback callback;
5594 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5596
5597 // Confirm the handshake after the 425 Too Early.
5598 base::RunLoop().RunUntilIdle();
5599
5600 // The handshake hasn't been confirmed yet, so the retry should not have
5601 // succeeded.
5602 EXPECT_FALSE(callback.have_result());
5603
5604 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:005605 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Steven Valdez58097ec32018-07-16 18:29:045606
5607 EXPECT_THAT(callback.WaitForResult(), IsOk());
5608 const HttpResponseInfo* response = trans.GetResponseInfo();
5609 ASSERT_TRUE(response != nullptr);
5610 ASSERT_TRUE(response->headers.get() != nullptr);
5611 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5612 EXPECT_TRUE(response->was_fetched_via_spdy);
5613 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085614 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5615 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045616}
5617
zhongyica364fbb2015-12-12 03:39:125618TEST_P(QuicNetworkTransactionTest,
5619 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435620 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5621 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5622 return;
5623 }
5624
Victor Vasilieva1e66d72019-12-05 17:55:385625 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595626 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235627 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495628 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255629 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235630 mock_quic_data.AddWrite(SYNCHRONOUS,
5631 ConstructInitialSettingsPacket(packet_num++));
5632 }
Nick Harper057264a82019-09-12 23:33:495633 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365634 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235635 SYNCHRONOUS,
5636 ConstructClientRequestHeadersPacket(
5637 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5638 true, GetRequestHeaders("GET", "https", "/")));
zhongyica364fbb2015-12-12 03:39:125639 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525640 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435641 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125642 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5643
5644 // The non-alternate protocol job needs to hang in order to guarantee that
5645 // the alternate-protocol job will "win".
5646 AddHangingNonAlternateProtocolSocketData();
5647
5648 // In order for a new QUIC session to be established via alternate-protocol
5649 // without racing an HTTP connection, we need the host resolution to happen
5650 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5651 // connection to the the server, in this test we require confirmation
5652 // before encrypting so the HTTP job will still start.
5653 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295654 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125655 "");
zhongyica364fbb2015-12-12 03:39:125656
rch3f4b8452016-02-23 16:59:325657 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435658 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5659 false);
Ryan Hamilton9835e662018-08-02 05:36:275660 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125661
bnc691fda62016-08-12 00:43:165662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125663 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365664 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125666
5667 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:005668 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015669 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125670
5671 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525672 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125673
bnc691fda62016-08-12 00:43:165674 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125675 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525676 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5677 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125678}
5679
5680TEST_P(QuicNetworkTransactionTest,
5681 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435682 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5683 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5684 return;
5685 }
5686
Victor Vasilieva1e66d72019-12-05 17:55:385687 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595688 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235689 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495690 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255691 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235692 mock_quic_data.AddWrite(SYNCHRONOUS,
5693 ConstructInitialSettingsPacket(packet_num++));
5694 }
Nick Harper057264a82019-09-12 23:33:495695 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365696 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235697 SYNCHRONOUS,
5698 ConstructClientRequestHeadersPacket(
5699 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5700 true, GetRequestHeaders("GET", "https", "/")));
zhongyif28b4a32016-04-25 21:35:215701 // Peer sending data from an non-existing stream causes this end to raise
5702 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335703 mock_quic_data.AddRead(
5704 ASYNC, ConstructServerRstPacket(
5705 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5706 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215707 std::string quic_error_details = "Data for nonexistent stream";
Findit2403b85d2019-11-19 05:06:375708 mock_quic_data.AddWrite(
5709 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
Bence Békyde6290f2019-12-19 15:21:535710 packet_num++, 1, 1, 1, quic::QUIC_INVALID_STREAM_ID,
5711 quic_error_details, quic::IETF_RST_STREAM));
zhongyica364fbb2015-12-12 03:39:125712 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5713
5714 // The non-alternate protocol job needs to hang in order to guarantee that
5715 // the alternate-protocol job will "win".
5716 AddHangingNonAlternateProtocolSocketData();
5717
5718 // In order for a new QUIC session to be established via alternate-protocol
5719 // without racing an HTTP connection, we need the host resolution to happen
5720 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5721 // connection to the the server, in this test we require confirmation
5722 // before encrypting so the HTTP job will still start.
5723 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295724 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125725 "");
zhongyica364fbb2015-12-12 03:39:125726
rch3f4b8452016-02-23 16:59:325727 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435728 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5729 false);
Ryan Hamilton9835e662018-08-02 05:36:275730 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125731
bnc691fda62016-08-12 00:43:165732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125733 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365734 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125736
5737 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:005738 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015739 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125740 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525741 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125742
bnc691fda62016-08-12 00:43:165743 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525744 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125745}
5746
Nick Harper057264a82019-09-12 23:33:495747TEST_P(QuicNetworkTransactionTest, RstStreamErrorHandling) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435748 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5749 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5750 return;
5751 }
5752
Ryan Hamiltonabad59e2019-06-06 04:02:595753 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235754 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495755 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255756 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235757 mock_quic_data.AddWrite(SYNCHRONOUS,
5758 ConstructInitialSettingsPacket(packet_num++));
5759 }
Nick Harper057264a82019-09-12 23:33:495760 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365761 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235762 SYNCHRONOUS,
5763 ConstructClientRequestHeadersPacket(
5764 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5765 true, GetRequestHeaders("GET", "https", "/")));
rchcd5f1c62016-06-23 02:43:485766 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335767 mock_quic_data.AddRead(
5768 ASYNC, ConstructServerResponseHeadersPacket(
5769 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5770 GetResponseHeaders("200 OK")));
5771 mock_quic_data.AddRead(
5772 ASYNC, ConstructServerRstPacket(
5773 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5774 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075775
5776 if (VersionUsesHttp3(version_.transport_version)) {
5777 mock_quic_data.AddWrite(
5778 SYNCHRONOUS,
5779 ConstructClientAckAndDataPacket(
5780 packet_num++, false, GetQpackDecoderStreamId(), 2, 1, 1, false,
5781 StreamCancellationQpackDecoderInstruction(0)));
5782 } else {
5783 mock_quic_data.AddWrite(SYNCHRONOUS,
5784 ConstructClientAckPacket(packet_num++, 2, 1, 1));
5785 }
rchcd5f1c62016-06-23 02:43:485786 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5787 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5788
5789 // The non-alternate protocol job needs to hang in order to guarantee that
5790 // the alternate-protocol job will "win".
5791 AddHangingNonAlternateProtocolSocketData();
5792
5793 // In order for a new QUIC session to be established via alternate-protocol
5794 // without racing an HTTP connection, we need the host resolution to happen
5795 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5796 // connection to the the server, in this test we require confirmation
5797 // before encrypting so the HTTP job will still start.
5798 host_resolver_.set_synchronous_mode(true);
5799 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5800 "");
rchcd5f1c62016-06-23 02:43:485801
5802 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435803 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5804 false);
Ryan Hamilton9835e662018-08-02 05:36:275805 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485806
bnc691fda62016-08-12 00:43:165807 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485808 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365809 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485811
5812 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:005813 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485814 // Read the headers.
robpercival214763f2016-07-01 23:27:015815 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485816
bnc691fda62016-08-12 00:43:165817 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485818 ASSERT_TRUE(response != nullptr);
5819 ASSERT_TRUE(response->headers.get() != nullptr);
5820 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5821 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525822 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:085823 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5824 response->connection_info);
rchcd5f1c62016-06-23 02:43:485825
5826 std::string response_data;
bnc691fda62016-08-12 00:43:165827 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485828}
5829
Nick Harper057264a82019-09-12 23:33:495830TEST_P(QuicNetworkTransactionTest, RstStreamBeforeHeaders) {
Renjie Tang3d8a6ddd2019-11-20 00:18:435831 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
5832 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
5833 return;
5834 }
5835
Victor Vasilieva1e66d72019-12-05 17:55:385836 context_.params()->retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595837 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:235838 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:495839 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:255840 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:235841 mock_quic_data.AddWrite(SYNCHRONOUS,
5842 ConstructInitialSettingsPacket(packet_num++));
5843 }
Nick Harper057264a82019-09-12 23:33:495844 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
rch5cb522462017-04-25 20:18:365845 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:235846 SYNCHRONOUS,
5847 ConstructClientRequestHeadersPacket(
5848 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
5849 true, GetRequestHeaders("GET", "https", "/")));
Fan Yang32c5a112018-12-10 20:06:335850 mock_quic_data.AddRead(
5851 ASYNC, ConstructServerRstPacket(
5852 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5853 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:075854
5855 if (VersionUsesHttp3(version_.transport_version)) {
5856 mock_quic_data.AddWrite(
5857 SYNCHRONOUS, ConstructClientDataPacket(
5858 packet_num++, GetQpackDecoderStreamId(), true, false,
5859 StreamCancellationQpackDecoderInstruction(0)));
5860 }
5861
rchcd5f1c62016-06-23 02:43:485862 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5863 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5864
5865 // The non-alternate protocol job needs to hang in order to guarantee that
5866 // the alternate-protocol job will "win".
5867 AddHangingNonAlternateProtocolSocketData();
5868
5869 // In order for a new QUIC session to be established via alternate-protocol
5870 // without racing an HTTP connection, we need the host resolution to happen
5871 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5872 // connection to the the server, in this test we require confirmation
5873 // before encrypting so the HTTP job will still start.
5874 host_resolver_.set_synchronous_mode(true);
5875 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5876 "");
rchcd5f1c62016-06-23 02:43:485877
5878 CreateSession();
Matt Menkeb566c392019-09-11 23:22:435879 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
5880 false);
Ryan Hamilton9835e662018-08-02 05:36:275881 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485882
bnc691fda62016-08-12 00:43:165883 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485884 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365885 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015886 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485887
5888 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:005889 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485890 // Read the headers.
robpercival214763f2016-07-01 23:27:015891 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485892}
5893
[email protected]1e960032013-12-20 19:00:205894TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305895 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525896 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585897 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305898 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505899 MockRead(ASYNC, close->data(), close->length()),
5900 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5901 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305902 };
Ryan Sleevib8d7ea02018-05-07 20:01:015903 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305904 socket_factory_.AddSocketDataProvider(&quic_data);
5905
5906 // Main job which will succeed even though the alternate job fails.
5907 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025908 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5909 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5910 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305911
Ryan Sleevib8d7ea02018-05-07 20:01:015912 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305913 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565914 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305915
rch3f4b8452016-02-23 16:59:325916 CreateSession();
David Schinazic8281052019-01-24 06:14:175917 AddQuicAlternateProtocolMapping(
5918 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195919 SendRequestAndExpectHttpResponse("hello from http");
5920 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305921}
5922
Matt Menkeb32ba5122019-09-10 19:17:055923TEST_P(QuicNetworkTransactionTest,
5924 BrokenAlternateProtocolWithNetworkIsolationKey) {
5925 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
5926 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
5927 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
5928 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
5929
5930 base::test::ScopedFeatureList feature_list;
5931 feature_list.InitWithFeatures(
5932 // enabled_features
5933 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
5934 features::kPartitionConnectionsByNetworkIsolationKey},
5935 // disabled_features
5936 {});
5937 // Since HttpServerProperties caches the feature value, have to create a new
5938 // one.
5939 http_server_properties_ = std::make_unique<HttpServerProperties>();
5940
5941 // Alternate-protocol job
5942 std::unique_ptr<quic::QuicEncryptedPacket> close(
5943 ConstructServerConnectionClosePacket(1));
5944 MockRead quic_reads[] = {
5945 MockRead(ASYNC, close->data(), close->length()),
5946 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5947 MockRead(ASYNC, OK), // EOF
5948 };
5949 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
5950 socket_factory_.AddSocketDataProvider(&quic_data);
5951
5952 // Main job which will succeed even though the alternate job fails.
5953 MockRead http_reads[] = {
5954 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5955 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5956 MockRead(ASYNC, OK)};
5957
5958 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
5959 socket_factory_.AddSocketDataProvider(&http_data);
5960 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5961
5962 CreateSession();
5963 AddQuicAlternateProtocolMapping(
5964 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey1);
5965 AddQuicAlternateProtocolMapping(
5966 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT, kNetworkIsolationKey2);
5967 request_.network_isolation_key = kNetworkIsolationKey1;
5968 SendRequestAndExpectHttpResponse("hello from http");
5969
5970 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
5971 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
5972}
5973
[email protected]1e960032013-12-20 19:00:205974TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595975 // Alternate-protocol job
5976 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025977 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595978 };
Ryan Sleevib8d7ea02018-05-07 20:01:015979 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595980 socket_factory_.AddSocketDataProvider(&quic_data);
5981
5982 // Main job which will succeed even though the alternate job fails.
5983 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025984 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5985 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5986 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595987
Ryan Sleevib8d7ea02018-05-07 20:01:015988 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595989 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565990 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595991
rch3f4b8452016-02-23 16:59:325992 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595993
Ryan Hamilton9835e662018-08-02 05:36:275994 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195995 SendRequestAndExpectHttpResponse("hello from http");
5996 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595997}
5998
[email protected]00c159f2014-05-21 22:38:165999TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:536000 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:166001 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:026002 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:166003 };
Ryan Sleevib8d7ea02018-05-07 20:01:016004 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:166005 socket_factory_.AddSocketDataProvider(&quic_data);
6006
[email protected]eb71ab62014-05-23 07:57:536007 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:166008 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026009 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:166010 };
6011
Ryan Sleevib8d7ea02018-05-07 20:01:016012 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:166013 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6014 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566015 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:166016
rtennetib8e80fb2016-05-16 00:12:096017 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326018 CreateSession();
[email protected]00c159f2014-05-21 22:38:166019
Ryan Hamilton9835e662018-08-02 05:36:276020 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:166021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:166022 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166023 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6025 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:166026 ExpectQuicAlternateProtocolMapping();
6027}
6028
Zhongyi Shia0cef1082017-08-25 01:49:506029TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436030 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6031 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6032 return;
6033 }
6034
Zhongyi Shia0cef1082017-08-25 01:49:506035 // Tests that TCP job is delayed and QUIC job does not require confirmation
6036 // if QUIC was recently supported on the same IP on start.
6037
6038 // Set QUIC support on the last IP address, which is same with the local IP
6039 // address. Require confirmation mode will be turned off immediately when
6040 // local IP address is sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436041 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6042 IPAddress(192, 0, 2, 33));
Zhongyi Shia0cef1082017-08-25 01:49:506043
Ryan Hamiltonabad59e2019-06-06 04:02:596044 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:036045 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Nick Harper057264a82019-09-12 23:33:496046 int packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256047 if (VersionUsesHttp3(version_.transport_version)) {
Nick Harper057264a82019-09-12 23:33:496048 mock_quic_data.AddWrite(SYNCHRONOUS,
6049 ConstructInitialSettingsPacket(packet_number++));
6050 }
Zhongyi Shi32f2fd02018-04-16 18:23:436051 mock_quic_data.AddWrite(
Nick Harper057264a82019-09-12 23:33:496052 SYNCHRONOUS,
6053 ConstructClientRequestHeadersPacket(
6054 packet_number++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6055 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436056 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336057 ASYNC, ConstructServerResponseHeadersPacket(
6058 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6059 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436060 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336061 mock_quic_data.AddRead(
6062 ASYNC, ConstructServerDataPacket(
6063 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176064 header + "hello!"));
Nick Harper057264a82019-09-12 23:33:496065 mock_quic_data.AddWrite(SYNCHRONOUS,
6066 ConstructClientAckPacket(packet_number++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506067 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6068 mock_quic_data.AddRead(ASYNC, 0); // EOF
6069
6070 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6071 // No HTTP data is mocked as TCP job never starts in this case.
6072
6073 CreateSession();
6074 // QuicStreamFactory by default requires confirmation on construction.
Matt Menkeb566c392019-09-11 23:22:436075 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6076 false);
Zhongyi Shia0cef1082017-08-25 01:49:506077
Ryan Hamilton9835e662018-08-02 05:36:276078 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506079
6080 // Stall host resolution so that QUIC job will not succeed synchronously.
6081 // Socket will not be configured immediately and QUIC support is not sorted
6082 // out, TCP job will still be delayed as server properties indicates QUIC
6083 // support on last IP address.
6084 host_resolver_.set_synchronous_mode(false);
6085
6086 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6087 TestCompletionCallback callback;
6088 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6089 IsError(ERR_IO_PENDING));
6090 // Complete host resolution in next message loop so that QUIC job could
6091 // proceed.
6092 base::RunLoop().RunUntilIdle();
6093 EXPECT_THAT(callback.WaitForResult(), IsOk());
6094
6095 CheckWasQuicResponse(&trans);
6096 CheckResponseData(&trans, "hello!");
6097}
6098
6099TEST_P(QuicNetworkTransactionTest,
6100 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436101 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6102 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6103 return;
6104 }
6105
Zhongyi Shia0cef1082017-08-25 01:49:506106 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
6107 // was recently supported on a different IP address on start.
6108
6109 // Set QUIC support on the last IP address, which is different with the local
6110 // IP address. Require confirmation mode will remain when local IP address is
6111 // sorted out after we configure the UDP socket.
Matt Menkeb566c392019-09-11 23:22:436112 http_server_properties_->SetLastLocalAddressWhenQuicWorked(
6113 IPAddress(1, 2, 3, 4));
Zhongyi Shia0cef1082017-08-25 01:49:506114
Ryan Hamiltonabad59e2019-06-06 04:02:596115 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236116 int packet_num = 1;
Nick Harper057264a82019-09-12 23:33:496117 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Victor Vasiliev7da08172019-10-14 06:04:256118 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236119 mock_quic_data.AddWrite(SYNCHRONOUS,
6120 ConstructInitialSettingsPacket(packet_num++));
6121 }
Nick Harper057264a82019-09-12 23:33:496122 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shia0cef1082017-08-25 01:49:506123 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236124 SYNCHRONOUS,
6125 ConstructClientRequestHeadersPacket(
6126 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6127 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436128 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336129 ASYNC, ConstructServerResponseHeadersPacket(
6130 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6131 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436132 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336133 mock_quic_data.AddRead(
6134 ASYNC, ConstructServerDataPacket(
6135 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176136 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236137 mock_quic_data.AddWrite(SYNCHRONOUS,
6138 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:506139 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
6140 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6141 // No HTTP data is mocked as TCP job will be delayed and never starts.
6142
6143 CreateSession();
Matt Menkeb566c392019-09-11 23:22:436144 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6145 false);
Ryan Hamilton9835e662018-08-02 05:36:276146 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:506147
6148 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
6149 // Socket will not be configured immediately and QUIC support is not sorted
6150 // out, TCP job will still be delayed as server properties indicates QUIC
6151 // support on last IP address.
6152 host_resolver_.set_synchronous_mode(false);
6153
6154 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6155 TestCompletionCallback callback;
6156 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
6157 IsError(ERR_IO_PENDING));
6158
6159 // Complete host resolution in next message loop so that QUIC job could
6160 // proceed.
6161 base::RunLoop().RunUntilIdle();
6162 // Explicitly confirm the handshake so that QUIC job could succeed.
6163 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Victor Vasiliev585a2e82020-01-17 23:41:006164 quic::QuicSession::EVENT_HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:506165 EXPECT_THAT(callback.WaitForResult(), IsOk());
6166
6167 CheckWasQuicResponse(&trans);
6168 CheckResponseData(&trans, "hello!");
6169}
6170
Ryan Hamilton75f197262017-08-17 14:00:076171TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
6172 // Test that NetErrorDetails is correctly populated, even if the
6173 // handshake has not yet been confirmed and no stream has been created.
6174
6175 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:596176 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:076177 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6178 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
6179 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6180
6181 // Main job will also fail.
6182 MockRead http_reads[] = {
6183 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6184 };
6185
Ryan Sleevib8d7ea02018-05-07 20:01:016186 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:076187 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
6188 socket_factory_.AddSocketDataProvider(&http_data);
6189 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6190
6191 AddHangingNonAlternateProtocolSocketData();
6192 CreateSession();
6193 // Require handshake confirmation to ensure that no QUIC streams are
6194 // created, and to ensure that the TCP job does not wait for the QUIC
6195 // job to fail before it starts.
Matt Menkeb566c392019-09-11 23:22:436196 session_->quic_stream_factory()->set_is_quic_known_to_work_on_current_network(
6197 false);
Ryan Hamilton75f197262017-08-17 14:00:076198
Ryan Hamilton9835e662018-08-02 05:36:276199 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:076200 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6201 TestCompletionCallback callback;
6202 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6203 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6204 // Allow the TCP job to fail.
6205 base::RunLoop().RunUntilIdle();
6206 // Now let the QUIC job fail.
6207 mock_quic_data.Resume();
6208 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6209 ExpectQuicAlternateProtocolMapping();
6210 NetErrorDetails details;
6211 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526212 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:076213}
6214
[email protected]1e960032013-12-20 19:00:206215TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:456216 // Alternate-protocol job
6217 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:026218 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:456219 };
Ryan Sleevib8d7ea02018-05-07 20:01:016220 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:456221 socket_factory_.AddSocketDataProvider(&quic_data);
6222
[email protected]c92c1b52014-05-31 04:16:066223 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:016224 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:066225 socket_factory_.AddSocketDataProvider(&quic_data2);
6226
[email protected]4d283b32013-10-17 12:57:276227 // Final job that will proceed when the QUIC job fails.
6228 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026229 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6230 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6231 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:276232
Ryan Sleevib8d7ea02018-05-07 20:01:016233 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:276234 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566235 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:276236
rch3f4b8452016-02-23 16:59:326237 CreateSession();
[email protected]77c6c162013-08-17 02:57:456238
Ryan Hamilton9835e662018-08-02 05:36:276239 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:456240
[email protected]4d283b32013-10-17 12:57:276241 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:456242
6243 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:276244
rch37de576c2015-05-17 20:28:176245 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6246 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:456247}
6248
Matt Menkeb32ba5122019-09-10 19:17:056249TEST_P(QuicNetworkTransactionTest,
6250 FailedZeroRttBrokenAlternateProtocolWithNetworkIsolationKey) {
Renjie Tang3d8a6ddd2019-11-20 00:18:436251 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6252 // QUIC with TLS1.3 handshake doesn't support 0-rtt.
6253 return;
6254 }
6255
Matt Menkeb32ba5122019-09-10 19:17:056256 base::test::ScopedFeatureList feature_list;
6257 feature_list.InitWithFeatures(
6258 // enabled_features
6259 {features::kPartitionHttpServerPropertiesByNetworkIsolationKey,
6260 features::kPartitionConnectionsByNetworkIsolationKey},
6261 // disabled_features
6262 {});
6263 // Since HttpServerProperties caches the feature value, have to create a new
6264 // one.
6265 http_server_properties_ = std::make_unique<HttpServerProperties>();
6266
6267 const url::Origin kOrigin1 = url::Origin::Create(GURL("https://foo.test/"));
6268 const net::NetworkIsolationKey kNetworkIsolationKey1(kOrigin1, kOrigin1);
6269 const url::Origin kOrigin2 = url::Origin::Create(GURL("https://bar.test/"));
6270 const net::NetworkIsolationKey kNetworkIsolationKey2(kOrigin2, kOrigin2);
6271
6272 // Alternate-protocol job
6273 MockRead quic_reads[] = {
6274 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
6275 };
6276 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
6277 socket_factory_.AddSocketDataProvider(&quic_data);
6278
6279 // Second Alternate-protocol job which will race with the TCP job.
6280 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
6281 socket_factory_.AddSocketDataProvider(&quic_data2);
6282
6283 // Final job that will proceed when the QUIC job fails.
6284 MockRead http_reads[] = {
6285 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6286 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6287 MockRead(ASYNC, OK)};
6288
6289 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
6290 socket_factory_.AddSocketDataProvider(&http_data);
6291 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6292
6293 CreateSession();
6294
6295 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6296 kNetworkIsolationKey1);
6297 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT,
6298 kNetworkIsolationKey2);
6299
6300 request_.network_isolation_key = kNetworkIsolationKey1;
6301 SendRequestAndExpectHttpResponse("hello from http");
6302 EXPECT_TRUE(quic_data.AllReadDataConsumed());
6303 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
6304
6305 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6306 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6307
6308 // Subsequent requests using kNetworkIsolationKey1 should not use QUIC.
6309 AddHttpDataAndRunRequest();
6310 // Requests using other NetworkIsolationKeys can still use QUIC.
6311 request_.network_isolation_key = kNetworkIsolationKey2;
6312 AddQuicDataAndRunRequest();
6313
6314 // The last two requests should not have changed the alternative service
6315 // mappings.
6316 ExpectBrokenAlternateProtocolMapping(kNetworkIsolationKey1);
6317 ExpectQuicAlternateProtocolMapping(kNetworkIsolationKey2);
6318}
6319
[email protected]93b31772014-06-19 08:03:356320TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:036321 // Alternate-protocol job
6322 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:596323 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:036324 };
Ryan Sleevib8d7ea02018-05-07 20:01:016325 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036326 socket_factory_.AddSocketDataProvider(&quic_data);
6327
6328 // Main job that will proceed when the QUIC job fails.
6329 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026330 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6331 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6332 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:036333
Ryan Sleevib8d7ea02018-05-07 20:01:016334 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:036335 socket_factory_.AddSocketDataProvider(&http_data);
6336
rtennetib8e80fb2016-05-16 00:12:096337 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326338 CreateSession();
[email protected]65768442014-06-06 23:37:036339
Ryan Hamilton9835e662018-08-02 05:36:276340 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:036341
6342 SendRequestAndExpectHttpResponse("hello from http");
6343}
6344
[email protected]eb71ab62014-05-23 07:57:536345TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:336346 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:016347 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:496348 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:336349 socket_factory_.AddSocketDataProvider(&quic_data);
6350
6351 // Main job which will succeed even though the alternate job fails.
6352 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:026353 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
6354 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6355 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:336356
Ryan Sleevib8d7ea02018-05-07 20:01:016357 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:336358 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566359 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:336360
rch3f4b8452016-02-23 16:59:326361 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276362 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:336363 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:536364
6365 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:336366}
6367
[email protected]4fee9672014-01-08 14:47:156368TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
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));
rcha5399e02015-04-21 19:32:046372 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:156373
6374 // When the QUIC connection fails, we will try the request again over HTTP.
6375 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:486376 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:566377 MockRead("hello world"),
6378 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6379 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:156380
Ryan Sleevib8d7ea02018-05-07 20:01:016381 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:156382 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:566383 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:156384
6385 // In order for a new QUIC session to be established via alternate-protocol
6386 // without racing an HTTP connection, we need the host resolution to happen
6387 // synchronously.
6388 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:296389 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:566390 "");
[email protected]4fee9672014-01-08 14:47:156391
rch3f4b8452016-02-23 16:59:326392 CreateSession();
David Schinazic8281052019-01-24 06:14:176393 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
6394 AddQuicAlternateProtocolMapping(
6395 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:156396 SendRequestAndExpectHttpResponse("hello world");
6397}
6398
tbansalc3308d72016-08-27 10:25:046399// For an alternative proxy that supports QUIC, test that the request is
6400// successfully fetched by the main job when the alternate proxy job encounters
6401// an error.
6402TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
6403 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
6404}
6405TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
6406 TestAlternativeProxy(ERR_CONNECTION_FAILED);
6407}
6408TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
6409 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
6410}
6411TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
6412 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
6413}
6414TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
6415 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
6416}
6417TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
6418 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
6419}
6420TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
6421 TestAlternativeProxy(ERR_IO_PENDING);
6422}
6423TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
6424 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
6425}
6426
6427TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:596428 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:176429 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
6430 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:336431 mock_quic_data.AddWrite(
6432 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6433 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
6434 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436435 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:046436 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6437
6438 // When the QUIC connection fails, we will try the request again over HTTP.
6439 MockRead http_reads[] = {
6440 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6441 MockRead("hello world"),
6442 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6443 MockRead(ASYNC, OK)};
6444
Ryan Sleevib8d7ea02018-05-07 20:01:016445 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:046446 socket_factory_.AddSocketDataProvider(&http_data);
6447 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6448
6449 TestProxyDelegate test_proxy_delegate;
6450 const HostPortPair host_port_pair("myproxy.org", 443);
6451 test_proxy_delegate.set_alternative_proxy_server(
6452 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6453 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6454
Ramin Halavatica8d5252018-03-12 05:33:496455 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6456 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526457 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046458 request_.url = GURL("http://mail.example.org/");
6459
6460 // In order for a new QUIC session to be established via alternate-protocol
6461 // without racing an HTTP connection, we need the host resolution to happen
6462 // synchronously.
6463 host_resolver_.set_synchronous_mode(true);
6464 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:046465
6466 CreateSession();
David Schinazic8281052019-01-24 06:14:176467 crypto_client_stream_factory_.set_handshake_mode(
6468 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046469 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596470 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166471 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046472}
6473
bnc508835902015-05-12 20:10:296474TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586475 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386476 EXPECT_FALSE(
6477 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:596478 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236479 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256480 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236481 mock_quic_data.AddWrite(SYNCHRONOUS,
6482 ConstructInitialSettingsPacket(packet_num++));
6483 }
rch5cb522462017-04-25 20:18:366484 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236485 SYNCHRONOUS,
6486 ConstructClientRequestHeadersPacket(
6487 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6488 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436489 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336490 ASYNC, ConstructServerResponseHeadersPacket(
6491 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6492 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436493 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336494 mock_quic_data.AddRead(
6495 ASYNC, ConstructServerDataPacket(
6496 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176497 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236498 mock_quic_data.AddWrite(SYNCHRONOUS,
6499 ConstructClientAckPacket(packet_num++, 2, 1, 1));
rchb27683c2015-07-29 23:53:506500 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296501 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6502
bncb07c05532015-05-14 19:07:206503 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096504 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326505 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276506 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296507 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386508 EXPECT_TRUE(
6509 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296510}
6511
zhongyi363c91c2017-03-23 23:16:086512// TODO(zhongyi): disabled this broken test as it was not testing the correct
6513// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6514TEST_P(QuicNetworkTransactionTest,
6515 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276516 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596517 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496518 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046519
6520 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046521
6522 test_proxy_delegate.set_alternative_proxy_server(
6523 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526524 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046525
6526 request_.url = GURL("http://mail.example.org/");
6527
6528 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6529 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016530 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046531 socket_factory_.AddSocketDataProvider(&socket_data);
6532
6533 // The non-alternate protocol job needs to hang in order to guarantee that
6534 // the alternate-protocol job will "win".
6535 AddHangingNonAlternateProtocolSocketData();
6536
6537 CreateSession();
6538 request_.method = "POST";
6539 ChunkedUploadDataStream upload_data(0);
6540 upload_data.AppendData("1", 1, true);
6541
6542 request_.upload_data_stream = &upload_data;
6543
6544 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6545 TestCompletionCallback callback;
6546 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6548 EXPECT_NE(OK, callback.WaitForResult());
6549
6550 // Verify that the alternative proxy server is not marked as broken.
6551 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6552
6553 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596554 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276555
6556 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6557 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6558 1);
tbansalc3308d72016-08-27 10:25:046559}
6560
rtenneti56977812016-01-15 19:26:566561TEST_P(QuicNetworkTransactionTest, QuicUpload) {
Victor Vasilieva1e66d72019-12-05 17:55:386562 context_.params()->origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576563 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566564
Renjie Tangaadb84b2019-08-31 01:00:236565 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:256566 if (!VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236567 mock_quic_data.AddRead(SYNCHRONOUS, OK);
6568 else
6569 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6570 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6571 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6572
6573 /*MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6574 //MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
6575 MockWrite writes[] = {};
Ryan Sleevib8d7ea02018-05-07 20:01:016576 SequencedSocketData socket_data(reads, writes);
Renjie Tangaadb84b2019-08-31 01:00:236577 socket_factory_.AddSocketDataProvider(&socket_data);*/
rtenneti56977812016-01-15 19:26:566578
rtennetib8e80fb2016-05-16 00:12:096579 // The non-alternate protocol job needs to hang in order to guarantee that
6580 // the alternate-protocol job will "win".
6581 AddHangingNonAlternateProtocolSocketData();
6582
rtenneti56977812016-01-15 19:26:566583 CreateSession();
6584 request_.method = "POST";
6585 ChunkedUploadDataStream upload_data(0);
6586 upload_data.AppendData("1", 1, true);
6587
6588 request_.upload_data_stream = &upload_data;
6589
bnc691fda62016-08-12 00:43:166590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566591 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166592 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016593 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566594 EXPECT_NE(OK, callback.WaitForResult());
6595}
6596
rche11300ef2016-09-02 01:44:286597TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Victor Vasilieva1e66d72019-12-05 17:55:386598 context_.params()->retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286599 ScopedMockNetworkChangeNotifier network_change_notifier;
6600 MockNetworkChangeNotifier* mock_ncn =
6601 network_change_notifier.mock_network_change_notifier();
6602 mock_ncn->ForceNetworkHandlesSupported();
6603 mock_ncn->SetConnectedNetworksList(
6604 {kDefaultNetworkForTests, kNewNetworkForTests});
6605
Victor Vasilieva1e66d72019-12-05 17:55:386606 context_.params()->origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286607 HostPortPair::FromString("mail.example.org:443"));
Victor Vasilieva1e66d72019-12-05 17:55:386608 context_.params()->migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286609
Ryan Hamiltonabad59e2019-06-06 04:02:596610 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286611 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236612 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256613 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236614 socket_data.AddWrite(SYNCHRONOUS,
6615 ConstructInitialSettingsPacket(packet_num++));
6616 }
Fan Yang32c5a112018-12-10 20:06:336617 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236618 SYNCHRONOUS,
6619 ConstructClientRequestHeadersPacket(
6620 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6621 false, GetRequestHeaders("POST", "https", "/")));
rche11300ef2016-09-02 01:44:286622 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6623 socket_data.AddSocketDataToFactory(&socket_factory_);
6624
Ryan Hamiltonabad59e2019-06-06 04:02:596625 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286626 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6627 socket_data2.AddSocketDataToFactory(&socket_factory_);
6628
6629 // The non-alternate protocol job needs to hang in order to guarantee that
6630 // the alternate-protocol job will "win".
6631 AddHangingNonAlternateProtocolSocketData();
6632
6633 CreateSession();
6634 request_.method = "POST";
6635 ChunkedUploadDataStream upload_data(0);
6636
6637 request_.upload_data_stream = &upload_data;
6638
rdsmith1d343be52016-10-21 20:37:506639 std::unique_ptr<HttpNetworkTransaction> trans(
6640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286641 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506642 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6644
6645 base::RunLoop().RunUntilIdle();
6646 upload_data.AppendData("1", 1, true);
6647 base::RunLoop().RunUntilIdle();
6648
6649 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506650 trans.reset();
rche11300ef2016-09-02 01:44:286651 session_.reset();
6652}
6653
Ryan Hamilton4b3574532017-10-30 20:17:256654TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386655 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256656 HostPortPair::FromString("mail.example.org:443"));
6657
Ryan Hamiltonabad59e2019-06-06 04:02:596658 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236659 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256660 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236661 socket_data.AddWrite(SYNCHRONOUS,
6662 ConstructInitialSettingsPacket(packet_num++));
6663 }
Ryan Hamilton4b3574532017-10-30 20:17:256664 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336665 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236666 SYNCHRONOUS,
6667 ConstructClientRequestHeadersPacket(
6668 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6669 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436670 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336671 ASYNC, ConstructServerResponseHeadersPacket(
6672 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6673 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436674 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336675 socket_data.AddRead(
6676 ASYNC, ConstructServerDataPacket(
6677 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176678 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236679 socket_data.AddWrite(SYNCHRONOUS,
6680 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256681 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436682 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6683 // TLS1.3 supports multiple packet number space, so the ack is no longer
6684 // sent.
6685 socket_data.AddWrite(
6686 SYNCHRONOUS,
6687 client_maker_.MakeConnectionClosePacket(
6688 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6689 } else {
Bence Békyde6290f2019-12-19 15:21:536690 socket_data.AddWrite(SYNCHRONOUS,
6691 client_maker_.MakeAckAndConnectionClosePacket(
6692 packet_num++, false, 2, 1, 1,
6693 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Renjie Tang3d8a6ddd2019-11-20 00:18:436694 }
Ryan Hamilton4b3574532017-10-30 20:17:256695
6696 socket_data.AddSocketDataToFactory(&socket_factory_);
6697
6698 CreateSession();
6699
6700 SendRequestAndExpectQuicResponse("hello!");
6701 session_.reset();
6702}
6703
6704TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386705 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256706 HostPortPair::FromString("mail.example.org:443"));
6707
Ryan Hamiltonabad59e2019-06-06 04:02:596708 MockQuicData socket_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:236709 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256710 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236711 socket_data.AddWrite(SYNCHRONOUS,
6712 ConstructInitialSettingsPacket(packet_num++));
6713 }
Ryan Hamilton4b3574532017-10-30 20:17:256714 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336715 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236716 SYNCHRONOUS,
6717 ConstructClientRequestHeadersPacket(
6718 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
6719 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436720 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336721 ASYNC, ConstructServerResponseHeadersPacket(
6722 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6723 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436724 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336725 socket_data.AddRead(
6726 ASYNC, ConstructServerDataPacket(
6727 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176728 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:236729 socket_data.AddWrite(SYNCHRONOUS,
6730 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256731 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tang3d8a6ddd2019-11-20 00:18:436732 if (version_.handshake_protocol == quic::PROTOCOL_TLS1_3) {
6733 // TLS1.3 supports multiple packet number space, so the ack is no longer
6734 // sent.
6735 socket_data.AddWrite(
6736 SYNCHRONOUS,
6737 client_maker_.MakeConnectionClosePacket(
6738 packet_num++, false, quic::QUIC_CONNECTION_CANCELLED, "net error"));
6739 } else {
Bence Békyde6290f2019-12-19 15:21:536740 socket_data.AddWrite(SYNCHRONOUS,
6741 client_maker_.MakeAckAndConnectionClosePacket(
6742 packet_num++, false, 2, 1, 1,
6743 quic::QUIC_CONNECTION_CANCELLED, "net error", 0));
Renjie Tang3d8a6ddd2019-11-20 00:18:436744 }
Ryan Hamilton4b3574532017-10-30 20:17:256745
6746 socket_data.AddSocketDataToFactory(&socket_factory_);
6747
6748 CreateSession();
6749
6750 SendRequestAndExpectQuicResponse("hello!");
6751 session_.reset();
6752}
6753
Ryan Hamilton9edcf1a2017-11-22 05:55:176754TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386755 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6756 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256757 HostPortPair::FromString("mail.example.org:443"));
6758
Ryan Hamiltonabad59e2019-06-06 04:02:596759 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256760 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256761 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236762 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176763 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256764 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6765 }
6766 socket_data.AddSocketDataToFactory(&socket_factory_);
6767
6768 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176769 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176770 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6771 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256772
Victor Vasiliev7752898d2019-11-14 21:30:226773 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6775 TestCompletionCallback callback;
6776 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176778 while (!callback.have_result()) {
6779 base::RunLoop().RunUntilIdle();
6780 quic_task_runner_->RunUntilIdle();
6781 }
6782 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256783 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176784 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6785 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6786 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226787 EXPECT_TRUE(context_.clock()->Now() - start >
6788 quic::QuicTime::Delta::FromSeconds(4));
6789 EXPECT_TRUE(context_.clock()->Now() - start <
6790 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256791}
6792
Ryan Hamilton9edcf1a2017-11-22 05:55:176793TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Victor Vasilieva1e66d72019-12-05 17:55:386794 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6795 context_.params()->origins_to_force_quic_on.insert(
Ryan Hamilton4b3574532017-10-30 20:17:256796 HostPortPair::FromString("mail.example.org:443"));
6797
Ryan Hamiltonabad59e2019-06-06 04:02:596798 MockQuicData socket_data(version_);
Ryan Hamilton4b3574532017-10-30 20:17:256799 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Victor Vasiliev7da08172019-10-14 06:04:256800 if (VersionUsesHttp3(version_.transport_version))
Renjie Tangaadb84b2019-08-31 01:00:236801 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1));
Ryan Hamilton9edcf1a2017-11-22 05:55:176802 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256803 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6804 }
6805 socket_data.AddSocketDataToFactory(&socket_factory_);
6806
6807 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176808 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176809 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6810 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256811
Victor Vasiliev7752898d2019-11-14 21:30:226812 quic::QuicTime start = context_.clock()->Now();
Ryan Hamilton4b3574532017-10-30 20:17:256813 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6814 TestCompletionCallback callback;
6815 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176817 while (!callback.have_result()) {
6818 base::RunLoop().RunUntilIdle();
6819 quic_task_runner_->RunUntilIdle();
6820 }
6821 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256822 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176823 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6824 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6825 // Backoff should take between 4 - 5 seconds.
Victor Vasiliev7752898d2019-11-14 21:30:226826 EXPECT_TRUE(context_.clock()->Now() - start >
6827 quic::QuicTime::Delta::FromSeconds(4));
6828 EXPECT_TRUE(context_.clock()->Now() - start <
6829 quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256830}
6831
Cherie Shi7596de632018-02-22 07:28:186832TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Victor Vasilieva1e66d72019-12-05 17:55:386833 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6834 context_.params()->origins_to_force_quic_on.insert(
Cherie Shi7596de632018-02-22 07:28:186835 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436836 const std::string error_details =
Zhongyi Shid1c00fc42019-12-14 06:05:096837 quiche::QuicheStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6838 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186839
Ryan Hamiltonabad59e2019-06-06 04:02:596840 MockQuicData socket_data(version_);
Cherie Shi7596de632018-02-22 07:28:186841 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie Tangaadb84b2019-08-31 01:00:236842 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:256843 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236844 socket_data.AddWrite(SYNCHRONOUS,
6845 ConstructInitialSettingsPacket(packet_num++));
6846 }
Cherie Shi7596de632018-02-22 07:28:186847 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6848 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526849 socket_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:236850 SYNCHRONOUS,
6851 client_maker_.MakeConnectionClosePacket(
6852 packet_num + 1, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186853 socket_data.AddSocketDataToFactory(&socket_factory_);
6854
6855 CreateSession();
6856
6857 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6858 TestCompletionCallback callback;
6859 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6861 base::RunLoop().RunUntilIdle();
6862 ASSERT_TRUE(callback.have_result());
6863 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6864 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6865 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6866}
6867
ckrasic769733c2016-06-30 00:42:136868// Adds coverage to catch regression such as https://crbug.com/622043
6869TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
Ryan Hamilton6c6493102019-12-05 21:36:506870 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6871 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386872 context_.params()->origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136873 HostPortPair::FromString("mail.example.org:443"));
6874
Ryan Hamiltonabad59e2019-06-06 04:02:596875 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236876 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:256877 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236878 mock_quic_data.AddWrite(
6879 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6880 }
Zhongyi Shi32f2fd02018-04-16 18:23:436881 mock_quic_data.AddWrite(
6882 SYNCHRONOUS,
6883 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336884 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026885 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:436886 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026887 ASYNC,
6888 ConstructServerPushPromisePacket(
6889 1, GetNthClientInitiatedBidirectionalStreamId(0),
6890 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6891 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316892 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426893 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:296894 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026895 mock_quic_data.AddWrite(
6896 SYNCHRONOUS,
6897 ConstructClientPriorityPacket(
6898 client_packet_number++, false,
6899 GetNthServerInitiatedUnidirectionalStreamId(0),
6900 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576901 }
Zhongyi Shi32f2fd02018-04-16 18:23:436902 mock_quic_data.AddRead(
6903 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336904 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026905 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:576906 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436907 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6908 mock_quic_data.AddRead(
6909 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336910 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:026911 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436912 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436913 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336914 ASYNC, ConstructServerDataPacket(
6915 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176916 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576917 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436918 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436919 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436920 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336921 ASYNC, ConstructServerDataPacket(
6922 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:176923 header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336924 mock_quic_data.AddWrite(SYNCHRONOUS,
6925 ConstructClientAckAndRstPacket(
6926 client_packet_number++,
6927 GetNthServerInitiatedUnidirectionalStreamId(0),
6928 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136929 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6930 mock_quic_data.AddRead(ASYNC, 0); // EOF
6931 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6932
6933 // The non-alternate protocol job needs to hang in order to guarantee that
6934 // the alternate-protocol job will "win".
6935 AddHangingNonAlternateProtocolSocketData();
6936
6937 CreateSession();
6938
6939 // PUSH_PROMISE handling in the http layer gets exercised here.
6940 SendRequestAndExpectQuicResponse("hello!");
6941
6942 request_.url = GURL("https://mail.example.org/pushed.jpg");
6943 SendRequestAndExpectQuicResponse("and hello!");
6944
6945 // Check that the NetLog was filled reasonably.
Eric Roman79cc7552019-07-19 02:17:546946 auto entries = net_log_.GetEntries();
ckrasic769733c2016-06-30 00:42:136947 EXPECT_LT(0u, entries.size());
6948
6949 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6950 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006951 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6952 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136953 EXPECT_LT(0, pos);
6954}
6955
rch56ec40a2017-06-23 14:48:446956// Regression test for http://crbug.com/719461 in which a promised stream
6957// is closed before the pushed headers arrive, but after the connection
6958// is closed and before the callbacks are executed.
6959TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamilton6c6493102019-12-05 21:36:506960 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
6961 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:386962 context_.params()->retry_without_alt_svc_on_quic_errors = false;
6963 context_.params()->origins_to_force_quic_on.insert(
rch56ec40a2017-06-23 14:48:446964 HostPortPair::FromString("mail.example.org:443"));
6965
Ryan Hamiltonabad59e2019-06-06 04:02:596966 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:236967 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446968 // Initial SETTINGS frame.
Victor Vasiliev7da08172019-10-14 06:04:256969 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:236970 mock_quic_data.AddWrite(
6971 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
6972 }
rch56ec40a2017-06-23 14:48:446973 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436974 mock_quic_data.AddWrite(
6975 SYNCHRONOUS,
6976 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336977 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:026978 true, true, GetRequestHeaders("GET", "https", "/")));
rch56ec40a2017-06-23 14:48:446979 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436980 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:026981 ASYNC,
6982 ConstructServerPushPromisePacket(
6983 1, GetNthClientInitiatedBidirectionalStreamId(0),
6984 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6985 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:316986 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:426987 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:296988 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:026989 mock_quic_data.AddWrite(
6990 SYNCHRONOUS,
6991 ConstructClientPriorityPacket(
6992 client_packet_number++, false,
6993 GetNthServerInitiatedUnidirectionalStreamId(0),
6994 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:576995 }
rch56ec40a2017-06-23 14:48:446996 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436997 mock_quic_data.AddRead(
6998 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336999 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027000 GetResponseHeaders("200 OK")));
rch56ec40a2017-06-23 14:48:447001 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:577002 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437003 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:447004 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:437005 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437006 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337007 ASYNC, ConstructServerDataPacket(
7008 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177009 header + "hello!"));
rch56ec40a2017-06-23 14:48:447010 // Write error for the third request.
7011 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
7012 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7013 mock_quic_data.AddRead(ASYNC, 0); // EOF
7014 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7015
7016 CreateSession();
7017
7018 // Send a request which triggers a push promise from the server.
7019 SendRequestAndExpectQuicResponse("hello!");
7020
7021 // Start a push transaction that will be cancelled after the connection
7022 // is closed, but before the callback is executed.
7023 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:197024 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:447025 session_.get());
7026 TestCompletionCallback callback2;
7027 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
7028 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7029 base::RunLoop().RunUntilIdle();
7030
7031 // Cause the connection to close on a write error.
7032 HttpRequestInfo request3;
7033 request3.method = "GET";
7034 request3.url = GURL("https://mail.example.org/");
7035 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:107036 request3.traffic_annotation =
7037 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:447038 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
7039 TestCompletionCallback callback3;
7040 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
7041 IsError(ERR_IO_PENDING));
7042
7043 base::RunLoop().RunUntilIdle();
7044
7045 // When |trans2| is destroyed, the underlying stream will be closed.
7046 EXPECT_FALSE(callback2.have_result());
7047 trans2 = nullptr;
7048
7049 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
7050}
7051
ckrasicda193a82016-07-09 00:39:367052TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
Victor Vasilieva1e66d72019-12-05 17:55:387053 context_.params()->origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:367054 HostPortPair::FromString("mail.example.org:443"));
7055
Ryan Hamiltonabad59e2019-06-06 04:02:597056 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:367057
Renjief49758b2019-01-11 23:32:417058 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:257059 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237060 mock_quic_data.AddWrite(
7061 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
7062 }
ckrasicda193a82016-07-09 00:39:367063
Victor Vasiliev076657c2019-03-12 02:46:437064 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567065 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417066 mock_quic_data.AddWrite(
7067 SYNCHRONOUS,
7068 ConstructClientRequestHeadersAndDataFramesPacket(
7069 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7070 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027071 GetRequestHeaders("POST", "https", "/"), 0, nullptr, {"1"}));
Renjief49758b2019-01-11 23:32:417072 } else {
7073 mock_quic_data.AddWrite(
7074 SYNCHRONOUS,
7075 ConstructClientRequestHeadersAndDataFramesPacket(
7076 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7077 true, true, DEFAULT_PRIORITY,
Ryan Hamilton0d65a8c2019-06-07 00:46:027078 GetRequestHeaders("POST", "https", "/"), 0, nullptr,
Renjief49758b2019-01-11 23:32:417079 {header, "1"}));
7080 }
ckrasicda193a82016-07-09 00:39:367081
Zhongyi Shi32f2fd02018-04-16 18:23:437082 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337083 ASYNC, ConstructServerResponseHeadersPacket(
7084 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7085 GetResponseHeaders("200 OK")));
7086
Victor Vasiliev076657c2019-03-12 02:46:437087 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337088 mock_quic_data.AddRead(
7089 ASYNC, ConstructServerDataPacket(
7090 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177091 header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:367092
Renjief49758b2019-01-11 23:32:417093 mock_quic_data.AddWrite(
7094 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:367095
7096 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7097 mock_quic_data.AddRead(ASYNC, 0); // EOF
7098 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7099
7100 // The non-alternate protocol job needs to hang in order to guarantee that
7101 // the alternate-protocol job will "win".
7102 AddHangingNonAlternateProtocolSocketData();
7103
7104 CreateSession();
7105 request_.method = "POST";
7106 ChunkedUploadDataStream upload_data(0);
7107 upload_data.AppendData("1", 1, true);
7108
7109 request_.upload_data_stream = &upload_data;
7110
7111 SendRequestAndExpectQuicResponse("hello!");
7112}
7113
allada71b2efb2016-09-09 04:57:487114class QuicURLRequestContext : public URLRequestContext {
7115 public:
7116 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
7117 MockClientSocketFactory* socket_factory)
7118 : storage_(this) {
7119 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:077120 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:047121 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:487122 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:047123 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:597124 storage_.set_proxy_resolution_service(
7125 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:077126 storage_.set_ssl_config_service(
7127 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:487128 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:117129 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:487130 storage_.set_http_server_properties(
Matt Menke609160742019-08-02 18:47:267131 std::make_unique<HttpServerProperties>());
Bence Béky8f9d7d3952017-10-09 19:58:047132 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:487133 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:047134 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
7135 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
7136 false));
allada71b2efb2016-09-09 04:57:487137 }
7138
7139 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
7140
7141 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
7142
7143 private:
7144 MockClientSocketFactory* socket_factory_;
7145 URLRequestContextStorage storage_;
7146};
7147
7148TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
Victor Vasilieva1e66d72019-12-05 17:55:387149 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487150 HostPortPair::FromString("mail.example.org:443"));
7151
Ryan Hamiltonabad59e2019-06-06 04:02:597152 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237153 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257154 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237155 mock_quic_data.AddWrite(SYNCHRONOUS,
7156 ConstructInitialSettingsPacket(packet_num++));
7157 }
Ryan Hamilton0239aac2018-05-19 00:03:137158 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487159 headers["user-agent"] = "";
7160 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:337161 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237162 SYNCHRONOUS,
7163 ConstructClientRequestHeadersPacket(
7164 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7165 true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487166
Fan Yang32c5a112018-12-10 20:06:337167 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027168 ASYNC, ConstructServerResponseHeadersPacket(
7169 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7170 GetResponseHeaders("200 OK")));
7171 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457172 server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257173 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457174 ? GetNthClientInitiatedBidirectionalStreamId(0)
7175 : quic::QuicUtils::GetHeadersStreamId(
7176 version_.transport_version));
allada71b2efb2016-09-09 04:57:487177
Victor Vasiliev076657c2019-03-12 02:46:437178 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367179 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337180 ASYNC, ConstructServerDataPacket(
7181 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177182 "Main Resource Data"));
Renjie Tangaadb84b2019-08-31 01:00:237183 mock_quic_data.AddWrite(SYNCHRONOUS,
7184 ConstructClientAckPacket(packet_num++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487185
7186 mock_quic_data.AddRead(ASYNC, 0); // EOF
7187
7188 CreateSession();
7189
7190 TestDelegate delegate;
7191 QuicURLRequestContext quic_url_request_context(std::move(session_),
7192 &socket_factory_);
7193
7194 mock_quic_data.AddSocketDataToFactory(
7195 &quic_url_request_context.socket_factory());
7196 TestNetworkDelegate network_delegate;
7197 quic_url_request_context.set_network_delegate(&network_delegate);
7198
7199 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297200 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7201 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487202 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7203 &ssl_data_);
7204
7205 request->Start();
Wez2a31b222018-06-07 22:07:157206 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487207
7208 EXPECT_LT(0, request->GetTotalSentBytes());
7209 EXPECT_LT(0, request->GetTotalReceivedBytes());
allada71b2efb2016-09-09 04:57:487210 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
7211 request->raw_header_size());
Wez0e717112018-06-18 23:09:227212
7213 // Pump the message loop to allow all data to be consumed.
7214 base::RunLoop().RunUntilIdle();
7215
allada71b2efb2016-09-09 04:57:487216 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7217 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7218}
7219
7220TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
Ryan Hamilton6c6493102019-12-05 21:36:507221 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7222 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387223 context_.params()->origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:487224 HostPortPair::FromString("mail.example.org:443"));
7225
Ryan Hamiltonabad59e2019-06-06 04:02:597226 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237227 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257228 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237229 mock_quic_data.AddWrite(
7230 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7231 }
Ryan Hamilton0239aac2018-05-19 00:03:137232 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:487233 headers["user-agent"] = "";
7234 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:437235 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337236 SYNCHRONOUS,
7237 ConstructClientRequestHeadersPacket(
7238 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027239 true, true, std::move(headers)));
allada71b2efb2016-09-09 04:57:487240
Fan Yang2330d182019-08-05 14:50:507241 const quic::QuicStreamOffset initial = server_maker_.stream_offset(
7242 GetNthClientInitiatedBidirectionalStreamId(0));
Zhongyi Shi32f2fd02018-04-16 18:23:437243 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027244 ASYNC,
7245 ConstructServerPushPromisePacket(
7246 1, GetNthClientInitiatedBidirectionalStreamId(0),
7247 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7248 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Fan Yang2330d182019-08-05 14:50:507249 quic::QuicStreamOffset push_promise_offset = 0;
Victor Vasiliev7da08172019-10-14 06:04:257250 if (VersionUsesHttp3(version_.transport_version)) {
Fan Yang2330d182019-08-05 14:50:507251 push_promise_offset = server_maker_.stream_offset(
7252 GetNthClientInitiatedBidirectionalStreamId(0)) -
7253 initial;
7254 }
allada71b2efb2016-09-09 04:57:487255
Renjie Tang703fea92019-07-23 21:08:317256 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427257 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:297258 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027259 mock_quic_data.AddWrite(
7260 SYNCHRONOUS,
7261 ConstructClientPriorityPacket(
7262 client_packet_number++, false,
7263 GetNthServerInitiatedUnidirectionalStreamId(0),
7264 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577265 }
7266
Ryan Hamiltone940bd12019-06-30 02:46:457267 const quic::QuicStreamOffset initial_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257268 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457269 ? GetNthClientInitiatedBidirectionalStreamId(0)
7270 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Zhongyi Shi32f2fd02018-04-16 18:23:437271 mock_quic_data.AddRead(
7272 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337273 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027274 GetResponseHeaders("200 OK")));
Ryan Hamiltone940bd12019-06-30 02:46:457275 const quic::QuicStreamOffset final_offset = server_maker_.stream_offset(
Victor Vasiliev7da08172019-10-14 06:04:257276 quic::VersionUsesHttp3(version_.transport_version)
Ryan Hamiltone940bd12019-06-30 02:46:457277 ? GetNthClientInitiatedBidirectionalStreamId(0)
7278 : quic::QuicUtils::GetHeadersStreamId(version_.transport_version));
Ryan Hamilton0d65a8c2019-06-07 00:46:027279 quic::QuicStreamOffset expected_raw_header_response_size =
Ryan Hamiltone940bd12019-06-30 02:46:457280 final_offset - initial_offset;
allada71b2efb2016-09-09 04:57:487281
Yixin Wangb470bc882018-02-15 18:43:577282 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437283 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:487284
ckrasicbf2f59c2017-05-04 23:54:367285 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:437286 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337287 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027288 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437289 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:437290 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337291 ASYNC, ConstructServerDataPacket(
7292 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177293 header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:487294
Yixin Wangb470bc882018-02-15 18:43:577295 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437296 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:437297 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:367298 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337299 ASYNC, ConstructServerDataPacket(
7300 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177301 header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:487302
Zhongyi Shi32f2fd02018-04-16 18:23:437303 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:487304
7305 CreateSession();
7306
7307 TestDelegate delegate;
7308 QuicURLRequestContext quic_url_request_context(std::move(session_),
7309 &socket_factory_);
7310
7311 mock_quic_data.AddSocketDataToFactory(
7312 &quic_url_request_context.socket_factory());
7313 TestNetworkDelegate network_delegate;
7314 quic_url_request_context.set_network_delegate(&network_delegate);
7315
7316 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:297317 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
7318 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:487319 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
7320 &ssl_data_);
7321
7322 request->Start();
Wez2a31b222018-06-07 22:07:157323 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:487324
7325 EXPECT_LT(0, request->GetTotalSentBytes());
7326 EXPECT_LT(0, request->GetTotalReceivedBytes());
Fan Yang2330d182019-08-05 14:50:507327 EXPECT_EQ(
7328 static_cast<int>(expected_raw_header_response_size + push_promise_offset),
7329 request->raw_header_size());
Wez0e717112018-06-18 23:09:227330
7331 // Pump the message loop to allow all data to be consumed.
7332 base::RunLoop().RunUntilIdle();
7333
allada71b2efb2016-09-09 04:57:487334 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7335 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7336}
7337
Ryan Sleevia9d6aa62019-07-26 13:32:187338TEST_P(QuicNetworkTransactionTest, HostInAllowlist) {
7339 session_params_.quic_host_allowlist.insert("mail.example.org");
Yixin Wang10f477ed2017-11-21 04:20:207340
7341 MockRead http_reads[] = {
7342 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7343 MockRead("hello world"),
7344 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7345 MockRead(ASYNC, OK)};
7346
Ryan Sleevib8d7ea02018-05-07 20:01:017347 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207348 socket_factory_.AddSocketDataProvider(&http_data);
7349 AddCertificate(&ssl_data_);
7350 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7351
Ryan Hamiltonabad59e2019-06-06 04:02:597352 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237353 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257354 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237355 mock_quic_data.AddWrite(SYNCHRONOUS,
7356 ConstructInitialSettingsPacket(packet_num++));
7357 }
Yixin Wang10f477ed2017-11-21 04:20:207358 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237359 SYNCHRONOUS,
7360 ConstructClientRequestHeadersPacket(
7361 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7362 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437363 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337364 ASYNC, ConstructServerResponseHeadersPacket(
7365 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7366 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437367 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:337368 mock_quic_data.AddRead(
7369 ASYNC, ConstructServerDataPacket(
7370 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177371 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:237372 mock_quic_data.AddWrite(SYNCHRONOUS,
7373 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:207374 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7375 mock_quic_data.AddRead(ASYNC, 0); // EOF
7376
7377 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7378
7379 AddHangingNonAlternateProtocolSocketData();
7380 CreateSession();
7381
7382 SendRequestAndExpectHttpResponse("hello world");
7383 SendRequestAndExpectQuicResponse("hello!");
7384}
7385
Ryan Sleevia9d6aa62019-07-26 13:32:187386TEST_P(QuicNetworkTransactionTest, HostNotInAllowlist) {
7387 session_params_.quic_host_allowlist.insert("mail.example.com");
Yixin Wang10f477ed2017-11-21 04:20:207388
7389 MockRead http_reads[] = {
7390 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
7391 MockRead("hello world"),
7392 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
7393 MockRead(ASYNC, OK)};
7394
Ryan Sleevib8d7ea02018-05-07 20:01:017395 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:207396 socket_factory_.AddSocketDataProvider(&http_data);
7397 AddCertificate(&ssl_data_);
7398 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7399 socket_factory_.AddSocketDataProvider(&http_data);
7400 AddCertificate(&ssl_data_);
7401 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7402
7403 AddHangingNonAlternateProtocolSocketData();
7404 CreateSession();
7405
7406 SendRequestAndExpectHttpResponse("hello world");
7407 SendRequestAndExpectHttpResponse("hello world");
7408}
7409
bnc359ed2a2016-04-29 20:43:457410class QuicNetworkTransactionWithDestinationTest
7411 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:017412 public ::testing::WithParamInterface<PoolingTestParams>,
Gabriel Charette694c3c332019-08-19 14:53:057413 public WithTaskEnvironment {
bnc359ed2a2016-04-29 20:43:457414 protected:
7415 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:557416 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:057417 client_headers_include_h2_stream_dependency_(
7418 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:567419 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:457420 destination_type_(GetParam().destination_type),
7421 cert_transparency_verifier_(new MultiLogCTVerifier()),
7422 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:597423 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:117424 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:457425 ssl_data_(ASYNC, OK) {}
7426
7427 void SetUp() override {
7428 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557429 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457430
mmenke6ddfbea2017-05-31 21:48:417431 HttpNetworkSession::Params session_params;
7432 session_params.enable_quic = true;
Victor Vasilieva1e66d72019-12-05 17:55:387433 context_.params()->allow_remote_alt_svc = true;
7434 context_.params()->supported_versions = supported_versions_;
7435 context_.params()->headers_include_h2_stream_dependency =
Yixin Wang079ad542018-01-11 04:06:057436 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:417437
7438 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:457439
Victor Vasiliev7752898d2019-11-14 21:30:227440 context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
bnc359ed2a2016-04-29 20:43:457441
7442 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:277443 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:417444 session_context.quic_crypto_client_stream_factory =
7445 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:457446
Victor Vasiliev7752898d2019-11-14 21:30:227447 session_context.quic_context = &context_;
mmenke6ddfbea2017-05-31 21:48:417448 session_context.client_socket_factory = &socket_factory_;
7449 session_context.host_resolver = &host_resolver_;
7450 session_context.cert_verifier = &cert_verifier_;
7451 session_context.transport_security_state = &transport_security_state_;
7452 session_context.cert_transparency_verifier =
7453 cert_transparency_verifier_.get();
7454 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
7455 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:457456 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:417457 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:597458 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:417459 session_context.http_auth_handler_factory = auth_handler_factory_.get();
7460 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:457461
mmenke6ddfbea2017-05-31 21:48:417462 session_.reset(new HttpNetworkSession(session_params, session_context));
Matt Menkeb566c392019-09-11 23:22:437463 session_->quic_stream_factory()
7464 ->set_is_quic_known_to_work_on_current_network(false);
bnc359ed2a2016-04-29 20:43:457465 }
7466
7467 void TearDown() override {
7468 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7469 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557470 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:457471 PlatformTest::TearDown();
7472 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:557473 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:407474 session_.reset();
bnc359ed2a2016-04-29 20:43:457475 }
7476
zhongyie537a002017-06-27 16:48:217477 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:457478 HostPortPair destination;
7479 switch (destination_type_) {
7480 case SAME_AS_FIRST:
7481 destination = HostPortPair(origin1_, 443);
7482 break;
7483 case SAME_AS_SECOND:
7484 destination = HostPortPair(origin2_, 443);
7485 break;
7486 case DIFFERENT:
7487 destination = HostPortPair(kDifferentHostname, 443);
7488 break;
7489 }
bnc3472afd2016-11-17 15:27:217490 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:457491 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:217492 http_server_properties_.SetQuicAlternativeService(
Matt Menke9aa86262019-08-21 15:52:077493 url::SchemeHostPort("https", origin, 443), NetworkIsolationKey(),
7494 alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:457495 }
7496
Ryan Hamilton8d9ee76e2018-05-29 23:52:527497 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237498 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527499 quic::QuicStreamId stream_id,
7500 bool should_include_version,
7501 quic::QuicStreamId parent_stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527502 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137503 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457504 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137505 spdy::SpdyHeaderBlock headers(
7506 maker->GetRequestHeaders("GET", "https", "/"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027507 return maker->MakeRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457508 packet_number, stream_id, should_include_version, true, priority,
Ryan Hamilton0d65a8c2019-06-07 00:46:027509 std::move(headers), parent_stream_id, nullptr);
bnc359ed2a2016-04-29 20:43:457510 }
7511
Ryan Hamilton8d9ee76e2018-05-29 23:52:527512 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237513 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527514 quic::QuicStreamId stream_id,
7515 bool should_include_version,
7516 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587517 return ConstructClientRequestHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:027518 packet_number, stream_id, should_include_version, 0, maker);
bnc359ed2a2016-04-29 20:43:457519 }
7520
Ryan Hamilton8d9ee76e2018-05-29 23:52:527521 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237522 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527523 quic::QuicStreamId stream_id,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527524 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137525 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
Ryan Hamilton0d65a8c2019-06-07 00:46:027526 return maker->MakeResponseHeadersPacket(packet_number, stream_id, false,
7527 false, std::move(headers), nullptr);
bnc359ed2a2016-04-29 20:43:457528 }
7529
Ryan Hamilton8d9ee76e2018-05-29 23:52:527530 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237531 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527532 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457533 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:437534 std::string header = "";
Nick Harper23290b82019-05-02 00:02:567535 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417536 std::unique_ptr<char[]> buffer;
Victor Vasiliev55d997922019-10-31 19:40:577537 auto header_length =
7538 quic::HttpEncoder::SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:437539 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:417540 }
Ryan Hamilton7505eb92019-06-08 00:22:177541 return maker->MakeDataPacket(packet_number, stream_id, false, true,
Renjief49758b2019-01-11 23:32:417542 header + "hello");
bnc359ed2a2016-04-29 20:43:457543 }
7544
Ryan Hamilton8d9ee76e2018-05-29 23:52:527545 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237546 uint64_t packet_number,
7547 uint64_t largest_received,
7548 uint64_t smallest_received,
7549 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457550 QuicTestPacketMaker* maker) {
7551 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497552 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457553 }
7554
Ryan Hamilton8d9ee76e2018-05-29 23:52:527555 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237556 uint64_t packet_number,
fayang3bcb8b502016-12-07 21:44:377557 QuicTestPacketMaker* maker) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027558 return maker->MakeInitialSettingsPacket(packet_number);
fayang3bcb8b502016-12-07 21:44:377559 }
7560
bnc359ed2a2016-04-29 20:43:457561 void AddRefusedSocketData() {
7562 std::unique_ptr<StaticSocketDataProvider> refused_data(
7563 new StaticSocketDataProvider());
7564 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7565 refused_data->set_connect_data(refused_connect);
7566 socket_factory_.AddSocketDataProvider(refused_data.get());
7567 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7568 }
7569
7570 void AddHangingSocketData() {
7571 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7572 new StaticSocketDataProvider());
7573 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7574 hanging_data->set_connect_data(hanging_connect);
7575 socket_factory_.AddSocketDataProvider(hanging_data.get());
7576 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7577 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7578 }
7579
7580 bool AllDataConsumed() {
7581 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7582 if (!socket_data_ptr->AllReadDataConsumed() ||
7583 !socket_data_ptr->AllWriteDataConsumed()) {
7584 return false;
7585 }
7586 }
7587 return true;
7588 }
7589
7590 void SendRequestAndExpectQuicResponse(const std::string& host) {
7591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7592 HttpRequestInfo request;
7593 std::string url("https://");
7594 url.append(host);
7595 request.url = GURL(url);
7596 request.load_flags = 0;
7597 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107598 request.traffic_annotation =
7599 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457600 TestCompletionCallback callback;
7601 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017602 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457603
7604 std::string response_data;
robpercival214763f2016-07-01 23:27:017605 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457606 EXPECT_EQ("hello", response_data);
7607
7608 const HttpResponseInfo* response = trans.GetResponseInfo();
7609 ASSERT_TRUE(response != nullptr);
7610 ASSERT_TRUE(response->headers.get() != nullptr);
7611 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7612 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527613 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper63da9422019-10-22 22:41:087614 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457615 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377616 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457617 }
7618
Fan Yang32c5a112018-12-10 20:06:337619 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567620 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7621 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367622 }
7623
Nick Harper23290b82019-05-02 00:02:567624 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057625 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567626 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457627 DestinationType destination_type_;
7628 std::string origin1_;
7629 std::string origin2_;
Victor Vasiliev7752898d2019-11-14 21:30:227630 MockQuicContext context_;
bnc359ed2a2016-04-29 20:43:457631 std::unique_ptr<HttpNetworkSession> session_;
7632 MockClientSocketFactory socket_factory_;
7633 MockHostResolver host_resolver_;
7634 MockCertVerifier cert_verifier_;
7635 TransportSecurityState transport_security_state_;
7636 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237637 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457638 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077639 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597640 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457641 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:267642 HttpServerProperties http_server_properties_;
Matt Muellerd9342e3a2019-11-26 01:41:147643 RecordingBoundTestNetLog net_log_;
bnc359ed2a2016-04-29 20:43:457644 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7645 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7646 static_socket_data_provider_vector_;
7647 SSLSocketDataProvider ssl_data_;
7648};
7649
Victor Costane635086f2019-01-27 05:20:307650INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7651 QuicNetworkTransactionWithDestinationTest,
David Schinazi09e9a6012019-10-03 17:37:577652 ::testing::ValuesIn(GetPoolingTestParams()),
7653 ::testing::PrintToStringParamName());
bnc359ed2a2016-04-29 20:43:457654
7655// A single QUIC request fails because the certificate does not match the origin
7656// hostname, regardless of whether it matches the alternative service hostname.
7657TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7658 if (destination_type_ == DIFFERENT)
7659 return;
7660
7661 GURL url("https://mail.example.com/");
7662 origin1_ = url.host();
7663
7664 // Not used for requests, but this provides a test case where the certificate
7665 // is valid for the hostname of the alternative service.
7666 origin2_ = "mail.example.org";
7667
zhongyie537a002017-06-27 16:48:217668 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457669
7670 scoped_refptr<X509Certificate> cert(
7671 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247672 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7673 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457674
7675 ProofVerifyDetailsChromium verify_details;
7676 verify_details.cert_verify_result.verified_cert = cert;
7677 verify_details.cert_verify_result.is_issued_by_known_root = true;
7678 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7679
Ryan Hamiltonabad59e2019-06-06 04:02:597680 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457681 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7682 mock_quic_data.AddRead(ASYNC, 0);
7683
7684 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7685
7686 AddRefusedSocketData();
7687
7688 HttpRequestInfo request;
7689 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107690 request.traffic_annotation =
7691 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457692
7693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7694 TestCompletionCallback callback;
7695 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017696 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457697
7698 EXPECT_TRUE(AllDataConsumed());
7699}
7700
7701// First request opens QUIC session to alternative service. Second request
7702// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527703// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457704TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7705 origin1_ = "mail.example.org";
7706 origin2_ = "news.example.org";
7707
zhongyie537a002017-06-27 16:48:217708 SetQuicAlternativeService(origin1_);
7709 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457710
7711 scoped_refptr<X509Certificate> cert(
7712 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247713 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7714 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7715 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457716
7717 ProofVerifyDetailsChromium verify_details;
7718 verify_details.cert_verify_result.verified_cert = cert;
7719 verify_details.cert_verify_result.is_issued_by_known_root = true;
7720 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7721
Yixin Wang079ad542018-01-11 04:06:057722 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227723 version_,
7724 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7725 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057726 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177727 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:227728 version_,
7729 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7730 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457731
Ryan Hamiltonabad59e2019-06-06 04:02:597732 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:237733 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257734 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237735 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7736 packet_num++, &client_maker));
7737 }
Fan Yang32c5a112018-12-10 20:06:337738 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237739 SYNCHRONOUS,
7740 ConstructClientRequestHeadersPacket(
7741 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7742 &client_maker));
Ryan Hamilton0d65a8c2019-06-07 00:46:027743 mock_quic_data.AddRead(
7744 ASYNC,
7745 ConstructServerResponseHeadersPacket(
7746 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437747 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337748 ASYNC,
7749 ConstructServerDataPacket(
7750 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237751 mock_quic_data.AddWrite(
7752 SYNCHRONOUS,
7753 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457754
Yixin Wang079ad542018-01-11 04:06:057755 client_maker.set_hostname(origin2_);
7756 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457757
Zhongyi Shi32f2fd02018-04-16 18:23:437758 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:027759 SYNCHRONOUS,
7760 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:237761 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027762 GetNthClientInitiatedBidirectionalStreamId(0), &client_maker));
7763 mock_quic_data.AddRead(
7764 ASYNC,
7765 ConstructServerResponseHeadersPacket(
7766 3, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437767 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337768 ASYNC,
7769 ConstructServerDataPacket(
7770 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Renjie Tangaadb84b2019-08-31 01:00:237771 mock_quic_data.AddWrite(
7772 SYNCHRONOUS,
7773 ConstructClientAckPacket(packet_num++, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457774 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7775 mock_quic_data.AddRead(ASYNC, 0); // EOF
7776
7777 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7778
7779 AddHangingSocketData();
7780 AddHangingSocketData();
7781
Victor Vasiliev7752898d2019-11-14 21:30:227782 scoped_refptr<TestTaskRunner> quic_task_runner(
7783 new TestTaskRunner(context_.mock_clock()));
Fan Yangc9e00dc2018-10-09 14:17:567784 QuicStreamFactoryPeer::SetAlarmFactory(
7785 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097786 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Victor Vasiliev7752898d2019-11-14 21:30:227787 context_.clock()));
Fan Yangc9e00dc2018-10-09 14:17:567788
bnc359ed2a2016-04-29 20:43:457789 SendRequestAndExpectQuicResponse(origin1_);
7790 SendRequestAndExpectQuicResponse(origin2_);
7791
7792 EXPECT_TRUE(AllDataConsumed());
7793}
7794
7795// First request opens QUIC session to alternative service. Second request does
7796// not pool to it, even though destination matches, because certificate is not
7797// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527798// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457799TEST_P(QuicNetworkTransactionWithDestinationTest,
7800 DoNotPoolIfCertificateInvalid) {
7801 origin1_ = "news.example.org";
7802 origin2_ = "mail.example.com";
7803
zhongyie537a002017-06-27 16:48:217804 SetQuicAlternativeService(origin1_);
7805 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457806
7807 scoped_refptr<X509Certificate> cert1(
7808 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247809 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7810 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7811 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457812
7813 scoped_refptr<X509Certificate> cert2(
7814 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247815 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7816 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457817
7818 ProofVerifyDetailsChromium verify_details1;
7819 verify_details1.cert_verify_result.verified_cert = cert1;
7820 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7821 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7822
7823 ProofVerifyDetailsChromium verify_details2;
7824 verify_details2.cert_verify_result.verified_cert = cert2;
7825 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7826 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7827
Yixin Wang079ad542018-01-11 04:06:057828 QuicTestPacketMaker client_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227829 version_,
7830 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7831 context_.clock(), origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057832 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177833 QuicTestPacketMaker server_maker1(
Victor Vasiliev7752898d2019-11-14 21:30:227834 version_,
7835 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7836 context_.clock(), origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457837
Ryan Hamiltonabad59e2019-06-06 04:02:597838 MockQuicData mock_quic_data1(version_);
Renjie Tangaadb84b2019-08-31 01:00:237839 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:257840 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237841 mock_quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7842 packet_num++, &client_maker1));
7843 }
Fan Yang32c5a112018-12-10 20:06:337844 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237845 SYNCHRONOUS,
7846 ConstructClientRequestHeadersPacket(
7847 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7848 &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437849 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337850 ASYNC,
7851 ConstructServerResponseHeadersPacket(
7852 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437853 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337854 ASYNC,
7855 ConstructServerDataPacket(
7856 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437857 mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237858 SYNCHRONOUS,
7859 ConstructClientAckPacket(packet_num++, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457860 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7861 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7862
7863 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7864
Yixin Wang079ad542018-01-11 04:06:057865 QuicTestPacketMaker client_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227866 version_,
7867 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7868 context_.clock(), origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057869 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177870 QuicTestPacketMaker server_maker2(
Victor Vasiliev7752898d2019-11-14 21:30:227871 version_,
7872 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
7873 context_.clock(), origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457874
Ryan Hamiltonabad59e2019-06-06 04:02:597875 MockQuicData mock_quic_data2(version_);
Renjie Tangaadb84b2019-08-31 01:00:237876 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:257877 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237878 mock_quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7879 packet_num2++, &client_maker2));
7880 }
Fan Yang32c5a112018-12-10 20:06:337881 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237882 SYNCHRONOUS,
7883 ConstructClientRequestHeadersPacket(
7884 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0), true,
7885 &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437886 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337887 ASYNC,
7888 ConstructServerResponseHeadersPacket(
7889 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437890 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337891 ASYNC,
7892 ConstructServerDataPacket(
7893 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437894 mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:237895 SYNCHRONOUS,
7896 ConstructClientAckPacket(packet_num2++, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457897 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7898 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7899
7900 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7901
bnc359ed2a2016-04-29 20:43:457902 SendRequestAndExpectQuicResponse(origin1_);
7903 SendRequestAndExpectQuicResponse(origin2_);
7904
7905 EXPECT_TRUE(AllDataConsumed());
7906}
7907
ckrasicdee37572017-04-06 22:42:277908// crbug.com/705109 - this confirms that matching request with a body
7909// triggers a crash (pre-fix).
7910TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
Ryan Hamilton6c6493102019-12-05 21:36:507911 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
7912 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
Victor Vasilieva1e66d72019-12-05 17:55:387913 context_.params()->origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277914 HostPortPair::FromString("mail.example.org:443"));
7915
Ryan Hamiltonabad59e2019-06-06 04:02:597916 MockQuicData mock_quic_data(version_);
Fan Yangac867502019-01-28 21:10:237917 uint64_t client_packet_number = 1;
Victor Vasiliev7da08172019-10-14 06:04:257918 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:237919 mock_quic_data.AddWrite(
7920 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++));
7921 }
Zhongyi Shi32f2fd02018-04-16 18:23:437922 mock_quic_data.AddWrite(
7923 SYNCHRONOUS,
7924 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337925 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:027926 true, true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:437927 mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:027928 ASYNC,
7929 ConstructServerPushPromisePacket(
7930 1, GetNthClientInitiatedBidirectionalStreamId(0),
7931 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7932 GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_maker_));
Renjie Tang703fea92019-07-23 21:08:317933
7934 if ((client_headers_include_h2_stream_dependency_ &&
Renjie Tang33f43ce2019-09-23 22:11:427935 version_.transport_version >= quic::QUIC_VERSION_43 &&
Ian Swett25d3c3b32020-01-14 17:51:297936 !VersionUsesHttp3(version_.transport_version))) {
Ryan Hamilton0d65a8c2019-06-07 00:46:027937 mock_quic_data.AddWrite(
7938 SYNCHRONOUS,
7939 ConstructClientPriorityPacket(
7940 client_packet_number++, false,
7941 GetNthServerInitiatedUnidirectionalStreamId(0),
7942 GetNthClientInitiatedBidirectionalStreamId(0), DEFAULT_PRIORITY));
Yixin Wangb470bc882018-02-15 18:43:577943 }
Zhongyi Shi32f2fd02018-04-16 18:23:437944 mock_quic_data.AddRead(
7945 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337946 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027947 GetResponseHeaders("200 OK")));
Yixin Wangb470bc882018-02-15 18:43:577948 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437949 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7950 mock_quic_data.AddRead(
7951 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337952 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:027953 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:437954 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437955 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337956 ASYNC, ConstructServerDataPacket(
7957 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177958 header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577959 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437960 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417961
Victor Vasiliev076657c2019-03-12 02:46:437962 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437963 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337964 ASYNC, ConstructServerDataPacket(
7965 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:177966 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277967
7968 // Because the matching request has a body, we will see the push
7969 // stream get cancelled, and the matching request go out on the
7970 // wire.
Fan Yang32c5a112018-12-10 20:06:337971 mock_quic_data.AddWrite(SYNCHRONOUS,
7972 ConstructClientAckAndRstPacket(
7973 client_packet_number++,
7974 GetNthServerInitiatedUnidirectionalStreamId(0),
7975 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277976 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437977 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567978 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417979 mock_quic_data.AddWrite(
7980 SYNCHRONOUS,
7981 ConstructClientRequestHeadersAndDataFramesPacket(
7982 client_packet_number++,
7983 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7984 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027985 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr, {kBody}));
Renjief49758b2019-01-11 23:32:417986 } else {
7987 mock_quic_data.AddWrite(
7988 SYNCHRONOUS,
7989 ConstructClientRequestHeadersAndDataFramesPacket(
7990 client_packet_number++,
7991 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7992 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
Ryan Hamilton0d65a8c2019-06-07 00:46:027993 GetNthServerInitiatedUnidirectionalStreamId(0), nullptr,
7994 {header3, kBody}));
Renjief49758b2019-01-11 23:32:417995 }
ckrasicdee37572017-04-06 22:42:277996
7997 // We see the same response as for the earlier pushed and cancelled
7998 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437999 mock_quic_data.AddRead(
8000 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338001 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028002 GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:438003 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338004 ASYNC, ConstructServerDataPacket(
8005 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:178006 header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:278007
Yixin Wangb470bc882018-02-15 18:43:578008 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438009 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:278010 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8011 mock_quic_data.AddRead(ASYNC, 0); // EOF
8012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8013
8014 // The non-alternate protocol job needs to hang in order to guarantee that
8015 // the alternate-protocol job will "win".
8016 AddHangingNonAlternateProtocolSocketData();
8017
8018 CreateSession();
8019
8020 // PUSH_PROMISE handling in the http layer gets exercised here.
8021 SendRequestAndExpectQuicResponse("hello!");
8022
8023 request_.url = GURL("https://mail.example.org/pushed.jpg");
8024 ChunkedUploadDataStream upload_data(0);
8025 upload_data.AppendData("1", 1, true);
8026 request_.upload_data_stream = &upload_data;
8027 SendRequestAndExpectQuicResponse("and hello!");
8028}
8029
Bence Béky7538a952018-02-01 16:59:528030// Regression test for https://crbug.com/797825: If pushed headers describe a
8031// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
8032// not be called (otherwise a DCHECK fails).
8033TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton6c6493102019-12-05 21:36:508034 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
8035 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
8036
Ryan Hamilton0239aac2018-05-19 00:03:138037 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:528038 pushed_request_headers[":authority"] = "";
8039 pushed_request_headers[":method"] = "GET";
8040 pushed_request_headers[":path"] = "/";
8041 pushed_request_headers[":scheme"] = "nosuchscheme";
8042
Victor Vasilieva1e66d72019-12-05 17:55:388043 context_.params()->origins_to_force_quic_on.insert(
Bence Béky7538a952018-02-01 16:59:528044 HostPortPair::FromString("mail.example.org:443"));
8045
Ryan Hamiltonabad59e2019-06-06 04:02:598046 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:528047
Renjie Tangaadb84b2019-08-31 01:00:238048 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258049 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238050 mock_quic_data.AddWrite(SYNCHRONOUS,
8051 ConstructInitialSettingsPacket(packet_num++));
8052 }
Bence Béky7538a952018-02-01 16:59:528053 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238054 SYNCHRONOUS,
8055 ConstructClientRequestHeadersPacket(
8056 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8057 true, GetRequestHeaders("GET", "https", "/")));
Bence Béky7538a952018-02-01 16:59:528058
Fan Yang32c5a112018-12-10 20:06:338059 mock_quic_data.AddRead(
8060 ASYNC, ConstructServerPushPromisePacket(
8061 1, GetNthClientInitiatedBidirectionalStreamId(0),
8062 GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028063 std::move(pushed_request_headers), &server_maker_));
Renjie Tangaadb84b2019-08-31 01:00:238064 mock_quic_data.AddWrite(
8065 SYNCHRONOUS,
8066 ConstructClientRstPacket(packet_num++,
8067 GetNthServerInitiatedUnidirectionalStreamId(0),
8068 quic::QUIC_INVALID_PROMISE_URL));
Bence Béky7538a952018-02-01 16:59:528069
Zhongyi Shi32f2fd02018-04-16 18:23:438070 mock_quic_data.AddRead(
8071 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338072 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028073 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:238074 mock_quic_data.AddWrite(SYNCHRONOUS,
8075 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:528076
Zhongyi Shi32f2fd02018-04-16 18:23:438077 mock_quic_data.AddRead(
8078 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338079 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028080 false, GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:438081 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:438082 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338083 ASYNC, ConstructServerDataPacket(
8084 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Ryan Hamilton7505eb92019-06-08 00:22:178085 header + "hello!"));
Renjie Tangaadb84b2019-08-31 01:00:238086 mock_quic_data.AddWrite(SYNCHRONOUS,
8087 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:528088
8089 mock_quic_data.AddRead(ASYNC, 0);
8090 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8091
8092 // The non-alternate protocol job needs to hang in order to guarantee that
8093 // the alternate-protocol job will "win".
8094 AddHangingNonAlternateProtocolSocketData();
8095
8096 CreateSession();
8097
8098 // PUSH_PROMISE handling in the http layer gets exercised here.
8099 SendRequestAndExpectQuicResponse("hello!");
8100
8101 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8102 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8103}
8104
Yixin Wang46a273ec302018-01-23 17:59:568105// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148106TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:568107 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148108 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568109 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498110 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568111
Ryan Hamiltonabad59e2019-06-06 04:02:598112 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238113 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258114 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238115 mock_quic_data.AddWrite(SYNCHRONOUS,
8116 ConstructInitialSettingsPacket(packet_num++));
8117 }
Fan Yang32c5a112018-12-10 20:06:338118 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238119 SYNCHRONOUS,
8120 ConstructClientRequestHeadersPacket(
8121 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8122 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8123 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338124 mock_quic_data.AddRead(
8125 ASYNC, ConstructServerResponseHeadersPacket(
8126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8127 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568128
8129 const char get_request[] =
8130 "GET / HTTP/1.1\r\n"
8131 "Host: mail.example.org\r\n"
8132 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438133 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568134 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418135 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358136 SYNCHRONOUS,
8137 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238138 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098139 1, 1, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418140 } else {
8141 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418142 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288143 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238144 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288145 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418146 }
8147
Yixin Wang46a273ec302018-01-23 17:59:568148 const char get_response[] =
8149 "HTTP/1.1 200 OK\r\n"
8150 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438151 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438152 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338153 ASYNC, ConstructServerDataPacket(
8154 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178155 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438156 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338157 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418158 SYNCHRONOUS, ConstructServerDataPacket(
8159 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178160 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238161 mock_quic_data.AddWrite(SYNCHRONOUS,
8162 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568163 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8164
Bence Béky6e243aa2019-12-13 19:01:078165 if (VersionUsesHttp3(version_.transport_version)) {
8166 mock_quic_data.AddWrite(
8167 SYNCHRONOUS, ConstructClientDataPacket(
8168 packet_num++, GetQpackDecoderStreamId(), true, false,
8169 StreamCancellationQpackDecoderInstruction(0)));
8170 }
8171
Yixin Wang46a273ec302018-01-23 17:59:568172 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418173 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238174 ConstructClientRstPacket(packet_num++,
8175 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418176 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568177
8178 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8179
8180 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8181
8182 CreateSession();
8183
8184 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:098185 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:568186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8187 HeadersHandler headers_handler;
8188 trans.SetBeforeHeadersSentCallback(
8189 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8190 base::Unretained(&headers_handler)));
8191 RunTransaction(&trans);
8192 CheckWasHttpResponse(&trans);
8193 CheckResponsePort(&trans, 70);
8194 CheckResponseData(&trans, "0123456789");
8195 EXPECT_TRUE(headers_handler.was_proxied());
8196 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8197
8198 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8199 // proxy socket to disconnect.
8200 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8201
8202 base::RunLoop().RunUntilIdle();
8203 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8204 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8205}
8206
8207// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148208TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:568209 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148210 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568211 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498212 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568213
Ryan Hamiltonabad59e2019-06-06 04:02:598214 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238215 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258216 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238217 mock_quic_data.AddWrite(SYNCHRONOUS,
8218 ConstructInitialSettingsPacket(packet_num++));
8219 }
Fan Yang32c5a112018-12-10 20:06:338220 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238221 SYNCHRONOUS,
8222 ConstructClientRequestHeadersPacket(
8223 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8224 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8225 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338226 mock_quic_data.AddRead(
8227 ASYNC, ConstructServerResponseHeadersPacket(
8228 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8229 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568230
8231 SpdyTestUtil spdy_util;
8232
Ryan Hamilton0239aac2018-05-19 00:03:138233 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568234 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438235 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568236 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418237 mock_quic_data.AddWrite(
8238 SYNCHRONOUS,
8239 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238240 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8241 1, 1, 1, false,
Zhongyi Shid1c00fc42019-12-14 06:05:098242 quiche::QuicheStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418243 } else {
8244 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418245 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288246 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238247 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
8248 1, 1, 1, false,
Renjie Tangd5133972019-12-06 00:20:288249 {header + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418250 }
Ryan Hamilton0239aac2018-05-19 00:03:138251 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568252 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438253 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438254 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178255 ASYNC, ConstructServerDataPacket(
8256 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8257 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568258
Ryan Hamilton0239aac2018-05-19 00:03:138259 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198260 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:438261 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438262 mock_quic_data.AddRead(
8263 SYNCHRONOUS,
8264 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:338265 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438266 header3 + std::string(data_frame.data(), data_frame.size())));
Renjie Tangaadb84b2019-08-31 01:00:238267 mock_quic_data.AddWrite(SYNCHRONOUS,
8268 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568269 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8270
Bence Béky6e243aa2019-12-13 19:01:078271 if (VersionUsesHttp3(version_.transport_version)) {
8272 mock_quic_data.AddWrite(
8273 SYNCHRONOUS, ConstructClientDataPacket(
8274 packet_num++, GetQpackDecoderStreamId(), true, false,
8275 StreamCancellationQpackDecoderInstruction(0)));
8276 }
8277
Yixin Wang46a273ec302018-01-23 17:59:568278 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438279 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238280 ConstructClientRstPacket(packet_num++,
8281 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418282 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568283
8284 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8285
8286 SSLSocketDataProvider ssl_data(ASYNC, OK);
8287 ssl_data.next_proto = kProtoHTTP2;
8288 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8289
8290 CreateSession();
8291
8292 request_.url = GURL("https://mail.example.org/");
8293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8294 HeadersHandler headers_handler;
8295 trans.SetBeforeHeadersSentCallback(
8296 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8297 base::Unretained(&headers_handler)));
8298 RunTransaction(&trans);
8299 CheckWasSpdyResponse(&trans);
8300 CheckResponsePort(&trans, 70);
8301 CheckResponseData(&trans, "0123456789");
8302 EXPECT_TRUE(headers_handler.was_proxied());
8303 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8304
Wez0e717112018-06-18 23:09:228305 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
8306 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:568307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8308
8309 base::RunLoop().RunUntilIdle();
8310 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8311 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8312}
8313
8314// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
8315// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148316TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:568317 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148318 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568319 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498320 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568321
Ryan Hamiltonabad59e2019-06-06 04:02:598322 MockQuicData mock_quic_data(version_);
Renjief49758b2019-01-11 23:32:418323 int write_packet_index = 1;
Victor Vasiliev7da08172019-10-14 06:04:258324 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238325 mock_quic_data.AddWrite(
8326 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++));
8327 }
Fan Yang32c5a112018-12-10 20:06:338328 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418329 SYNCHRONOUS,
8330 ConstructClientRequestHeadersPacket(
8331 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:048332 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
Ryan Hamilton0d65a8c2019-06-07 00:46:028333 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338334 mock_quic_data.AddRead(
8335 ASYNC, ConstructServerResponseHeadersPacket(
8336 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8337 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568338
Ryan Hamilton8d9ee76e2018-05-29 23:52:528339 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568340 const char get_request_1[] =
8341 "GET / HTTP/1.1\r\n"
8342 "Host: mail.example.org\r\n"
8343 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438344 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:568345 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418346 mock_quic_data.AddWrite(
Ryan Hamilton7505eb92019-06-08 00:22:178347 SYNCHRONOUS, ConstructClientAckAndDataPacket(
8348 write_packet_index++, false,
8349 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Zhongyi Shid1c00fc42019-12-14 06:05:098350 false, quiche::QuicheStringPiece(get_request_1)));
Renjief49758b2019-01-11 23:32:418351 } else {
8352 mock_quic_data.AddWrite(
Renjie Tangd5133972019-12-06 00:20:288353 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Ryan Hamilton7505eb92019-06-08 00:22:178354 write_packet_index++, false,
8355 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Renjie Tangd5133972019-12-06 00:20:288356 false, {header + std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:418357 }
8358
Yixin Wang46a273ec302018-01-23 17:59:568359 const char get_response_1[] =
8360 "HTTP/1.1 200 OK\r\n"
8361 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438362 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:438363 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438364 ASYNC, ConstructServerDataPacket(
8365 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178366 header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:418367 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:568368
Victor Vasiliev076657c2019-03-12 02:46:438369 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338370 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178371 SYNCHRONOUS, ConstructServerDataPacket(
8372 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8373 false, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:418374 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:568375
Renjief49758b2019-01-11 23:32:418376 mock_quic_data.AddWrite(
8377 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568378
8379 const char get_request_2[] =
8380 "GET /2 HTTP/1.1\r\n"
8381 "Host: mail.example.org\r\n"
8382 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438383 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:568384 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418385 mock_quic_data.AddWrite(
8386 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288387 ConstructClientDataPacket(
Renjied172e812019-01-16 05:12:358388 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288389 false, false, {header4 + std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:358390 } else {
8391 mock_quic_data.AddWrite(
8392 SYNCHRONOUS,
Ryan Hamilton7505eb92019-06-08 00:22:178393 ConstructClientDataPacket(
8394 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098395 false, false, quiche::QuicheStringPiece(get_request_2)));
Renjief49758b2019-01-11 23:32:418396 }
Yixin Wang46a273ec302018-01-23 17:59:568397
8398 const char get_response_2[] =
8399 "HTTP/1.1 200 OK\r\n"
8400 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438401 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:438402 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438403 ASYNC, ConstructServerDataPacket(
8404 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178405 header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:418406 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:568407
Victor Vasiliev076657c2019-03-12 02:46:438408 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528409 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178410 SYNCHRONOUS, ConstructServerDataPacket(
8411 5, GetNthClientInitiatedBidirectionalStreamId(0), false,
8412 false, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:418413 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:568414
Renjief49758b2019-01-11 23:32:418415 mock_quic_data.AddWrite(
8416 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:568417 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8418
Bence Béky6e243aa2019-12-13 19:01:078419 if (VersionUsesHttp3(version_.transport_version)) {
8420 mock_quic_data.AddWrite(
8421 SYNCHRONOUS, ConstructClientDataPacket(
8422 write_packet_index++, GetQpackDecoderStreamId(), true,
8423 false, StreamCancellationQpackDecoderInstruction(0)));
8424 }
8425
Renjief49758b2019-01-11 23:32:418426 mock_quic_data.AddWrite(
8427 SYNCHRONOUS,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418428 ConstructClientRstPacket(write_packet_index++,
8429 GetNthClientInitiatedBidirectionalStreamId(0),
8430 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568431
8432 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8433
8434 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8435
8436 CreateSession();
8437
8438 request_.url = GURL("https://mail.example.org/");
8439 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8440 HeadersHandler headers_handler_1;
8441 trans_1.SetBeforeHeadersSentCallback(
8442 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8443 base::Unretained(&headers_handler_1)));
8444 RunTransaction(&trans_1);
8445 CheckWasHttpResponse(&trans_1);
8446 CheckResponsePort(&trans_1, 70);
8447 CheckResponseData(&trans_1, "0123456789");
8448 EXPECT_TRUE(headers_handler_1.was_proxied());
8449 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8450
8451 request_.url = GURL("https://mail.example.org/2");
8452 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8453 HeadersHandler headers_handler_2;
8454 trans_2.SetBeforeHeadersSentCallback(
8455 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8456 base::Unretained(&headers_handler_2)));
8457 RunTransaction(&trans_2);
8458 CheckWasHttpResponse(&trans_2);
8459 CheckResponsePort(&trans_2, 70);
8460 CheckResponseData(&trans_2, "0123456");
8461 EXPECT_TRUE(headers_handler_2.was_proxied());
8462 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8463
8464 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8465 // proxy socket to disconnect.
8466 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8467
8468 base::RunLoop().RunUntilIdle();
8469 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8470 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8471}
8472
8473// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
8474// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
8475// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:148476TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:568477 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148478 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568479 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498480 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568481
Ryan Hamiltonabad59e2019-06-06 04:02:598482 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238483 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258484 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238485 mock_quic_data.AddWrite(SYNCHRONOUS,
8486 ConstructInitialSettingsPacket(packet_num++));
8487 }
Yixin Wang46a273ec302018-01-23 17:59:568488
8489 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:338490 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238491 SYNCHRONOUS,
8492 ConstructClientRequestHeadersPacket(
8493 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8494 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8495 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438496 mock_quic_data.AddRead(
8497 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338498 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028499 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568500
8501 // GET request, response, and data over QUIC tunnel for first request
8502 const char get_request[] =
8503 "GET / HTTP/1.1\r\n"
8504 "Host: mail.example.org\r\n"
8505 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438506 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568507 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418508 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358509 SYNCHRONOUS,
8510 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238511 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Zhongyi Shid1c00fc42019-12-14 06:05:098512 1, 1, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418513 } else {
8514 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418515 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288516 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238517 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Renjie Tangd5133972019-12-06 00:20:288518 1, 1, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418519 }
8520
Yixin Wang46a273ec302018-01-23 17:59:568521 const char get_response[] =
8522 "HTTP/1.1 200 OK\r\n"
8523 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438524 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:568525 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338526 ASYNC, ConstructServerDataPacket(
8527 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178528 header2 + std::string(get_response)));
Victor Vasiliev076657c2019-03-12 02:46:438529 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338530 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418531 SYNCHRONOUS, ConstructServerDataPacket(
8532 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:178533 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238534 mock_quic_data.AddWrite(SYNCHRONOUS,
8535 ConstructClientAckPacket(packet_num++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568536
8537 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438538 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238539 SYNCHRONOUS,
8540 ConstructClientRequestHeadersPacket(
8541 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8542 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8543 ConnectRequestHeaders("different.example.org:443"),
8544 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438545 mock_quic_data.AddRead(
8546 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338547 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028548 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568549
8550 // GET request, response, and data over QUIC tunnel for second request
8551 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138552 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568553 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:438554 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:568555 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418556 mock_quic_data.AddWrite(
8557 SYNCHRONOUS,
8558 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238559 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8560 4, 4, 1, false,
Zhongyi Shid1c00fc42019-12-14 06:05:098561 quiche::QuicheStringPiece(get_frame.data(), get_frame.size())));
Renjief49758b2019-01-11 23:32:418562 } else {
8563 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418564 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288565 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238566 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
8567 4, 4, 1, false,
Renjie Tangd5133972019-12-06 00:20:288568 {header4 + std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418569 }
Yixin Wang46a273ec302018-01-23 17:59:568570
Ryan Hamilton0239aac2018-05-19 00:03:138571 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568572 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:438573 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438574 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:178575 ASYNC, ConstructServerDataPacket(
8576 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8577 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568578
Ryan Hamilton0239aac2018-05-19 00:03:138579 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198580 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:438581 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438582 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:438583 ASYNC, ConstructServerDataPacket(
8584 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438585 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568586
Renjie Tangaadb84b2019-08-31 01:00:238587 mock_quic_data.AddWrite(SYNCHRONOUS,
8588 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568589 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8590
Bence Béky6e243aa2019-12-13 19:01:078591 if (VersionUsesHttp3(version_.transport_version)) {
8592 mock_quic_data.AddWrite(
8593 SYNCHRONOUS, ConstructClientDataPacket(
8594 packet_num++, GetQpackDecoderStreamId(), true, false,
8595 StreamCancellationQpackDecoderInstruction(0)));
8596 }
8597
Yixin Wang46a273ec302018-01-23 17:59:568598 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418599 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238600 ConstructClientRstPacket(packet_num++,
8601 GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418602 quic::QUIC_STREAM_CANCELLED));
Bence Béky6e243aa2019-12-13 19:01:078603
8604 if (VersionUsesHttp3(version_.transport_version)) {
8605 mock_quic_data.AddWrite(
8606 SYNCHRONOUS, ConstructClientDataPacket(
8607 packet_num++, GetQpackDecoderStreamId(), true, false,
8608 StreamCancellationQpackDecoderInstruction(1)));
8609 }
8610
Yixin Wang46a273ec302018-01-23 17:59:568611 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438612 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238613 ConstructClientRstPacket(packet_num++,
8614 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418615 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568616
8617 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8618
8619 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8620
8621 SSLSocketDataProvider ssl_data(ASYNC, OK);
8622 ssl_data.next_proto = kProtoHTTP2;
8623 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8624
8625 CreateSession();
8626
8627 request_.url = GURL("https://mail.example.org/");
8628 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8629 HeadersHandler headers_handler_1;
8630 trans_1.SetBeforeHeadersSentCallback(
8631 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8632 base::Unretained(&headers_handler_1)));
8633 RunTransaction(&trans_1);
8634 CheckWasHttpResponse(&trans_1);
8635 CheckResponsePort(&trans_1, 70);
8636 CheckResponseData(&trans_1, "0123456789");
8637 EXPECT_TRUE(headers_handler_1.was_proxied());
8638 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8639
8640 request_.url = GURL("https://different.example.org/");
8641 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8642 HeadersHandler headers_handler_2;
8643 trans_2.SetBeforeHeadersSentCallback(
8644 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8645 base::Unretained(&headers_handler_2)));
8646 RunTransaction(&trans_2);
8647 CheckWasSpdyResponse(&trans_2);
8648 CheckResponsePort(&trans_2, 70);
8649 CheckResponseData(&trans_2, "0123456");
8650 EXPECT_TRUE(headers_handler_2.was_proxied());
8651 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8652
8653 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8654 // proxy socket to disconnect.
8655 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8656
8657 base::RunLoop().RunUntilIdle();
8658 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8659 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8660}
8661
8662// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148663TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568664 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148665 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568666 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498667 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568668
Ryan Hamiltonabad59e2019-06-06 04:02:598669 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238670 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258671 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238672 mock_quic_data.AddWrite(SYNCHRONOUS,
8673 ConstructInitialSettingsPacket(packet_num++));
8674 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:528675 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238676 SYNCHRONOUS,
8677 ConstructClientRequestHeadersPacket(
8678 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8679 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8680 ConnectRequestHeaders("mail.example.org:443"), 0));
Fan Yang32c5a112018-12-10 20:06:338681 mock_quic_data.AddRead(
8682 ASYNC, ConstructServerResponseHeadersPacket(
8683 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8684 GetResponseHeaders("500")));
8685 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjie Tangaadb84b2019-08-31 01:00:238686 mock_quic_data.AddWrite(
8687 SYNCHRONOUS,
8688 ConstructClientAckAndRstPacket(
8689 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8690 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568691
8692 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8693
8694 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8695
8696 CreateSession();
8697
8698 request_.url = GURL("https://mail.example.org/");
8699 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8700 HeadersHandler headers_handler;
8701 trans.SetBeforeHeadersSentCallback(
8702 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8703 base::Unretained(&headers_handler)));
8704 TestCompletionCallback callback;
8705 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8706 EXPECT_EQ(ERR_IO_PENDING, rv);
8707 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8708 EXPECT_EQ(false, headers_handler.was_proxied());
8709
8710 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8711 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8712}
8713
8714// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148715TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568716 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148717 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568718 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498719 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568720
Ryan Hamiltonabad59e2019-06-06 04:02:598721 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238722 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258723 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238724 mock_quic_data.AddWrite(SYNCHRONOUS,
8725 ConstructInitialSettingsPacket(packet_num++));
8726 }
Fan Yang32c5a112018-12-10 20:06:338727 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238728 SYNCHRONOUS,
8729 ConstructClientRequestHeadersPacket(
8730 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8731 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8732 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang46a273ec302018-01-23 17:59:568733 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8734
8735 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8736
8737 CreateSession();
8738
8739 request_.url = GURL("https://mail.example.org/");
8740 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8741 HeadersHandler headers_handler;
8742 trans.SetBeforeHeadersSentCallback(
8743 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8744 base::Unretained(&headers_handler)));
8745 TestCompletionCallback callback;
8746 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8747 EXPECT_EQ(ERR_IO_PENDING, rv);
8748 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8749
8750 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8751 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8752}
8753
8754// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8755// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148756TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568757 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148758 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568759 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498760 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568761
Ryan Hamiltonabad59e2019-06-06 04:02:598762 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238763 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258764 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238765 mock_quic_data.AddWrite(SYNCHRONOUS,
8766 ConstructInitialSettingsPacket(packet_num++));
8767 }
Fan Yang32c5a112018-12-10 20:06:338768 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238769 SYNCHRONOUS,
8770 ConstructClientRequestHeadersPacket(
8771 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8772 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8773 ConnectRequestHeaders("mail.example.org:443"), 0));
Zhongyi Shi32f2fd02018-04-16 18:23:438774 mock_quic_data.AddRead(
8775 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338776 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028777 GetResponseHeaders("200 OK")));
Bence Béky6e243aa2019-12-13 19:01:078778 if (VersionUsesHttp3(version_.transport_version)) {
8779 mock_quic_data.AddWrite(
8780 SYNCHRONOUS,
8781 ConstructClientAckAndDataPacket(
8782 packet_num++, false, GetQpackDecoderStreamId(), 1, 1, 1, false,
8783 StreamCancellationQpackDecoderInstruction(0)));
8784 mock_quic_data.AddWrite(
8785 SYNCHRONOUS,
8786 ConstructClientRstPacket(packet_num++,
8787 GetNthClientInitiatedBidirectionalStreamId(0),
8788 quic::QUIC_STREAM_CANCELLED));
8789 } else {
8790 mock_quic_data.AddWrite(
8791 SYNCHRONOUS,
8792 ConstructClientAckAndRstPacket(
8793 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0),
8794 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
8795 }
Yixin Wang46a273ec302018-01-23 17:59:568796
Zhongyi Shi32f2fd02018-04-16 18:23:438797 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238798 SYNCHRONOUS,
8799 ConstructClientRequestHeadersPacket(
8800 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
8801 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8802 ConnectRequestHeaders("mail.example.org:443"),
8803 GetNthClientInitiatedBidirectionalStreamId(0)));
Zhongyi Shi32f2fd02018-04-16 18:23:438804 mock_quic_data.AddRead(
8805 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338806 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton0d65a8c2019-06-07 00:46:028807 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:568808
8809 const char get_request[] =
8810 "GET / HTTP/1.1\r\n"
8811 "Host: mail.example.org\r\n"
8812 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438813 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568814 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418815 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358816 SYNCHRONOUS,
8817 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238818 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Zhongyi Shid1c00fc42019-12-14 06:05:098819 2, 2, 1, false, quiche::QuicheStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418820 } else {
8821 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418822 SYNCHRONOUS,
Renjie Tangd5133972019-12-06 00:20:288823 ConstructClientAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:238824 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(1),
Renjie Tangd5133972019-12-06 00:20:288825 2, 2, 1, false, {header + std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418826 }
Yixin Wang46a273ec302018-01-23 17:59:568827 const char get_response[] =
8828 "HTTP/1.1 200 OK\r\n"
8829 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438830 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438831 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338832 ASYNC, ConstructServerDataPacket(
8833 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Ryan Hamilton7505eb92019-06-08 00:22:178834 header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528835
Victor Vasiliev076657c2019-03-12 02:46:438836 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338837 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418838 SYNCHRONOUS, ConstructServerDataPacket(
8839 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:178840 false, header3 + std::string("0123456789")));
Renjie Tangaadb84b2019-08-31 01:00:238841 mock_quic_data.AddWrite(SYNCHRONOUS,
8842 ConstructClientAckPacket(packet_num++, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568843 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8844
Bence Béky6e243aa2019-12-13 19:01:078845 if (VersionUsesHttp3(version_.transport_version)) {
8846 mock_quic_data.AddWrite(
8847 SYNCHRONOUS, ConstructClientDataPacket(
8848 packet_num++, GetQpackDecoderStreamId(), true, false,
8849 StreamCancellationQpackDecoderInstruction(1)));
8850 }
Yixin Wang46a273ec302018-01-23 17:59:568851 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418852 SYNCHRONOUS,
Renjie Tangaadb84b2019-08-31 01:00:238853 ConstructClientRstPacket(packet_num++,
8854 GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:418855 quic::QUIC_STREAM_CANCELLED));
Yixin Wang46a273ec302018-01-23 17:59:568856
8857 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8858
8859 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8860 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8861
8862 SSLSocketDataProvider ssl_data(ASYNC, OK);
8863 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8864
8865 CreateSession();
8866
8867 request_.url = GURL("https://mail.example.org/");
8868 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8869 HeadersHandler headers_handler;
8870 trans.SetBeforeHeadersSentCallback(
8871 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8872 base::Unretained(&headers_handler)));
8873 TestCompletionCallback callback;
8874 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8875 EXPECT_EQ(ERR_IO_PENDING, rv);
8876 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8877
8878 rv = trans.RestartIgnoringLastError(callback.callback());
8879 EXPECT_EQ(ERR_IO_PENDING, rv);
8880 EXPECT_EQ(OK, callback.WaitForResult());
8881
8882 CheckWasHttpResponse(&trans);
8883 CheckResponsePort(&trans, 70);
8884 CheckResponseData(&trans, "0123456789");
8885 EXPECT_EQ(true, headers_handler.was_proxied());
8886 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8887
8888 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8889 // proxy socket to disconnect.
8890 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8891
8892 base::RunLoop().RunUntilIdle();
8893 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8894 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8895}
8896
8897// Checks if a request's specified "user-agent" header shows up correctly in the
8898// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148899TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008900 const char kConfiguredUserAgent[] = "Configured User-Agent";
8901 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568902 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148903 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568904 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498905 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568906
Ryan Hamiltonabad59e2019-06-06 04:02:598907 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238908 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258909 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238910 mock_quic_data.AddWrite(SYNCHRONOUS,
8911 ConstructInitialSettingsPacket(packet_num++));
8912 }
Yixin Wang46a273ec302018-01-23 17:59:568913
Ryan Hamilton0239aac2018-05-19 00:03:138914 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008915 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338916 mock_quic_data.AddWrite(
Ryan Hamilton0d65a8c2019-06-07 00:46:028917 SYNCHRONOUS,
8918 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:238919 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8920 false, HttpProxyConnectJob::kH2QuicTunnelPriority, std::move(headers),
8921 0));
Yixin Wang46a273ec302018-01-23 17:59:568922 // Return an error, so the transaction stops here (this test isn't interested
8923 // in the rest).
8924 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8925
8926 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8927
Matt Menked732ea42019-03-08 12:05:008928 StaticHttpUserAgentSettings http_user_agent_settings(
8929 std::string() /* accept_language */, kConfiguredUserAgent);
8930 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568931 CreateSession();
8932
8933 request_.url = GURL("https://mail.example.org/");
8934 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008935 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568936 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8937 HeadersHandler headers_handler;
8938 trans.SetBeforeHeadersSentCallback(
8939 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8940 base::Unretained(&headers_handler)));
8941 TestCompletionCallback callback;
8942 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8943 EXPECT_EQ(ERR_IO_PENDING, rv);
8944 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8945
8946 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8947 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8948}
8949
Yixin Wang00fc44c2018-01-23 21:12:208950// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8951// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148952TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208953 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148954 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208955 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498956 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208957
8958 const RequestPriority request_priority = MEDIUM;
8959
Ryan Hamiltonabad59e2019-06-06 04:02:598960 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:238961 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:258962 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:238963 mock_quic_data.AddWrite(SYNCHRONOUS,
8964 ConstructInitialSettingsPacket(packet_num++));
8965 }
Zhongyi Shi32f2fd02018-04-16 18:23:438966 mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:238967 SYNCHRONOUS,
8968 ConstructClientRequestHeadersPacket(
8969 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
8970 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8971 ConnectRequestHeaders("mail.example.org:443"), 0));
Yixin Wang00fc44c2018-01-23 21:12:208972 // Return an error, so the transaction stops here (this test isn't interested
8973 // in the rest).
8974 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8975
8976 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8977
8978 CreateSession();
8979
8980 request_.url = GURL("https://mail.example.org/");
8981 HttpNetworkTransaction trans(request_priority, session_.get());
8982 TestCompletionCallback callback;
8983 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8984 EXPECT_EQ(ERR_IO_PENDING, rv);
8985 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8986
8987 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8988 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8989}
8990
Matt Menkeedaf3b82019-03-14 21:39:448991// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8992// HTTP/2 stream dependency and weights given the request priority.
8993TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8994 session_params_.enable_quic = true;
8995 session_params_.enable_quic_proxies_for_https_urls = true;
8996 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8997 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8998
8999 const RequestPriority kRequestPriority = MEDIUM;
9000 const RequestPriority kRequestPriority2 = LOWEST;
9001
Ryan Hamiltonabad59e2019-06-06 04:02:599002 MockQuicData mock_quic_data(version_);
Victor Vasiliev7da08172019-10-14 06:04:259003 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239004 mock_quic_data.AddWrite(ASYNC, ConstructInitialSettingsPacket(1));
9005 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9006 } else {
9007 mock_quic_data.AddWrite(
9008 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9009 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
9010 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
9011 ConnectRequestHeaders("mail.example.org:443"), 0));
9012 }
Matt Menkeedaf3b82019-03-14 21:39:449013 // This should never be reached.
9014 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
9015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9016
9017 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:599018 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:449019 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
9020 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9021
9022 int original_max_sockets_per_group =
9023 ClientSocketPoolManager::max_sockets_per_group(
9024 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
9025 ClientSocketPoolManager::set_max_sockets_per_group(
9026 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
9027 int original_max_sockets_per_pool =
9028 ClientSocketPoolManager::max_sockets_per_pool(
9029 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
9030 ClientSocketPoolManager::set_max_sockets_per_pool(
9031 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
9032 CreateSession();
9033
9034 request_.url = GURL("https://mail.example.org/");
9035 HttpNetworkTransaction trans(kRequestPriority, session_.get());
9036 TestCompletionCallback callback;
9037 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
9038 EXPECT_EQ(ERR_IO_PENDING, rv);
9039
9040 HttpRequestInfo request2;
9041 request2.url = GURL("https://mail.example.org/some/other/path/");
9042 request2.traffic_annotation =
9043 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9044
9045 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
9046 TestCompletionCallback callback2;
9047 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
9048 EXPECT_EQ(ERR_IO_PENDING, rv2);
9049
9050 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
9051 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9052
9053 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
9054
9055 ClientSocketPoolManager::set_max_sockets_per_pool(
9056 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
9057 original_max_sockets_per_pool);
9058 ClientSocketPoolManager::set_max_sockets_per_group(
9059 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
9060 original_max_sockets_per_group);
9061}
9062
Yixin Wang46a273ec302018-01-23 17:59:569063// Test the request-challenge-retry sequence for basic auth, over a QUIC
9064// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:149065TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:569066 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
9067 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:569068
Yixin Wang46a273ec302018-01-23 17:59:569069 // On the second pass, the body read of the auth challenge is synchronous, so
9070 // IsConnectedAndIdle returns false. The socket should still be drained and
9071 // reused. See http://crbug.com/544255.
9072 for (int i = 0; i < 2; ++i) {
Bence Béky6e243aa2019-12-13 19:01:079073 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229074 version_,
9075 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9076 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Bence Béky6e243aa2019-12-13 19:01:079077 client_headers_include_h2_stream_dependency_);
9078 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229079 version_,
9080 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9081 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
Bence Béky6e243aa2019-12-13 19:01:079082 false);
Yixin Wang46a273ec302018-01-23 17:59:569083
9084 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:149085 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:569086 proxy_resolution_service_ =
9087 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:499088 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:569089
Ryan Hamiltonabad59e2019-06-06 04:02:599090 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529091 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:569092
Renjie Tangaadb84b2019-08-31 01:00:239093 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259094 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239095 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:079096 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
Renjie Tangaadb84b2019-08-31 01:00:239097 }
Yixin Wang46a273ec302018-01-23 17:59:569098
9099 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439100 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079101 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239102 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9103 false,
Matt Menke6e879bd2019-03-18 17:26:049104 ConvertRequestPriorityToQuicPriority(
9105 HttpProxyConnectJob::kH2QuicTunnelPriority),
Bence Béky6e243aa2019-12-13 19:01:079106 client_maker.ConnectRequestHeaders("mail.example.org:443"), 0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029107 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569108
Ryan Hamilton0239aac2018-05-19 00:03:139109 spdy::SpdyHeaderBlock headers =
Bence Béky6e243aa2019-12-13 19:01:079110 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569111 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9112 headers["content-length"] = "10";
9113 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079114 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339115 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029116 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569117
9118 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:439119 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079120 ASYNC, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339121 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179122 false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569123 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:439124 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079125 SYNCHRONOUS, server_maker.MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:339126 2, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton7505eb92019-06-08 00:22:179127 false, false, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:569128 }
9129 server_data_offset += 10;
9130
Renjie Tangaadb84b2019-08-31 01:00:239131 mock_quic_data.AddWrite(
Bence Béky6e243aa2019-12-13 19:01:079132 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 2, 1, 1, true));
9133
9134 if (VersionUsesHttp3(version_.transport_version)) {
9135 mock_quic_data.AddWrite(
9136 SYNCHRONOUS,
9137 client_maker.MakeDataPacket(
9138 packet_num++, GetQpackDecoderStreamId(),
9139 /* should_include_version = */ true,
9140 /* fin = */ false, StreamCancellationQpackDecoderInstruction(0)));
9141 }
Yixin Wang46a273ec302018-01-23 17:59:569142
9143 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339144 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079145 client_maker.MakeRstPacket(
Renjie Tangaadb84b2019-08-31 01:00:239146 packet_num++, false, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamiltonb5d4c5a2019-06-21 22:08:419147 quic::QUIC_STREAM_CANCELLED,
Frank Kastenholz684ea412019-02-13 18:48:189148 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:569149
Bence Béky6e243aa2019-12-13 19:01:079150 headers = client_maker.ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:569151 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
9152 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:049153 SYNCHRONOUS,
Bence Béky6e243aa2019-12-13 19:01:079154 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239155 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1), false,
9156 false,
Matt Menke6e879bd2019-03-18 17:26:049157 ConvertRequestPriorityToQuicPriority(
9158 HttpProxyConnectJob::kH2QuicTunnelPriority),
9159 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton0d65a8c2019-06-07 00:46:029160 nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569161
9162 // Response to wrong password
9163 headers =
Bence Béky6e243aa2019-12-13 19:01:079164 server_maker.GetResponseHeaders("407 Proxy Authentication Required");
Yixin Wang46a273ec302018-01-23 17:59:569165 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
9166 headers["content-length"] = "10";
9167 mock_quic_data.AddRead(
Bence Béky6e243aa2019-12-13 19:01:079168 ASYNC, server_maker.MakeResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:339169 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton0d65a8c2019-06-07 00:46:029170 false, std::move(headers), nullptr));
Yixin Wang46a273ec302018-01-23 17:59:569171 mock_quic_data.AddRead(SYNCHRONOUS,
9172 ERR_IO_PENDING); // No more data to read
9173
Bence Béky6e243aa2019-12-13 19:01:079174 if (VersionUsesHttp3(version_.transport_version)) {
9175 mock_quic_data.AddWrite(
9176 SYNCHRONOUS,
9177 client_maker.MakeAckAndDataPacket(
9178 packet_num++, false, GetQpackDecoderStreamId(), 3, 3, 1, false,
9179 StreamCancellationQpackDecoderInstruction(1)));
9180 mock_quic_data.AddWrite(SYNCHRONOUS,
9181 client_maker.MakeRstPacket(
9182 packet_num++, false,
9183 GetNthClientInitiatedBidirectionalStreamId(1),
9184 quic::QUIC_STREAM_CANCELLED));
9185 } else {
9186 mock_quic_data.AddWrite(SYNCHRONOUS,
9187 client_maker.MakeAckAndRstPacket(
9188 packet_num++, false,
9189 GetNthClientInitiatedBidirectionalStreamId(1),
9190 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
9191 }
Yixin Wang46a273ec302018-01-23 17:59:569192
9193 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9194 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
9195
9196 CreateSession();
9197
9198 request_.url = GURL("https://mail.example.org/");
9199 // Ensure that proxy authentication is attempted even
9200 // when the no authentication data flag is set.
9201 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
9202 {
9203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9204 HeadersHandler headers_handler;
9205 trans.SetBeforeHeadersSentCallback(
9206 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
9207 base::Unretained(&headers_handler)));
9208 RunTransaction(&trans);
9209
9210 const HttpResponseInfo* response = trans.GetResponseInfo();
9211 ASSERT_TRUE(response != nullptr);
9212 ASSERT_TRUE(response->headers.get() != nullptr);
9213 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9214 response->headers->GetStatusLine());
9215 EXPECT_TRUE(response->headers->IsKeepAlive());
9216 EXPECT_EQ(407, response->headers->response_code());
9217 EXPECT_EQ(10, response->headers->GetContentLength());
9218 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589219 base::Optional<AuthChallengeInfo> auth_challenge =
9220 response->auth_challenge;
9221 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569222 EXPECT_TRUE(auth_challenge->is_proxy);
9223 EXPECT_EQ("https://proxy.example.org:70",
9224 auth_challenge->challenger.Serialize());
9225 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9226 EXPECT_EQ("basic", auth_challenge->scheme);
9227
9228 TestCompletionCallback callback;
9229 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
9230 callback.callback());
9231 EXPECT_EQ(ERR_IO_PENDING, rv);
9232 EXPECT_EQ(OK, callback.WaitForResult());
9233
9234 response = trans.GetResponseInfo();
9235 ASSERT_TRUE(response != nullptr);
9236 ASSERT_TRUE(response->headers.get() != nullptr);
9237 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
9238 response->headers->GetStatusLine());
9239 EXPECT_TRUE(response->headers->IsKeepAlive());
9240 EXPECT_EQ(407, response->headers->response_code());
9241 EXPECT_EQ(10, response->headers->GetContentLength());
9242 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589243 auth_challenge = response->auth_challenge;
9244 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:569245 EXPECT_TRUE(auth_challenge->is_proxy);
9246 EXPECT_EQ("https://proxy.example.org:70",
9247 auth_challenge->challenger.Serialize());
9248 EXPECT_EQ("MyRealm1", auth_challenge->realm);
9249 EXPECT_EQ("basic", auth_challenge->scheme);
9250 }
9251 // HttpNetworkTransaction is torn down now that it's out of scope, causing
9252 // the QUIC stream to be cleaned up (since the proxy socket cannot be
9253 // reused because it's not connected).
9254 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9255 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9256 }
9257}
9258
Yixin Wang385652a2018-02-16 02:37:239259TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
Ryan Hamilton6c6493102019-12-05 21:36:509260 client_maker_.set_max_allowed_push_id(quic::kMaxQuicStreamId);
9261 context_.params()->max_allowed_push_id = quic::kMaxQuicStreamId;
9262
Yixin Wang385652a2018-02-16 02:37:239263 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
9264 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:569265 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:239266 !client_headers_include_h2_stream_dependency_) {
9267 return;
9268 }
9269
Victor Vasiliev7da08172019-10-14 06:04:259270 if (quic::VersionUsesHttp3(version_.transport_version)) {
Renjie Tangba21e032019-09-27 21:52:289271 // HTTP/3 currently doesn't support PRIORITY.
Ryan Hamiltone940bd12019-06-30 02:46:459272 return;
9273 }
9274
Victor Vasilieva1e66d72019-12-05 17:55:389275 context_.params()->origins_to_force_quic_on.insert(
Yixin Wang385652a2018-02-16 02:37:239276 HostPortPair::FromString("mail.example.org:443"));
9277
Fan Yang32c5a112018-12-10 20:06:339278 const quic::QuicStreamId client_stream_0 =
9279 GetNthClientInitiatedBidirectionalStreamId(0);
9280 const quic::QuicStreamId client_stream_1 =
9281 GetNthClientInitiatedBidirectionalStreamId(1);
9282 const quic::QuicStreamId client_stream_2 =
9283 GetNthClientInitiatedBidirectionalStreamId(2);
9284 const quic::QuicStreamId push_stream_0 =
9285 GetNthServerInitiatedUnidirectionalStreamId(0);
9286 const quic::QuicStreamId push_stream_1 =
9287 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:239288
Ryan Hamiltonabad59e2019-06-06 04:02:599289 MockQuicData mock_quic_data(version_);
Renjie Tangaadb84b2019-08-31 01:00:239290 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259291 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239292 mock_quic_data.AddWrite(SYNCHRONOUS,
9293 ConstructInitialSettingsPacket(packet_num++));
9294 }
Yixin Wang385652a2018-02-16 02:37:239295
9296 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Renjie Tangaadb84b2019-08-31 01:00:239297 mock_quic_data.AddWrite(
9298 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
9299 packet_num++, client_stream_0, true, true, HIGHEST,
9300 GetRequestHeaders("GET", "https", "/0.jpg"), 0));
Ryan Hamilton0d65a8c2019-06-07 00:46:029301 mock_quic_data.AddWrite(
9302 SYNCHRONOUS,
9303 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239304 packet_num++, client_stream_1, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029305 GetRequestHeaders("GET", "https", "/1.jpg"), client_stream_0));
9306 mock_quic_data.AddWrite(
9307 SYNCHRONOUS,
9308 ConstructClientRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239309 packet_num++, client_stream_2, true, true, MEDIUM,
Ryan Hamilton0d65a8c2019-06-07 00:46:029310 GetRequestHeaders("GET", "https", "/2.jpg"), client_stream_1));
Yixin Wang385652a2018-02-16 02:37:239311
9312 // Server replies "OK" for the three requests.
Ryan Hamilton0d65a8c2019-06-07 00:46:029313 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9314 1, client_stream_0, false, false,
9315 GetResponseHeaders("200 OK")));
9316 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9317 2, client_stream_1, false, false,
9318 GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239319 mock_quic_data.AddWrite(SYNCHRONOUS,
9320 ConstructClientAckPacket(packet_num++, 2, 1, 1));
Ryan Hamilton0d65a8c2019-06-07 00:46:029321 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
9322 3, client_stream_2, false, false,
9323 GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239324
9325 // Server sends two push promises associated with |client_stream_0|; client
9326 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
9327 // dependency info for each push promise stream.
Ryan Hamilton0d65a8c2019-06-07 00:46:029328 mock_quic_data.AddRead(
9329 ASYNC,
9330 ConstructServerPushPromisePacket(
9331 4, client_stream_0, push_stream_0, false,
9332 GetRequestHeaders("GET", "https", "/pushed_0.jpg"), &server_maker_));
Yixin Wang385652a2018-02-16 02:37:239333 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:439334 SYNCHRONOUS,
9335 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239336 packet_num++, false, 4, 3, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439337 {{push_stream_0, client_stream_2,
Ryan Hamilton0d65a8c2019-06-07 00:46:029338 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}}));
9339 mock_quic_data.AddRead(
9340 ASYNC,
9341 ConstructServerPushPromisePacket(
9342 5, client_stream_0, push_stream_1, false,
9343 GetRequestHeaders("GET", "https", "/pushed_1.jpg"), &server_maker_));
9344 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientPriorityPacket(
Renjie Tangaadb84b2019-08-31 01:00:239345 packet_num++, false, push_stream_1,
Ryan Hamilton0d65a8c2019-06-07 00:46:029346 push_stream_0, DEFAULT_PRIORITY));
Yixin Wang385652a2018-02-16 02:37:239347
9348 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:439349 mock_quic_data.AddRead(
9350 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029351 6, push_stream_0, false, false, GetResponseHeaders("200 OK")));
Renjie Tangaadb84b2019-08-31 01:00:239352 mock_quic_data.AddWrite(SYNCHRONOUS,
9353 ConstructClientAckPacket(packet_num++, 6, 5, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439354 mock_quic_data.AddRead(
9355 ASYNC, ConstructServerResponseHeadersPacket(
Ryan Hamilton0d65a8c2019-06-07 00:46:029356 7, push_stream_1, false, false, GetResponseHeaders("200 OK")));
Yixin Wang385652a2018-02-16 02:37:239357
9358 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
9359 // priority updates to match the request's priority. Client sends PRIORITY
9360 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:439361 mock_quic_data.AddWrite(
9362 SYNCHRONOUS,
9363 ConstructClientAckAndPriorityFramesPacket(
Renjie Tangaadb84b2019-08-31 01:00:239364 packet_num++, false, 7, 7, 1,
Zhongyi Shi32f2fd02018-04-16 18:23:439365 {{push_stream_1, client_stream_2,
9366 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
9367 {push_stream_0, client_stream_0,
Ryan Hamilton0d65a8c2019-06-07 00:46:029368 ConvertRequestPriorityToQuicPriority(HIGHEST)}}));
Yixin Wang385652a2018-02-16 02:37:239369
9370 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:439371 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:439372 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179373 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419374 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:439375 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179376 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419377 header + "hello 1!"));
Renjie Tangaadb84b2019-08-31 01:00:239378 mock_quic_data.AddWrite(SYNCHRONOUS,
9379 ConstructClientAckPacket(packet_num++, 9, 8, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439380 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179381 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true,
Renjief49758b2019-01-11 23:32:419382 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:439383 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:439384 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179385 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true,
Renjief49758b2019-01-11 23:32:419386 header2 + "and hello 0!"));
Renjie Tangaadb84b2019-08-31 01:00:239387 mock_quic_data.AddWrite(SYNCHRONOUS,
9388 ConstructClientAckPacket(packet_num++, 11, 10, 1));
Zhongyi Shi32f2fd02018-04-16 18:23:439389 mock_quic_data.AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179390 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true,
Renjief49758b2019-01-11 23:32:419391 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:239392
Yixin Wang385652a2018-02-16 02:37:239393 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
9394 mock_quic_data.AddRead(ASYNC, 0); // EOF
9395 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9396
9397 // The non-alternate protocol job needs to hang in order to guarantee that
9398 // the alternate-protocol job will "win".
9399 AddHangingNonAlternateProtocolSocketData();
9400
9401 CreateSession();
9402
9403 request_.url = GURL("https://mail.example.org/0.jpg");
9404 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
9405 TestCompletionCallback callback_0;
9406 EXPECT_EQ(ERR_IO_PENDING,
9407 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
9408 base::RunLoop().RunUntilIdle();
9409
9410 request_.url = GURL("https://mail.example.org/1.jpg");
9411 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
9412 TestCompletionCallback callback_1;
9413 EXPECT_EQ(ERR_IO_PENDING,
9414 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
9415 base::RunLoop().RunUntilIdle();
9416
9417 request_.url = GURL("https://mail.example.org/2.jpg");
9418 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
9419 TestCompletionCallback callback_2;
9420 EXPECT_EQ(ERR_IO_PENDING,
9421 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
9422 base::RunLoop().RunUntilIdle();
9423
9424 // Client makes request that matches resource pushed in |pushed_stream_0|.
9425 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
9426 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
9427 TestCompletionCallback callback_3;
9428 EXPECT_EQ(ERR_IO_PENDING,
9429 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
9430 base::RunLoop().RunUntilIdle();
9431
9432 EXPECT_TRUE(callback_0.have_result());
9433 EXPECT_EQ(OK, callback_0.WaitForResult());
9434 EXPECT_TRUE(callback_1.have_result());
9435 EXPECT_EQ(OK, callback_1.WaitForResult());
9436 EXPECT_TRUE(callback_2.have_result());
9437 EXPECT_EQ(OK, callback_2.WaitForResult());
9438
9439 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
9440 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
9441 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
9442 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
9443
9444 mock_quic_data.Resume();
9445 base::RunLoop().RunUntilIdle();
9446 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
9447 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
9448}
9449
Matt Menke26e41542019-06-05 01:09:519450// Test that NetworkIsolationKey is respected by QUIC connections, when
9451// kPartitionConnectionsByNetworkIsolationKey is enabled.
9452TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
Shivani Sharma8ae506c2019-07-21 21:08:279453 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9454 const auto kOrigin2 = url::Origin::Create(GURL("http://origin2/"));
9455 NetworkIsolationKey network_isolation_key1(kOrigin1, kOrigin1);
9456 NetworkIsolationKey network_isolation_key2(kOrigin2, kOrigin2);
Matt Menke26e41542019-06-05 01:09:519457
Victor Vasilieva1e66d72019-12-05 17:55:389458 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519459 HostPortPair::FromString("mail.example.org:443"));
9460
9461 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
9462 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
9463 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
9464 // the same way as the HTTP over H2 proxy case.
9465 for (bool use_proxy : {false, true}) {
9466 SCOPED_TRACE(use_proxy);
9467
9468 if (use_proxy) {
9469 proxy_resolution_service_ =
9470 ProxyResolutionService::CreateFixedFromPacResult(
9471 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
9472 } else {
9473 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
9474 }
9475
9476 GURL url1;
9477 GURL url2;
9478 GURL url3;
9479 if (use_proxy) {
9480 url1 = GURL("http://mail.example.org/1");
9481 url2 = GURL("http://mail.example.org/2");
9482 url3 = GURL("http://mail.example.org/3");
9483 } else {
9484 url1 = GURL("https://mail.example.org/1");
9485 url2 = GURL("https://mail.example.org/2");
9486 url3 = GURL("https://mail.example.org/3");
9487 }
9488
9489 for (bool partition_connections : {false, true}) {
9490 SCOPED_TRACE(partition_connections);
9491
9492 base::test::ScopedFeatureList feature_list;
9493 if (partition_connections) {
9494 feature_list.InitAndEnableFeature(
9495 features::kPartitionConnectionsByNetworkIsolationKey);
9496 } else {
9497 feature_list.InitAndDisableFeature(
9498 features::kPartitionConnectionsByNetworkIsolationKey);
9499 }
9500
9501 // Reads and writes for the unpartitioned case, where only one socket is
9502 // used.
9503
Victor Vasilieva1e66d72019-12-05 17:55:389504 context_.params()->origins_to_force_quic_on.insert(
Matt Menke26e41542019-06-05 01:09:519505 HostPortPair::FromString("mail.example.org:443"));
9506
Ryan Hamiltonabad59e2019-06-06 04:02:599507 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:519508 QuicTestPacketMaker client_maker1(
9509 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229510 quic::QuicUtils::CreateRandomConnectionId(
9511 context_.random_generator()),
9512 context_.clock(), kDefaultServerHostName,
9513 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519514 client_headers_include_h2_stream_dependency_);
9515 QuicTestPacketMaker server_maker1(
9516 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229517 quic::QuicUtils::CreateRandomConnectionId(
9518 context_.random_generator()),
9519 context_.clock(), kDefaultServerHostName,
9520 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519521
Renjie Tangaadb84b2019-08-31 01:00:239522 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259523 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239524 unpartitioned_mock_quic_data.AddWrite(
9525 SYNCHRONOUS, client_maker1.MakeInitialSettingsPacket(packet_num++));
9526 }
Matt Menke26e41542019-06-05 01:09:519527
9528 unpartitioned_mock_quic_data.AddWrite(
9529 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029530 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239531 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9532 true, ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029533 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519534 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029535 ASYNC, server_maker1.MakeResponseHeadersPacket(
9536 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9537 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519538 unpartitioned_mock_quic_data.AddRead(
9539 ASYNC, server_maker1.MakeDataPacket(
9540 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179541 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519542 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239543 SYNCHRONOUS, ConstructClientAckPacket(packet_num++, 2, 1, 1));
Matt Menke26e41542019-06-05 01:09:519544
9545 unpartitioned_mock_quic_data.AddWrite(
9546 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029547 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239548 packet_num++, GetNthClientInitiatedBidirectionalStreamId(1),
9549 false, true,
Matt Menke26e41542019-06-05 01:09:519550 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029551 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519552 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029553 ASYNC, server_maker1.MakeResponseHeadersPacket(
9554 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9555 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519556 unpartitioned_mock_quic_data.AddRead(
9557 ASYNC, server_maker1.MakeDataPacket(
9558 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179559 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519560 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239561 SYNCHRONOUS,
9562 ConstructClientAckAndConnectionClosePacket(packet_num++, 4, 3, 1));
Matt Menke26e41542019-06-05 01:09:519563
9564 unpartitioned_mock_quic_data.AddWrite(
9565 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029566 client_maker1.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239567 packet_num++, GetNthClientInitiatedBidirectionalStreamId(2),
9568 false, true,
Matt Menke26e41542019-06-05 01:09:519569 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029570 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519571 unpartitioned_mock_quic_data.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029572 ASYNC, server_maker1.MakeResponseHeadersPacket(
9573 5, GetNthClientInitiatedBidirectionalStreamId(2), false,
9574 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519575 unpartitioned_mock_quic_data.AddRead(
9576 ASYNC, server_maker1.MakeDataPacket(
9577 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
Ryan Hamilton7505eb92019-06-08 00:22:179578 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519579 unpartitioned_mock_quic_data.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239580 SYNCHRONOUS,
9581 ConstructClientAckAndConnectionClosePacket(packet_num++, 6, 5, 1));
Matt Menke26e41542019-06-05 01:09:519582
9583 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9584
9585 // Reads and writes for the partitioned case, where two sockets are used.
9586
Ryan Hamiltonabad59e2019-06-06 04:02:599587 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:519588 QuicTestPacketMaker client_maker2(
9589 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229590 quic::QuicUtils::CreateRandomConnectionId(
9591 context_.random_generator()),
9592 context_.clock(), kDefaultServerHostName,
9593 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519594 client_headers_include_h2_stream_dependency_);
9595 QuicTestPacketMaker server_maker2(
9596 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229597 quic::QuicUtils::CreateRandomConnectionId(
9598 context_.random_generator()),
9599 context_.clock(), kDefaultServerHostName,
9600 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519601
Renjie Tangaadb84b2019-08-31 01:00:239602 int packet_num2 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259603 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239604 partitioned_mock_quic_data1.AddWrite(
9605 SYNCHRONOUS,
9606 client_maker2.MakeInitialSettingsPacket(packet_num2++));
9607 }
Matt Menke26e41542019-06-05 01:09:519608
9609 partitioned_mock_quic_data1.AddWrite(
9610 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029611 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239612 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(0),
9613 true, true,
Matt Menke26e41542019-06-05 01:09:519614 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029615 GetRequestHeaders("GET", url1.scheme(), "/1"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519616 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029617 ASYNC, server_maker2.MakeResponseHeadersPacket(
9618 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9619 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519620 partitioned_mock_quic_data1.AddRead(
9621 ASYNC, server_maker2.MakeDataPacket(
9622 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179623 true, ConstructDataHeader(1) + "1"));
Matt Menke26e41542019-06-05 01:09:519624 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239625 SYNCHRONOUS,
9626 client_maker2.MakeAckPacket(packet_num2++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519627
9628 partitioned_mock_quic_data1.AddWrite(
9629 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029630 client_maker2.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239631 packet_num2++, GetNthClientInitiatedBidirectionalStreamId(1),
9632 false, true,
Matt Menke26e41542019-06-05 01:09:519633 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029634 GetRequestHeaders("GET", url3.scheme(), "/3"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519635 partitioned_mock_quic_data1.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029636 ASYNC, server_maker2.MakeResponseHeadersPacket(
9637 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
9638 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519639 partitioned_mock_quic_data1.AddRead(
9640 ASYNC, server_maker2.MakeDataPacket(
9641 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Ryan Hamilton7505eb92019-06-08 00:22:179642 true, ConstructDataHeader(1) + "3"));
Matt Menke26e41542019-06-05 01:09:519643 partitioned_mock_quic_data1.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239644 SYNCHRONOUS,
9645 client_maker2.MakeAckPacket(packet_num2++, 4, 3, 1, true));
Matt Menke26e41542019-06-05 01:09:519646
9647 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9648
Ryan Hamiltonabad59e2019-06-06 04:02:599649 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:519650 QuicTestPacketMaker client_maker3(
9651 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229652 quic::QuicUtils::CreateRandomConnectionId(
9653 context_.random_generator()),
9654 context_.clock(), kDefaultServerHostName,
9655 quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519656 client_headers_include_h2_stream_dependency_);
9657 QuicTestPacketMaker server_maker3(
9658 version_,
Victor Vasiliev7752898d2019-11-14 21:30:229659 quic::QuicUtils::CreateRandomConnectionId(
9660 context_.random_generator()),
9661 context_.clock(), kDefaultServerHostName,
9662 quic::Perspective::IS_SERVER, false);
Matt Menke26e41542019-06-05 01:09:519663
Renjie Tangaadb84b2019-08-31 01:00:239664 int packet_num3 = 1;
Victor Vasiliev7da08172019-10-14 06:04:259665 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239666 partitioned_mock_quic_data2.AddWrite(
9667 SYNCHRONOUS,
9668 client_maker3.MakeInitialSettingsPacket(packet_num3++));
9669 }
Matt Menke26e41542019-06-05 01:09:519670
9671 partitioned_mock_quic_data2.AddWrite(
9672 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029673 client_maker3.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239674 packet_num3++, GetNthClientInitiatedBidirectionalStreamId(0),
9675 true, true,
Matt Menke26e41542019-06-05 01:09:519676 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
Ryan Hamilton0d65a8c2019-06-07 00:46:029677 GetRequestHeaders("GET", url2.scheme(), "/2"), 0, nullptr));
Matt Menke26e41542019-06-05 01:09:519678 partitioned_mock_quic_data2.AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029679 ASYNC, server_maker3.MakeResponseHeadersPacket(
9680 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9681 false, GetResponseHeaders("200 OK"), nullptr));
Matt Menke26e41542019-06-05 01:09:519682 partitioned_mock_quic_data2.AddRead(
9683 ASYNC, server_maker3.MakeDataPacket(
9684 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179685 true, ConstructDataHeader(1) + "2"));
Matt Menke26e41542019-06-05 01:09:519686 partitioned_mock_quic_data2.AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239687 SYNCHRONOUS,
9688 client_maker3.MakeAckPacket(packet_num3++, 2, 1, 1, true));
Matt Menke26e41542019-06-05 01:09:519689
9690 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9691
9692 if (partition_connections) {
9693 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
9694 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
9695 } else {
9696 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
9697 }
9698
9699 CreateSession();
9700
9701 TestCompletionCallback callback;
9702 HttpRequestInfo request1;
9703 request1.method = "GET";
9704 request1.url = GURL(url1);
9705 request1.traffic_annotation =
9706 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9707 request1.network_isolation_key = network_isolation_key1;
9708 HttpNetworkTransaction trans1(LOWEST, session_.get());
9709 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
9710 EXPECT_THAT(callback.GetResult(rv), IsOk());
9711 std::string response_data1;
9712 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
9713 EXPECT_EQ("1", response_data1);
9714
9715 HttpRequestInfo request2;
9716 request2.method = "GET";
9717 request2.url = GURL(url2);
9718 request2.traffic_annotation =
9719 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9720 request2.network_isolation_key = network_isolation_key2;
9721 HttpNetworkTransaction trans2(LOWEST, session_.get());
9722 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
9723 EXPECT_THAT(callback.GetResult(rv), IsOk());
9724 std::string response_data2;
9725 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
9726 EXPECT_EQ("2", response_data2);
9727
9728 HttpRequestInfo request3;
9729 request3.method = "GET";
9730 request3.url = GURL(url3);
9731 request3.traffic_annotation =
9732 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9733 request3.network_isolation_key = network_isolation_key1;
9734 HttpNetworkTransaction trans3(LOWEST, session_.get());
9735 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
9736 EXPECT_THAT(callback.GetResult(rv), IsOk());
9737 std::string response_data3;
9738 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9739 EXPECT_EQ("3", response_data3);
9740
9741 if (partition_connections) {
9742 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9743 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9744 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9745 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9746 } else {
9747 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9748 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9749 }
9750 }
9751 }
9752}
9753
9754// Test that two requests to the same origin over QUIC tunnels use different
9755// QUIC sessions if their NetworkIsolationKeys don't match, and
9756// kPartitionConnectionsByNetworkIsolationKey is enabled.
9757TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9758 base::test::ScopedFeatureList feature_list;
9759 feature_list.InitAndEnableFeature(
9760 features::kPartitionConnectionsByNetworkIsolationKey);
9761
9762 session_params_.enable_quic = true;
9763 session_params_.enable_quic_proxies_for_https_urls = true;
9764 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9765 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9766
9767 const char kGetRequest[] =
9768 "GET / HTTP/1.1\r\n"
9769 "Host: mail.example.org\r\n"
9770 "Connection: keep-alive\r\n\r\n";
9771 const char kGetResponse[] =
9772 "HTTP/1.1 200 OK\r\n"
9773 "Content-Length: 10\r\n\r\n";
9774
Ryan Hamiltonabad59e2019-06-06 04:02:599775 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9776 std::make_unique<MockQuicData>(version_),
9777 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519778
9779 for (int index : {0, 1}) {
9780 QuicTestPacketMaker client_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229781 version_,
9782 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9783 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Matt Menke26e41542019-06-05 01:09:519784 client_headers_include_h2_stream_dependency_);
9785 QuicTestPacketMaker server_maker(
Victor Vasiliev7752898d2019-11-14 21:30:229786 version_,
9787 quic::QuicUtils::CreateRandomConnectionId(context_.random_generator()),
9788 context_.clock(), kDefaultServerHostName, quic::Perspective::IS_SERVER,
9789 false);
Matt Menke26e41542019-06-05 01:09:519790
Renjie Tangaadb84b2019-08-31 01:00:239791 int packet_num = 1;
Victor Vasiliev7da08172019-10-14 06:04:259792 if (VersionUsesHttp3(version_.transport_version)) {
Renjie Tangaadb84b2019-08-31 01:00:239793 mock_quic_data[index]->AddWrite(
9794 SYNCHRONOUS, client_maker.MakeInitialSettingsPacket(packet_num++));
9795 }
Matt Menke26e41542019-06-05 01:09:519796
Ryan Hamiltonabad59e2019-06-06 04:02:599797 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519798 SYNCHRONOUS,
Ryan Hamilton0d65a8c2019-06-07 00:46:029799 client_maker.MakeRequestHeadersPacket(
Renjie Tangaadb84b2019-08-31 01:00:239800 packet_num++, GetNthClientInitiatedBidirectionalStreamId(0), true,
9801 false,
Matt Menke26e41542019-06-05 01:09:519802 ConvertRequestPriorityToQuicPriority(
9803 HttpProxyConnectJob::kH2QuicTunnelPriority),
Ryan Hamilton0d65a8c2019-06-07 00:46:029804 ConnectRequestHeaders("mail.example.org:443"), 0, nullptr));
Ryan Hamiltonabad59e2019-06-06 04:02:599805 mock_quic_data[index]->AddRead(
Ryan Hamilton0d65a8c2019-06-07 00:46:029806 ASYNC, server_maker.MakeResponseHeadersPacket(
Matt Menke26e41542019-06-05 01:09:519807 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9808 false, GetResponseHeaders("200 OK"), nullptr));
9809
9810 std::string header = ConstructDataHeader(strlen(kGetRequest));
9811 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599812 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239813 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
9814 packet_num++, false,
9815 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Zhongyi Shid1c00fc42019-12-14 06:05:099816 1, false, quiche::QuicheStringPiece(kGetRequest)));
Matt Menke26e41542019-06-05 01:09:519817 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599818 mock_quic_data[index]->AddWrite(
Renjie Tangd5133972019-12-06 00:20:289819 SYNCHRONOUS, client_maker.MakeAckAndDataPacket(
Renjie Tangaadb84b2019-08-31 01:00:239820 packet_num++, false,
9821 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1,
Renjie Tangd5133972019-12-06 00:20:289822 1, false, {header + std::string(kGetRequest)}));
Matt Menke26e41542019-06-05 01:09:519823 }
9824
9825 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599826 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519827 ASYNC, server_maker.MakeDataPacket(
9828 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
Ryan Hamilton7505eb92019-06-08 00:22:179829 false, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599830 mock_quic_data[index]->AddRead(
Ryan Hamilton7505eb92019-06-08 00:22:179831 SYNCHRONOUS,
9832 server_maker.MakeDataPacket(
9833 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
9834 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599835 mock_quic_data[index]->AddWrite(
Renjie Tangaadb84b2019-08-31 01:00:239836 SYNCHRONOUS, client_maker.MakeAckPacket(packet_num++, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599837 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9838 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519839
Ryan Hamiltonabad59e2019-06-06 04:02:599840 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519841 }
9842
9843 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9844 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9845 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9846
9847 CreateSession();
9848
9849 request_.url = GURL("https://mail.example.org/");
9850 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9852 RunTransaction(&trans);
9853 CheckResponseData(&trans, "0123456789");
9854
9855 HttpRequestInfo request2;
Shivani Sharma8ae506c2019-07-21 21:08:279856 const auto kOrigin1 = url::Origin::Create(GURL("http://origin1/"));
9857 request_.network_isolation_key = NetworkIsolationKey(kOrigin1, kOrigin1);
Matt Menke26e41542019-06-05 01:09:519858 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9859 RunTransaction(&trans2);
9860 CheckResponseData(&trans2, "0123456789");
9861
Ryan Hamiltonabad59e2019-06-06 04:02:599862 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9863 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9864 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9865 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519866}
9867
[email protected]61a527782013-02-21 03:58:009868} // namespace test
9869} // namespace net