blob: c1344d117495b84875474a6cc54e888967bace13 [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"
[email protected]61a527782013-02-21 03:58:0026#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0427#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2028#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1129#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1230#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5331#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0032#include "net/http/http_auth_handler_factory.h"
33#include "net/http/http_network_session.h"
34#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0435#include "net/http/http_proxy_connect_job.h"
[email protected]61a527782013-02-21 03:58:0036#include "net/http/http_server_properties_impl.h"
37#include "net/http/http_stream.h"
38#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1939#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1140#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0041#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5142#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4643#include "net/log/test_net_log_entry.h"
44#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4045#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0346#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4047#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0848#include "net/quic/crypto/proof_verifier_chromium.h"
49#include "net/quic/mock_crypto_client_stream_factory.h"
50#include "net/quic/mock_quic_data.h"
51#include "net/quic/quic_chromium_alarm_factory.h"
52#include "net/quic/quic_http_stream.h"
53#include "net/quic/quic_http_utils.h"
54#include "net/quic/quic_stream_factory_peer.h"
55#include "net/quic/quic_test_packet_maker.h"
56#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0057#include "net/socket/client_socket_factory.h"
58#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2159#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2860#include "net/socket/socket_performance_watcher.h"
61#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0062#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5863#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5764#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2965#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0166#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4367#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0168#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5169#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
70#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
71#include "net/third_party/quiche/src/quic/core/quic_framer.h"
72#include "net/third_party/quiche/src/quic/core/quic_utils.h"
73#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
74#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
75#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
76#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
77#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
78#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
79#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
80#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1481#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
82#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2983#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0084#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4885#include "net/url_request/url_request.h"
86#include "net/url_request/url_request_job_factory_impl.h"
87#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0188#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0089#include "testing/gtest/include/gtest/gtest.h"
90#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4691#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0092
Reilly Grant89a7e512018-01-20 01:57:1693using ::testing::ElementsAre;
94using ::testing::Key;
95
bnc508835902015-05-12 20:10:2996namespace net {
97namespace test {
[email protected]61a527782013-02-21 03:58:0098
99namespace {
100
bnc359ed2a2016-04-29 20:43:45101enum DestinationType {
102 // In pooling tests with two requests for different origins to the same
103 // destination, the destination should be
104 SAME_AS_FIRST, // the same as the first origin,
105 SAME_AS_SECOND, // the same as the second origin, or
106 DIFFERENT, // different from both.
107};
108
rchf114d982015-10-21 01:34:56109static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52110 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12111static const char kQuicAlternativeServiceWithProbabilityHeader[] =
112 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56113static const char kQuicAlternativeServiceDifferentPortHeader[] =
114 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20115
rch9ae5b3b2016-02-11 00:36:29116const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45117const char kDifferentHostname[] = "different.example.com";
118
119// Run QuicNetworkTransactionWithDestinationTest instances with all value
120// combinations of version and destination_type.
121struct PoolingTestParams {
122 friend std::ostream& operator<<(std::ostream& os,
123 const PoolingTestParams& p) {
Nick Harper23290b82019-05-02 00:02:56124 os << "{ version: " << ParsedQuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45125 << ", destination_type: ";
126 switch (p.destination_type) {
127 case SAME_AS_FIRST:
128 os << "SAME_AS_FIRST";
129 break;
130 case SAME_AS_SECOND:
131 os << "SAME_AS_SECOND";
132 break;
133 case DIFFERENT:
134 os << "DIFFERENT";
135 break;
136 }
Yixin Wang079ad542018-01-11 04:06:05137 os << ", client_headers_include_h2_stream_dependency: "
138 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45139 os << " }";
140 return os;
141 }
142
Nick Harper23290b82019-05-02 00:02:56143 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45144 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05145 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45146};
147
zhongyie537a002017-06-27 16:48:21148std::string GenerateQuicVersionsListForAltSvcHeader(
Nick Harper23290b82019-05-02 00:02:56149 const quic::ParsedQuicVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21150 std::string result = "";
Nick Harper23290b82019-05-02 00:02:56151 for (const quic::ParsedQuicVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21152 if (!result.empty())
153 result.append(",");
Nick Harper23290b82019-05-02 00:02:56154 result.append(base::NumberToString(version.transport_version));
zhongyie537a002017-06-27 16:48:21155 }
156 return result;
157}
158
bnc359ed2a2016-04-29 20:43:45159std::vector<PoolingTestParams> GetPoolingTestParams() {
160 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56161 quic::ParsedQuicVersionVector all_supported_versions =
Victor Vasiliev5d6cdc22019-05-28 20:37:43162 quic::AllVersionsExcept99();
Nick Harper23290b82019-05-02 00:02:56163 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05164 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
165 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
166 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
167 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
168 params.push_back(PoolingTestParams{version, DIFFERENT, false});
169 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45170 }
171 return params;
172}
bncb07c05532015-05-14 19:07:20173
[email protected]61a527782013-02-21 03:58:00174} // namespace
175
ryansturm49a8cb12016-06-15 16:51:09176class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12177 public:
ryansturm49a8cb12016-06-15 16:51:09178 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12179
ryansturm49a8cb12016-06-15 16:51:09180 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12181
ryansturm49a8cb12016-06-15 16:51:09182 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
183 HttpRequestHeaders* request_headers) {
184 if (!proxy_info.is_http() && !proxy_info.is_https() &&
185 !proxy_info.is_quic()) {
186 return;
187 }
188 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12189 }
190
191 private:
ryansturm49a8cb12016-06-15 16:51:09192 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12193};
194
tbansal0f56a39a2016-04-07 22:03:38195class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40196 public:
tbansal180587c2017-02-16 15:13:23197 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
198 bool* rtt_notification_received)
199 : should_notify_updated_rtt_(should_notify_updated_rtt),
200 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38201 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40202
tbansal180587c2017-02-16 15:13:23203 bool ShouldNotifyUpdatedRTT() const override {
204 return *should_notify_updated_rtt_;
205 }
tbansalfdf5665b2015-09-21 22:46:40206
tbansal0f56a39a2016-04-07 22:03:38207 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
208 *rtt_notification_received_ = true;
209 }
210
211 void OnConnectionChanged() override {}
212
213 private:
tbansal180587c2017-02-16 15:13:23214 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38215 bool* rtt_notification_received_;
216
217 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
218};
219
220class TestSocketPerformanceWatcherFactory
221 : public SocketPerformanceWatcherFactory {
222 public:
223 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23224 : watcher_count_(0u),
225 should_notify_updated_rtt_(true),
226 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38227 ~TestSocketPerformanceWatcherFactory() override {}
228
229 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42230 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41231 const Protocol protocol,
232 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51233 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38234 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51235 }
236 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42237 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23238 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
239 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40240 }
241
tbansalc8a94ea2015-11-02 23:58:51242 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40243
tbansalc8a94ea2015-11-02 23:58:51244 bool rtt_notification_received() const { return rtt_notification_received_; }
245
tbansal180587c2017-02-16 15:13:23246 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
247 should_notify_updated_rtt_ = should_notify_updated_rtt;
248 }
249
tbansalc8a94ea2015-11-02 23:58:51250 private:
tbansal0f56a39a2016-04-07 22:03:38251 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23252 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51253 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38254
255 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51256};
257
Ryan Hamilton8d9ee76e2018-05-29 23:52:52258class QuicNetworkTransactionTest
259 : public PlatformTest,
260 public ::testing::WithParamInterface<
Nick Harper23290b82019-05-02 00:02:56261 std::tuple<quic::ParsedQuicVersion, bool>>,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52262 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00263 protected:
[email protected]1c04f9522013-02-21 20:32:43264 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05265 : version_(std::get<0>(GetParam())),
266 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Nick Harper23290b82019-05-02 00:02:56267 supported_versions_(quic::test::SupportedVersions(version_)),
David Schinazic8281052019-01-24 06:14:17268 random_generator_(0),
269 client_maker_(
270 version_,
271 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
272 &clock_,
273 kDefaultServerHostName,
274 quic::Perspective::IS_CLIENT,
275 client_headers_include_h2_stream_dependency_),
276 server_maker_(
277 version_,
278 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
279 &clock_,
280 kDefaultServerHostName,
281 quic::Perspective::IS_SERVER,
282 false),
Nick Harpereb483e12019-05-14 00:18:09283 quic_task_runner_(new TestTaskRunner(&clock_)),
rtenneti052774e2015-11-24 21:00:12284 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43285 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59286 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11287 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
rchf114d982015-10-21 01:34:56288 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19289 request_.method = "GET";
rchf114d982015-10-21 01:34:56290 std::string url("https://");
bncb07c05532015-05-14 19:07:20291 url.append(kDefaultServerHostName);
292 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19293 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10294 request_.traffic_annotation =
295 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52296 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56297
298 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29299 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56300 verify_details_.cert_verify_result.verified_cert = cert;
301 verify_details_.cert_verify_result.is_issued_by_known_root = true;
302 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43303 }
[email protected]61a527782013-02-21 03:58:00304
dcheng67be2b1f2014-10-27 21:47:29305 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00306 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55307 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00308 }
309
dcheng67be2b1f2014-10-27 21:47:29310 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00311 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
312 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55313 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00314 PlatformTest::TearDown();
315 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55316 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40317 session_.reset();
[email protected]61a527782013-02-21 03:58:00318 }
319
Ryan Hamilton8d9ee76e2018-05-29 23:52:52320 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23321 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03322 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52323 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30324 }
325
Ryan Hamilton8d9ee76e2018-05-29 23:52:52326 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23327 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03328 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52329 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58330 }
331
Ryan Hamilton8d9ee76e2018-05-29 23:52:52332 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23333 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52334 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20335 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58336 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20337 }
338
Ryan Hamilton8d9ee76e2018-05-29 23:52:52339 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23340 uint64_t packet_number,
341 uint64_t largest_received,
342 uint64_t smallest_received,
343 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37344 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49345 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37346 }
347
Ryan Hamilton8d9ee76e2018-05-29 23:52:52348 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23349 uint64_t packet_number,
350 uint64_t largest_received,
351 uint64_t smallest_received,
352 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52353 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23354 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49355 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23356 ack_delay_time);
357 }
358
Ryan Hamilton8d9ee76e2018-05-29 23:52:52359 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23360 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52361 quic::QuicStreamId stream_id,
362 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23363 uint64_t largest_received,
364 uint64_t smallest_received,
365 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58366 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49367 num, false, stream_id, error_code, largest_received, smallest_received,
368 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20369 }
370
Ryan Hamilton8d9ee76e2018-05-29 23:52:52371 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23372 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52373 quic::QuicStreamId stream_id,
374 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56375 size_t bytes_written) {
376 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18377 bytes_written,
378 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56379 }
380
Ryan Hamilton8d9ee76e2018-05-29 23:52:52381 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23382 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
383 uint64_t largest_received,
384 uint64_t smallest_received,
385 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58386 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49387 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20388 }
[email protected]61a527782013-02-21 03:58:00389
Ryan Hamilton8d9ee76e2018-05-29 23:52:52390 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58391 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23392 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23394 uint64_t largest_received,
395 uint64_t smallest_received,
396 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52397 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50398 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58399 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12400 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49401 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12402 }
403
Ryan Hamilton8d9ee76e2018-05-29 23:52:52404 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23405 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12406 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52407 quic::QuicStreamId stream_id,
408 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58409 return server_maker_.MakeRstPacket(num, include_version, stream_id,
410 error_code);
zhongyica364fbb2015-12-12 03:39:12411 }
412
Ryan Hamilton8d9ee76e2018-05-29 23:52:52413 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23414 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36416 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37417 }
418
Ryan Hamilton8d9ee76e2018-05-29 23:52:52419 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23420 uint64_t packet_number,
421 uint64_t largest_received,
422 uint64_t smallest_received,
423 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37424 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49425 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37426 }
427
Ryan Hamilton8d9ee76e2018-05-29 23:52:52428 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23429 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57430 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52431 quic::QuicStreamId id,
432 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57433 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52434 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57435 return client_maker_.MakePriorityPacket(
436 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23437 ConvertRequestPriorityToQuicPriority(request_priority), offset);
438 }
439
Ryan Hamilton8d9ee76e2018-05-29 23:52:52440 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25441 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23442 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23443 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23444 uint64_t largest_received,
445 uint64_t smallest_received,
446 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25447 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
448 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52449 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25450 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23451 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25452 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57453 }
454
zhongyi32569c62016-01-08 02:54:30455 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13456 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
457 const std::string& scheme,
458 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58459 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30460 }
461
462 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13463 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
464 const std::string& scheme,
465 const std::string& path,
466 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50467 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00468 }
469
Ryan Hamilton0239aac2018-05-19 00:03:13470 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56471 return client_maker_.ConnectRequestHeaders(host_port);
472 }
473
Ryan Hamilton0239aac2018-05-19 00:03:13474 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58475 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00476 }
477
zhongyi32569c62016-01-08 02:54:30478 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13479 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
480 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58481 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30482 }
483
Ryan Hamilton8d9ee76e2018-05-29 23:52:52484 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23485 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52486 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05487 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00488 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52489 quic::QuicStreamOffset offset,
490 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58491 return server_maker_.MakeDataPacket(
492 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00493 }
494
Ryan Hamilton8d9ee76e2018-05-29 23:52:52495 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23496 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52497 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36498 bool should_include_version,
499 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52500 quic::QuicStreamOffset offset,
501 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36502 return client_maker_.MakeDataPacket(
503 packet_number, stream_id, should_include_version, fin, offset, data);
504 }
505
Renjied172e812019-01-16 05:12:35506 std::unique_ptr<quic::QuicEncryptedPacket>
507 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23508 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35509 quic::QuicStreamId stream_id,
510 bool should_include_version,
511 bool fin,
512 quic::QuicStreamOffset offset,
513 const std::vector<std::string> data_writes) {
514 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
515 should_include_version,
516 fin, offset, data_writes);
517 }
518
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23520 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56521 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23523 uint64_t largest_received,
524 uint64_t smallest_received,
525 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56526 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52527 quic::QuicStreamOffset offset,
528 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56529 return client_maker_.MakeAckAndDataPacket(
530 packet_number, include_version, stream_id, largest_received,
531 smallest_received, least_unacked, fin, offset, data);
532 }
533
Renjied172e812019-01-16 05:12:35534 std::unique_ptr<quic::QuicEncryptedPacket>
535 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23536 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35537 bool include_version,
538 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23539 uint64_t largest_received,
540 uint64_t smallest_received,
541 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35542 bool fin,
543 quic::QuicStreamOffset offset,
544 const std::vector<std::string> data_writes) {
545 return client_maker_.MakeAckAndMultipleDataFramesPacket(
546 packet_number, include_version, stream_id, largest_received,
547 smallest_received, least_unacked, fin, offset, data_writes);
548 }
549
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23551 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52552 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36553 bool should_include_version,
554 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52555 quic::QuicStreamOffset* offset,
556 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36557 return client_maker_.MakeForceHolDataPacket(
558 packet_number, stream_id, should_include_version, fin, offset, data);
559 }
560
Ryan Hamilton8d9ee76e2018-05-29 23:52:52561 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23562 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52563 quic::QuicStreamId stream_id,
564 bool should_include_version,
565 bool fin,
566 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56567 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
568 should_include_version, fin,
569 std::move(headers), nullptr);
570 }
571
Ryan Hamilton8d9ee76e2018-05-29 23:52:52572 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23573 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52574 quic::QuicStreamId stream_id,
575 bool should_include_version,
576 bool fin,
577 spdy::SpdyHeaderBlock headers,
578 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48579 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
580 should_include_version, fin,
581 std::move(headers), 0, offset);
582 }
583
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23585 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52586 quic::QuicStreamId stream_id,
587 bool should_include_version,
588 bool fin,
589 spdy::SpdyHeaderBlock headers,
590 quic::QuicStreamId parent_stream_id,
591 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56592 return ConstructClientRequestHeadersPacket(
593 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48594 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30595 }
596
Ryan Hamilton8d9ee76e2018-05-29 23:52:52597 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23598 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52599 quic::QuicStreamId stream_id,
600 bool should_include_version,
601 bool fin,
602 RequestPriority request_priority,
603 spdy::SpdyHeaderBlock headers,
604 quic::QuicStreamId parent_stream_id,
605 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13606 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56607 ConvertRequestPriorityToQuicPriority(request_priority);
608 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
609 packet_number, stream_id, should_include_version, fin, priority,
610 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00611 }
612
Ryan Hamilton8d9ee76e2018-05-29 23:52:52613 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25614 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23615 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52616 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25617 bool should_include_version,
618 bool fin,
619 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13620 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52621 quic::QuicStreamId parent_stream_id,
622 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25623 size_t* spdy_headers_frame_length,
624 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13625 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25626 ConvertRequestPriorityToQuicPriority(request_priority);
627 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
628 packet_number, stream_id, should_include_version, fin, priority,
629 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
630 data_writes);
631 }
632
Ryan Hamilton8d9ee76e2018-05-29 23:52:52633 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23634 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52635 quic::QuicStreamId stream_id,
636 bool should_include_version,
637 bool fin,
638 const std::vector<std::string>& data,
639 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27640 return client_maker_.MakeMultipleDataFramesPacket(
641 packet_number, stream_id, should_include_version, fin, offset, data);
642 }
643
Ryan Hamilton8d9ee76e2018-05-29 23:52:52644 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23645 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52646 quic::QuicStreamId stream_id,
647 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13648 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13649 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52650 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13651 QuicTestPacketMaker* maker) {
652 return maker->MakePushPromisePacket(
653 packet_number, stream_id, promised_stream_id, should_include_version,
654 false, std::move(headers), nullptr, offset);
655 }
656
Ryan Hamilton8d9ee76e2018-05-29 23:52:52657 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23658 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52659 quic::QuicStreamId stream_id,
660 bool should_include_version,
661 bool fin,
662 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27663 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
664 should_include_version, fin,
665 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30666 }
667
Ryan Hamilton8d9ee76e2018-05-29 23:52:52668 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23669 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52670 quic::QuicStreamId stream_id,
671 bool should_include_version,
672 bool fin,
673 spdy::SpdyHeaderBlock headers,
674 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58675 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25676 packet_number, stream_id, should_include_version, fin,
677 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30678 }
679
Victor Vasiliev076657c2019-03-12 02:46:43680 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56681 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41682 return "";
683 }
684 quic::HttpEncoder encoder;
685 std::unique_ptr<char[]> buffer;
686 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43687 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41688 }
689
Nick Harper23290b82019-05-02 00:02:56690 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41691 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21692 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05693 session_params_.quic_headers_include_h2_stream_dependency =
694 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00695
mmenke6ddfbea2017-05-31 21:48:41696 session_context_.quic_clock = &clock_;
697 session_context_.quic_random = &random_generator_;
698 session_context_.client_socket_factory = &socket_factory_;
699 session_context_.quic_crypto_client_stream_factory =
700 &crypto_client_stream_factory_;
701 session_context_.host_resolver = &host_resolver_;
702 session_context_.cert_verifier = &cert_verifier_;
703 session_context_.transport_security_state = &transport_security_state_;
704 session_context_.cert_transparency_verifier =
705 cert_transparency_verifier_.get();
706 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
707 session_context_.socket_performance_watcher_factory =
708 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59709 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41710 session_context_.ssl_config_service = ssl_config_service_.get();
711 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
712 session_context_.http_server_properties = &http_server_properties_;
713 session_context_.net_log = net_log_.bound().net_log();
714
715 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12716 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56717 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
718 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00719 }
720
zhongyi86838d52017-06-30 01:19:44721 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21722
bnc691fda62016-08-12 00:43:16723 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19724 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42725 ASSERT_TRUE(response != nullptr);
726 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19727 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
728 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52729 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:56730 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
731 version_.transport_version),
[email protected]aa9b14d2013-05-10 23:45:19732 response->connection_info);
733 }
734
bnc691fda62016-08-12 00:43:16735 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41736 const HttpResponseInfo* response = trans->GetResponseInfo();
737 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37738 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41739 }
740
bnc691fda62016-08-12 00:43:16741 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19742 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42743 ASSERT_TRUE(response != nullptr);
744 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19745 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
746 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52747 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52748 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19749 response->connection_info);
750 }
751
Yixin Wang46a273ec302018-01-23 17:59:56752 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
753 const HttpResponseInfo* response = trans->GetResponseInfo();
754 ASSERT_TRUE(response != nullptr);
755 ASSERT_TRUE(response->headers.get() != nullptr);
756 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
757 EXPECT_TRUE(response->was_fetched_via_spdy);
758 EXPECT_TRUE(response->was_alpn_negotiated);
759 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
760 response->connection_info);
761 }
762
bnc691fda62016-08-12 00:43:16763 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19764 const std::string& expected) {
765 std::string response_data;
bnc691fda62016-08-12 00:43:16766 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19767 EXPECT_EQ(expected, response_data);
768 }
769
bnc691fda62016-08-12 00:43:16770 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19771 TestCompletionCallback callback;
772 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
774 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19775 }
776
777 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16778 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
779 RunTransaction(&trans);
780 CheckWasHttpResponse(&trans);
781 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19782 }
783
tbansalc3308d72016-08-27 10:25:04784 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
785 bool used_proxy,
786 uint16_t port) {
787 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
788 HeadersHandler headers_handler;
789 trans.SetBeforeHeadersSentCallback(
790 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
791 base::Unretained(&headers_handler)));
792 RunTransaction(&trans);
793 CheckWasHttpResponse(&trans);
794 CheckResponsePort(&trans, port);
795 CheckResponseData(&trans, expected);
796 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47797 if (used_proxy) {
798 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
799 } else {
800 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
801 }
tbansalc3308d72016-08-27 10:25:04802 }
803
[email protected]aa9b14d2013-05-10 23:45:19804 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56805 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12806 }
807
bnc62a44f022015-04-02 15:59:41808 void SendRequestAndExpectQuicResponseFromProxyOnPort(
809 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46810 uint16_t port) {
bnc62a44f022015-04-02 15:59:41811 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19812 }
813
814 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27815 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19816 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46817 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21818 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12819 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21820 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44821 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19822 }
823
rchbe69cb902016-02-11 01:10:48824 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27825 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48826 const HostPortPair& alternative) {
827 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46828 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21829 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48830 alternative.port());
831 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21832 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44833 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48834 }
835
[email protected]aa9b14d2013-05-10 23:45:19836 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46837 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34838 const AlternativeServiceInfoVector alternative_service_info_vector =
839 http_server_properties_.GetAlternativeServiceInfos(server);
840 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07841 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54842 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19843 }
844
[email protected]4d590c9c2014-05-02 05:14:33845 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46846 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34847 const AlternativeServiceInfoVector alternative_service_info_vector =
848 http_server_properties_.GetAlternativeServiceInfos(server);
849 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54850 EXPECT_EQ(
851 kProtoQUIC,
852 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23853 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54854 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33855 }
856
[email protected]aa9b14d2013-05-10 23:45:19857 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42858 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30859 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30860 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30861 hanging_data->set_connect_data(hanging_connect);
862 hanging_data_.push_back(std::move(hanging_data));
863 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56864 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19865 }
866
Zhongyi Shia6b68d112018-09-24 07:49:03867 void SetUpTestForRetryConnectionOnAlternateNetwork() {
868 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
869 session_params_.quic_migrate_sessions_early_v2 = true;
870 session_params_.quic_retry_on_alternate_network_before_handshake = true;
871 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
872 MockNetworkChangeNotifier* mock_ncn =
873 scoped_mock_change_notifier_->mock_network_change_notifier();
874 mock_ncn->ForceNetworkHandlesSupported();
875 mock_ncn->SetConnectedNetworksList(
876 {kDefaultNetworkForTests, kNewNetworkForTests});
877 }
878
tbansalc3308d72016-08-27 10:25:04879 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
880 // alternative proxy. Verifies that if the alternative proxy job returns
881 // |error_code|, the request is fetched successfully by the main job.
882 void TestAlternativeProxy(int error_code) {
883 // Use a non-cryptographic scheme for the request URL since this request
884 // will be fetched via proxy with QUIC as the alternative service.
885 request_.url = GURL("http://example.org/");
886 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27887 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04888 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27889 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04890 };
891
Ryan Sleevib8d7ea02018-05-07 20:01:01892 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04893 socket_factory_.AddSocketDataProvider(&quic_data);
894
895 // Main job succeeds and the alternative job fails.
896 // Add data for two requests that will be read by the main job.
897 MockRead http_reads_1[] = {
898 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
900 MockRead(ASYNC, OK)};
901
902 MockRead http_reads_2[] = {
903 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
904 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
905 MockRead(ASYNC, OK)};
906
Ryan Sleevib8d7ea02018-05-07 20:01:01907 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
908 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04909 socket_factory_.AddSocketDataProvider(&http_data_1);
910 socket_factory_.AddSocketDataProvider(&http_data_2);
911 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
912 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
913
914 TestProxyDelegate test_proxy_delegate;
915 // Proxy URL is different from the request URL.
916 test_proxy_delegate.set_alternative_proxy_server(
917 ProxyServer::FromPacString("QUIC myproxy.org:443"));
918
Lily Houghton8c2f97d2018-01-22 05:06:59919 proxy_resolution_service_ =
920 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49921 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52922 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04923
924 CreateSession();
925 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
926
927 // The first request should be fetched via the HTTPS proxy.
928 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
929
Reilly Grant89a7e512018-01-20 01:57:16930 // Since the main job succeeded only the alternative proxy server should be
931 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59932 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16933 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04934
935 // Verify that the second request completes successfully, and the
936 // alternative proxy server job is not started.
937 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
938 }
939
Fan Yang32c5a112018-12-10 20:06:33940 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56941 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
942 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36943 }
944
Fan Yang32c5a112018-12-10 20:06:33945 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56946 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
947 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36948 }
949
Bence Béky230ac612017-08-30 19:17:08950 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49951 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08952 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49953 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08954 }
955
Nick Harper23290b82019-05-02 00:02:56956 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05957 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56958 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01959 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52960 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17961 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58962 QuicTestPacketMaker client_maker_;
963 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09964 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42965 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00966 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56967 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05968 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43969 MockHostResolver host_resolver_;
970 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11971 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42972 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23973 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38974 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07975 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59976 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42977 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07978 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41979 HttpNetworkSession::Params session_params_;
980 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19981 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51982 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42983 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56984 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03985 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12986
987 private:
988 void SendRequestAndExpectQuicResponseMaybeFromProxy(
989 const std::string& expected,
bnc62a44f022015-04-02 15:59:41990 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46991 uint16_t port) {
bnc691fda62016-08-12 00:43:16992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09993 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16994 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09995 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
996 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16997 RunTransaction(&trans);
998 CheckWasQuicResponse(&trans);
999 CheckResponsePort(&trans, port);
1000 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:091001 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471002 if (used_proxy) {
1003 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1004 } else {
1005 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1006 }
tbansal7cec3812015-02-05 21:25:121007 }
[email protected]61a527782013-02-21 03:58:001008};
1009
Victor Costane635086f2019-01-27 05:20:301010INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231011 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051012 QuicNetworkTransactionTest,
Victor Vasiliev5d6cdc22019-05-28 20:37:431013 ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
Nick Harper23290b82019-05-02 00:02:561014 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201015
Ryan Hamiltona64a5bcf2017-11-30 07:35:281016TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481017 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281018 base::HistogramTester histograms;
1019 session_params_.origins_to_force_quic_on.insert(
1020 HostPortPair::FromString("mail.example.org:443"));
1021 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271022 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281023
Ryan Hamiltonabad59e2019-06-06 04:02:591024 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521025 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281026 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431027 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281028 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1029 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1030 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1031
1032 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1033
1034 CreateSession();
1035
1036 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1037 TestCompletionCallback callback;
1038 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1039 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1040 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1041
1042 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1043 -ERR_INTERNET_DISCONNECTED, 1);
1044 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1045 -ERR_INTERNET_DISCONNECTED, 1);
1046}
1047
1048TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481049 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281050 base::HistogramTester histograms;
1051 session_params_.origins_to_force_quic_on.insert(
1052 HostPortPair::FromString("mail.example.org:443"));
1053 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271054 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281055
Ryan Hamiltonabad59e2019-06-06 04:02:591056 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521057 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281058 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431059 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281060 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1061 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1062 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1063
1064 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1065
1066 CreateSession();
1067
1068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1069 TestCompletionCallback callback;
1070 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1072 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1073
1074 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1075 -ERR_INTERNET_DISCONNECTED, 1);
1076 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1077 -ERR_INTERNET_DISCONNECTED, 1);
1078}
1079
tbansal180587c2017-02-16 15:13:231080TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411081 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231082 HostPortPair::FromString("mail.example.org:443"));
1083
Ryan Hamiltonabad59e2019-06-06 04:02:591084 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521085 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361086 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431087 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1088 mock_quic_data.AddWrite(
1089 SYNCHRONOUS,
1090 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331091 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431092 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431093 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331094 ASYNC, ConstructServerResponseHeadersPacket(
1095 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1096 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431097 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331098 mock_quic_data.AddRead(
1099 ASYNC, ConstructServerDataPacket(
1100 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411101 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431102 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231103 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1104
1105 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1106
1107 CreateSession();
1108 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1109
1110 EXPECT_FALSE(
1111 test_socket_performance_watcher_factory_.rtt_notification_received());
1112 SendRequestAndExpectQuicResponse("hello!");
1113 EXPECT_TRUE(
1114 test_socket_performance_watcher_factory_.rtt_notification_received());
1115}
1116
1117TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411118 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231119 HostPortPair::FromString("mail.example.org:443"));
1120
Ryan Hamiltonabad59e2019-06-06 04:02:591121 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521122 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361123 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431124 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1125 mock_quic_data.AddWrite(
1126 SYNCHRONOUS,
1127 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331128 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431129 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431130 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331131 ASYNC, ConstructServerResponseHeadersPacket(
1132 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1133 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431134 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331135 mock_quic_data.AddRead(
1136 ASYNC, ConstructServerDataPacket(
1137 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411138 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431139 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231140 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1141
1142 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1143
1144 CreateSession();
1145 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1146
1147 EXPECT_FALSE(
1148 test_socket_performance_watcher_factory_.rtt_notification_received());
1149 SendRequestAndExpectQuicResponse("hello!");
1150 EXPECT_FALSE(
1151 test_socket_performance_watcher_factory_.rtt_notification_received());
1152}
1153
[email protected]1e960032013-12-20 19:00:201154TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411155 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571156 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471157
Ryan Hamiltonabad59e2019-06-06 04:02:591158 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521159 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361160 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431161 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1162 mock_quic_data.AddWrite(
1163 SYNCHRONOUS,
1164 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331165 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431166 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431167 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331168 ASYNC, ConstructServerResponseHeadersPacket(
1169 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1170 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431171 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331172 mock_quic_data.AddRead(
1173 ASYNC, ConstructServerDataPacket(
1174 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411175 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431176 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591177 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471178
rcha5399e02015-04-21 19:32:041179 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471180
[email protected]4dca587c2013-03-07 16:54:471181 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471182
[email protected]aa9b14d2013-05-10 23:45:191183 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471184
[email protected]98b20ce2013-05-10 05:55:261185 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461186 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191187 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261188 EXPECT_LT(0u, entries.size());
1189
1190 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291191 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001192 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1193 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261194 EXPECT_LT(0, pos);
1195
rchfd527212015-08-25 00:41:261196 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291197 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261198 entries, 0,
mikecirone8b85c432016-09-08 19:11:001199 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1200 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261201 EXPECT_LT(0, pos);
1202
Eric Romanaefc98c2018-12-18 21:38:011203 int packet_number;
1204 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1205 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261206
rchfd527212015-08-25 00:41:261207 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1208 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001209 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1210 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261211 EXPECT_LT(0, pos);
1212
[email protected]98b20ce2013-05-10 05:55:261213 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291214 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001215 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1216 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261217 EXPECT_LT(0, pos);
1218
1219 int log_stream_id;
1220 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Nick Harper23290b82019-05-02 00:02:561221 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
Fan Yang7c68f632018-11-06 03:05:381222 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471223}
1224
rchbd089ab2017-05-26 23:05:041225TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411226 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041227 HostPortPair::FromString("mail.example.org:443"));
1228
Ryan Hamiltonabad59e2019-06-06 04:02:591229 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521230 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041231 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431232 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1233 mock_quic_data.AddWrite(
1234 SYNCHRONOUS,
1235 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331236 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431237 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131238 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041239 response_headers["key1"] = std::string(30000, 'A');
1240 response_headers["key2"] = std::string(30000, 'A');
1241 response_headers["key3"] = std::string(30000, 'A');
1242 response_headers["key4"] = std::string(30000, 'A');
1243 response_headers["key5"] = std::string(30000, 'A');
1244 response_headers["key6"] = std::string(30000, 'A');
1245 response_headers["key7"] = std::string(30000, 'A');
1246 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331247 spdy::SpdyHeadersIR headers_frame(
1248 GetNthClientInitiatedBidirectionalStreamId(0),
1249 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131250 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1251 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041252 response_framer.SerializeFrame(headers_frame);
1253
Fan Yangac867502019-01-28 21:10:231254 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041255 size_t chunk_size = 1200;
1256 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1257 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431258 mock_quic_data.AddRead(
Nick Harper23290b82019-05-02 00:02:561259 ASYNC,
1260 ConstructServerDataPacket(
1261 packet_number++,
1262 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1263 false, false, offset,
1264 base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041265 }
1266
Victor Vasiliev076657c2019-03-12 02:46:431267 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041268 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331269 ASYNC, ConstructServerDataPacket(
1270 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411271 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041272 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431273 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1274 mock_quic_data.AddWrite(ASYNC,
1275 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041276
1277 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1278
1279 CreateSession();
1280
1281 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421282 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1283 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041284}
1285
1286TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481287 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411288 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041289 HostPortPair::FromString("mail.example.org:443"));
1290
Ryan Hamiltonabad59e2019-06-06 04:02:591291 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521292 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041293 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431294 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1295 mock_quic_data.AddWrite(
1296 SYNCHRONOUS,
1297 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331298 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431299 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131300 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041301 response_headers["key1"] = std::string(30000, 'A');
1302 response_headers["key2"] = std::string(30000, 'A');
1303 response_headers["key3"] = std::string(30000, 'A');
1304 response_headers["key4"] = std::string(30000, 'A');
1305 response_headers["key5"] = std::string(30000, 'A');
1306 response_headers["key6"] = std::string(30000, 'A');
1307 response_headers["key7"] = std::string(30000, 'A');
1308 response_headers["key8"] = std::string(30000, 'A');
1309 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331310 spdy::SpdyHeadersIR headers_frame(
1311 GetNthClientInitiatedBidirectionalStreamId(0),
1312 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131313 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1314 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041315 response_framer.SerializeFrame(headers_frame);
1316
Fan Yangac867502019-01-28 21:10:231317 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041318 size_t chunk_size = 1200;
1319 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1320 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431321 mock_quic_data.AddRead(
Nick Harper23290b82019-05-02 00:02:561322 ASYNC,
1323 ConstructServerDataPacket(
1324 packet_number++,
1325 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1326 false, false, offset,
1327 base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041328 }
1329
Victor Vasiliev076657c2019-03-12 02:46:431330 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411331
rchbd089ab2017-05-26 23:05:041332 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331333 ASYNC, ConstructServerDataPacket(
1334 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411335 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041336 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431337 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1338 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331339 ASYNC, ConstructClientAckAndRstPacket(
1340 4, GetNthClientInitiatedBidirectionalStreamId(0),
1341 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041342
1343 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1344
1345 CreateSession();
1346
1347 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1348 TestCompletionCallback callback;
1349 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1350 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1351 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1352}
1353
rcha2bd44b2016-07-02 00:42:551354TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411355 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551356
Ryan Hamilton9835e662018-08-02 05:36:271357 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551358
Ryan Hamiltonabad59e2019-06-06 04:02:591359 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521360 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361361 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431362 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1363 mock_quic_data.AddWrite(
1364 SYNCHRONOUS,
1365 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331366 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431367 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431368 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331369 ASYNC, ConstructServerResponseHeadersPacket(
1370 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1371 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431372 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331373 mock_quic_data.AddRead(
1374 ASYNC, ConstructServerDataPacket(
1375 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411376 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431377 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551378 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1379
1380 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1381
1382 CreateSession();
1383
1384 SendRequestAndExpectQuicResponse("hello!");
1385 EXPECT_TRUE(
1386 test_socket_performance_watcher_factory_.rtt_notification_received());
1387}
1388
[email protected]cf3e3cd62014-02-05 16:16:161389TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411390 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591391 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491392 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161393
Ryan Hamiltonabad59e2019-06-06 04:02:591394 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521395 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361396 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431397 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1398 mock_quic_data.AddWrite(
1399 SYNCHRONOUS,
1400 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331401 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431402 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431403 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331404 ASYNC, ConstructServerResponseHeadersPacket(
1405 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1406 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431407 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331408 mock_quic_data.AddRead(
1409 ASYNC, ConstructServerDataPacket(
1410 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411411 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431412 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501413 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591414 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161415
rcha5399e02015-04-21 19:32:041416 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161417
tbansal0f56a39a2016-04-07 22:03:381418 EXPECT_FALSE(
1419 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161420 // There is no need to set up an alternate protocol job, because
1421 // no attempt will be made to speak to the proxy over TCP.
1422
rch9ae5b3b2016-02-11 00:36:291423 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161424 CreateSession();
1425
bnc62a44f022015-04-02 15:59:411426 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381427 EXPECT_TRUE(
1428 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161429}
1430
bnc313ba9c2015-06-11 15:42:311431// Regression test for https://crbug.com/492458. Test that for an HTTP
1432// connection through a QUIC proxy, the certificate exhibited by the proxy is
1433// checked against the proxy hostname, not the origin hostname.
1434TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291435 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311436 const std::string proxy_host = "www.example.org";
1437
mmenke6ddfbea2017-05-31 21:48:411438 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591439 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491440 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311441
alyssar2adf3ac2016-05-03 17:12:581442 client_maker_.set_hostname(origin_host);
Ryan Hamiltonabad59e2019-06-06 04:02:591443 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521444 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361445 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431446 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1447 mock_quic_data.AddWrite(
1448 SYNCHRONOUS,
1449 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331450 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431451 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431452 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331453 ASYNC, ConstructServerResponseHeadersPacket(
1454 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1455 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431456 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331457 mock_quic_data.AddRead(
1458 ASYNC, ConstructServerDataPacket(
1459 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411460 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431461 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501462 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591463 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311464 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1465
1466 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291467 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311468 ASSERT_TRUE(cert.get());
1469 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241470 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1471 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311472 ProofVerifyDetailsChromium verify_details;
1473 verify_details.cert_verify_result.verified_cert = cert;
1474 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561475 ProofVerifyDetailsChromium verify_details2;
1476 verify_details2.cert_verify_result.verified_cert = cert;
1477 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311478
1479 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091480 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321481 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271482 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311483 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1484}
1485
rchbe69cb902016-02-11 01:10:481486TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341487 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481488 HostPortPair origin("www.example.org", 443);
1489 HostPortPair alternative("mail.example.org", 443);
1490
1491 base::FilePath certs_dir = GetTestCertsDirectory();
1492 scoped_refptr<X509Certificate> cert(
1493 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1494 ASSERT_TRUE(cert.get());
1495 // TODO(rch): the connection should be "to" the origin, so if the cert is
1496 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241497 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1498 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481499 ProofVerifyDetailsChromium verify_details;
1500 verify_details.cert_verify_result.verified_cert = cert;
1501 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1502
alyssar2adf3ac2016-05-03 17:12:581503 client_maker_.set_hostname(origin.host());
Ryan Hamiltonabad59e2019-06-06 04:02:591504 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521505 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361506 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431507 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1508 mock_quic_data.AddWrite(
1509 SYNCHRONOUS,
1510 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331511 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431512 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431513 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331514 ASYNC, ConstructServerResponseHeadersPacket(
1515 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1516 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431517 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331518 mock_quic_data.AddRead(
1519 ASYNC, ConstructServerDataPacket(
1520 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411521 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431522 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481523 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1524 mock_quic_data.AddRead(ASYNC, 0);
1525 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1526
1527 request_.url = GURL("https://" + origin.host());
1528 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271529 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091530 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321531 CreateSession();
rchbe69cb902016-02-11 01:10:481532
1533 SendRequestAndExpectQuicResponse("hello!");
1534}
1535
zhongyief3f4ce52017-07-05 23:53:281536TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561537 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281538 // Add support for another QUIC version besides |version_|. Also find a
1539 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561540 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281541 if (version == version_)
1542 continue;
1543 if (supported_versions_.size() != 2) {
1544 supported_versions_.push_back(version);
1545 continue;
1546 }
1547 unsupported_version = version;
1548 break;
1549 }
Nick Harper23290b82019-05-02 00:02:561550 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281551
1552 // Set up alternative service to use QUIC with a version that is not
1553 // supported.
1554 url::SchemeHostPort server(request_.url);
1555 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1556 443);
1557 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1558 http_server_properties_.SetQuicAlternativeService(
1559 server, alternative_service, expiration, {unsupported_version});
1560
1561 AlternativeServiceInfoVector alt_svc_info_vector =
1562 http_server_properties_.GetAlternativeServiceInfos(server);
1563 EXPECT_EQ(1u, alt_svc_info_vector.size());
1564 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1565 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1566 EXPECT_EQ(unsupported_version,
1567 alt_svc_info_vector[0].advertised_versions()[0]);
1568
1569 // First request should still be sent via TCP as the QUIC version advertised
1570 // in the stored AlternativeService is not supported by the client. However,
1571 // the response from the server will advertise new Alt-Svc with supported
1572 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061573 quic::ParsedQuicVersionVector versions;
1574 for (quic::QuicTransportVersion version :
1575 quic::AllSupportedTransportVersions()) {
1576 versions.push_back(
1577 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1578 }
zhongyief3f4ce52017-07-05 23:53:281579 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061580 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281581 std::string altsvc_header =
1582 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1583 advertised_versions_list_str.c_str());
1584 MockRead http_reads[] = {
1585 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1586 MockRead("hello world"),
1587 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1588 MockRead(ASYNC, OK)};
1589
Ryan Sleevib8d7ea02018-05-07 20:01:011590 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281591 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081592 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281593 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1594
1595 // Second request should be sent via QUIC as a new list of verions supported
1596 // by the client has been advertised by the server.
Ryan Hamiltonabad59e2019-06-06 04:02:591597 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521598 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281599 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431600 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1601 mock_quic_data.AddWrite(
1602 SYNCHRONOUS,
1603 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331604 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431605 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431606 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331607 ASYNC, ConstructServerResponseHeadersPacket(
1608 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1609 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431610 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331611 mock_quic_data.AddRead(
1612 ASYNC, ConstructServerDataPacket(
1613 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411614 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431615 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281616 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1617 mock_quic_data.AddRead(ASYNC, 0); // EOF
1618
1619 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1620
1621 AddHangingNonAlternateProtocolSocketData();
1622
1623 CreateSession(supported_versions_);
1624
1625 SendRequestAndExpectHttpResponse("hello world");
1626 SendRequestAndExpectQuicResponse("hello!");
1627
1628 // Check alternative service list is updated with new versions.
1629 alt_svc_info_vector =
1630 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1631 EXPECT_EQ(1u, alt_svc_info_vector.size());
1632 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1633 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1634 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561635 std::sort(
1636 supported_versions_.begin(), supported_versions_.end(),
1637 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1638 return a.transport_version < b.transport_version;
1639 });
zhongyief3f4ce52017-07-05 23:53:281640 EXPECT_EQ(supported_versions_[0],
1641 alt_svc_info_vector[0].advertised_versions()[0]);
1642 EXPECT_EQ(supported_versions_[1],
1643 alt_svc_info_vector[0].advertised_versions()[1]);
1644}
1645
bncaccd4962017-04-06 21:00:261646// Regression test for https://crbug.com/546991.
1647// The server might not be able to serve a request on an alternative connection,
1648// and might send a 421 Misdirected Request response status to indicate this.
1649// HttpNetworkTransaction should reset the request and retry without using
1650// alternative services.
1651TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1652 // Set up alternative service to use QUIC.
1653 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1654 // that overrides |enable_alternative_services|.
1655 url::SchemeHostPort server(request_.url);
1656 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1657 443);
1658 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211659 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441660 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261661
davidbena4449722017-05-05 23:30:531662 // First try: The alternative job uses QUIC and reports an HTTP 421
1663 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1664 // paused at Connect(), so it will never exit the socket pool. This ensures
1665 // that the alternate job always wins the race and keeps whether the
1666 // |http_data| exits the socket pool before the main job is aborted
1667 // deterministic. The first main job gets aborted without the socket pool ever
1668 // dispensing the socket, making it available for the second try.
Ryan Hamiltonabad59e2019-06-06 04:02:591669 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521670 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361671 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431672 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1673 mock_quic_data.AddWrite(
1674 SYNCHRONOUS,
1675 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331676 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431677 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331678 mock_quic_data.AddRead(
1679 ASYNC, ConstructServerResponseHeadersPacket(
1680 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1681 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261682 mock_quic_data.AddRead(ASYNC, OK);
1683 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1684
davidbena4449722017-05-05 23:30:531685 // Second try: The main job uses TCP, and there is no alternate job. Once the
1686 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1687 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261688 // Note that if there was an alternative QUIC Job created for the second try,
1689 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1690 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531691 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1692 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1693 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1694 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1695 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1696 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011697 reads, writes);
bncaccd4962017-04-06 21:00:261698 socket_factory_.AddSocketDataProvider(&http_data);
1699 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1700
bncaccd4962017-04-06 21:00:261701 CreateSession();
1702 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531703
1704 // Run until |mock_quic_data| has failed and |http_data| has paused.
1705 TestCompletionCallback callback;
1706 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1707 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1708 base::RunLoop().RunUntilIdle();
1709
1710 // |mock_quic_data| must have run to completion.
1711 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1712 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1713
1714 // Now that the QUIC data has been consumed, unblock |http_data|.
1715 http_data.socket()->OnConnectComplete(MockConnect());
1716
1717 // The retry logic must hide the 421 status. The transaction succeeds on
1718 // |http_data|.
1719 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261720 CheckWasHttpResponse(&trans);
1721 CheckResponsePort(&trans, 443);
1722 CheckResponseData(&trans, "hello!");
1723}
1724
[email protected]1e960032013-12-20 19:00:201725TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411726 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571727 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301728
Ryan Hamiltonabad59e2019-06-06 04:02:591729 MockQuicData mock_quic_data1(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521730 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361731 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431732 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401733 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Ryan Hamiltonabad59e2019-06-06 04:02:591734 MockQuicData mock_quic_data2(version_);
fayang3bcb8b502016-12-07 21:44:371735 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361736 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431737 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301738 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401739 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431740 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401741
1742 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1743 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301744
1745 CreateSession();
1746
tbansal0f56a39a2016-04-07 22:03:381747 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401748 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401750 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161751 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011752 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1753 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381754 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531755
1756 NetErrorDetails details;
1757 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521758 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401759 }
[email protected]cebe3282013-05-22 23:49:301760}
1761
tbansalc8a94ea2015-11-02 23:58:511762TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1763 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411764 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571765 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511766
1767 MockRead http_reads[] = {
1768 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1769 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1770 MockRead(ASYNC, OK)};
1771
Ryan Sleevib8d7ea02018-05-07 20:01:011772 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511773 socket_factory_.AddSocketDataProvider(&data);
1774 SSLSocketDataProvider ssl(ASYNC, OK);
1775 socket_factory_.AddSSLSocketDataProvider(&ssl);
1776
1777 CreateSession();
1778
1779 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381780 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511781}
1782
bncc958faa2015-07-31 18:14:521783TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521784 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561785 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1786 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521787 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1788 MockRead(ASYNC, OK)};
1789
Ryan Sleevib8d7ea02018-05-07 20:01:011790 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521791 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081792 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561793 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521794
Ryan Hamiltonabad59e2019-06-06 04:02:591795 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521796 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361797 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431798 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1799 mock_quic_data.AddWrite(
1800 SYNCHRONOUS,
1801 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331802 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431803 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431804 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331805 ASYNC, ConstructServerResponseHeadersPacket(
1806 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1807 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431808 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331809 mock_quic_data.AddRead(
1810 ASYNC, ConstructServerDataPacket(
1811 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411812 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431813 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521814 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591815 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521816
1817 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1818
rtennetib8e80fb2016-05-16 00:12:091819 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321820 CreateSession();
bncc958faa2015-07-31 18:14:521821
1822 SendRequestAndExpectHttpResponse("hello world");
1823 SendRequestAndExpectQuicResponse("hello!");
1824}
1825
zhongyia00ca012017-07-06 23:36:391826TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1827 // Both server advertises and client supports two QUIC versions.
1828 // Only |version_| is advertised and supported.
1829 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1830 // PacketMakers are using |version_|.
1831
1832 // Add support for another QUIC version besides |version_| on the client side.
1833 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:561834 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
1835 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391836 if (version == version_)
1837 continue;
1838 if (supported_versions_.size() != 2) {
1839 supported_versions_.push_back(version);
1840 continue;
1841 }
1842 advertised_version_2 = version;
1843 break;
1844 }
Nick Harper23290b82019-05-02 00:02:561845 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391846
Nick Harper23290b82019-05-02 00:02:561847 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1848 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1849 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391850
1851 MockRead http_reads[] = {
1852 MockRead("HTTP/1.1 200 OK\r\n"),
1853 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1854 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1855 MockRead(ASYNC, OK)};
1856
Ryan Sleevib8d7ea02018-05-07 20:01:011857 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391858 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081859 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391860 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1861
Ryan Hamiltonabad59e2019-06-06 04:02:591862 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521863 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391864 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431865 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1866 mock_quic_data.AddWrite(
1867 SYNCHRONOUS,
1868 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331869 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431870 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431871 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331872 ASYNC, ConstructServerResponseHeadersPacket(
1873 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1874 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431875 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331876 mock_quic_data.AddRead(
1877 ASYNC, ConstructServerDataPacket(
1878 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411879 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431880 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391881 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1882 mock_quic_data.AddRead(ASYNC, 0); // EOF
1883
1884 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1885
1886 AddHangingNonAlternateProtocolSocketData();
1887 CreateSession(supported_versions_);
1888
1889 SendRequestAndExpectHttpResponse("hello world");
1890 SendRequestAndExpectQuicResponse("hello!");
1891}
1892
1893TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1894 // Client and server mutually support more than one QUIC_VERSION.
1895 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1896 // which is verified as the PacketMakers are using |version_|.
1897
Nick Harper23290b82019-05-02 00:02:561898 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
1899 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391900 if (version == version_)
1901 continue;
1902 common_version_2 = version;
1903 break;
1904 }
Nick Harper23290b82019-05-02 00:02:561905 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391906
1907 supported_versions_.push_back(
1908 common_version_2); // Supported but unpreferred.
1909
1910 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:561911 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1912 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391913
1914 MockRead http_reads[] = {
1915 MockRead("HTTP/1.1 200 OK\r\n"),
1916 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1917 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1918 MockRead(ASYNC, OK)};
1919
Ryan Sleevib8d7ea02018-05-07 20:01:011920 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391921 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081922 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391923 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1924
Ryan Hamiltonabad59e2019-06-06 04:02:591925 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521926 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391927 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431928 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1929 mock_quic_data.AddWrite(
1930 SYNCHRONOUS,
1931 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331932 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431933 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431934 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331935 ASYNC, ConstructServerResponseHeadersPacket(
1936 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1937 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431938 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331939 mock_quic_data.AddRead(
1940 ASYNC, ConstructServerDataPacket(
1941 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411942 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431943 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391944 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1945 mock_quic_data.AddRead(ASYNC, 0); // EOF
1946
1947 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1948
1949 AddHangingNonAlternateProtocolSocketData();
1950 CreateSession(supported_versions_);
1951
1952 SendRequestAndExpectHttpResponse("hello world");
1953 SendRequestAndExpectQuicResponse("hello!");
1954}
1955
rchf47265dc2016-03-21 21:33:121956TEST_P(QuicNetworkTransactionTest,
1957 UseAlternativeServiceWithProbabilityForQuic) {
1958 MockRead http_reads[] = {
1959 MockRead("HTTP/1.1 200 OK\r\n"),
1960 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1961 MockRead("hello world"),
1962 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1963 MockRead(ASYNC, OK)};
1964
Ryan Sleevib8d7ea02018-05-07 20:01:011965 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121966 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081967 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121968 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1969
Ryan Hamiltonabad59e2019-06-06 04:02:591970 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521971 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361972 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431973 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1974 mock_quic_data.AddWrite(
1975 SYNCHRONOUS,
1976 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331977 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431978 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431979 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331980 ASYNC, ConstructServerResponseHeadersPacket(
1981 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1982 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431983 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331984 mock_quic_data.AddRead(
1985 ASYNC, ConstructServerDataPacket(
1986 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411987 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431988 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121989 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1990 mock_quic_data.AddRead(ASYNC, 0); // EOF
1991
1992 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1993
rtennetib8e80fb2016-05-16 00:12:091994 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121995 CreateSession();
1996
1997 SendRequestAndExpectHttpResponse("hello world");
1998 SendRequestAndExpectQuicResponse("hello!");
1999}
2000
zhongyi3d4a55e72016-04-22 20:36:462001TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2002 MockRead http_reads[] = {
2003 MockRead("HTTP/1.1 200 OK\r\n"),
2004 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2005 MockRead("hello world"),
2006 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2007 MockRead(ASYNC, OK)};
2008
Ryan Sleevib8d7ea02018-05-07 20:01:012009 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462010 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082011 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462012 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2013
2014 CreateSession();
bncb26024382016-06-29 02:39:452015 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462016 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452017 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462018 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402019 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462020 session_->http_server_properties();
2021 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2022 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2023 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462024 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342025 2u,
2026 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452027 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342028 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462029}
2030
2031TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2032 MockRead http_reads[] = {
2033 MockRead("HTTP/1.1 200 OK\r\n"),
2034 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2035 MockRead("hello world"),
2036 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2037 MockRead(ASYNC, OK)};
2038
Ryan Sleevib8d7ea02018-05-07 20:01:012039 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082040 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462041
2042 socket_factory_.AddSocketDataProvider(&http_data);
2043 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2044 socket_factory_.AddSocketDataProvider(&http_data);
2045 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2046
2047 CreateSession();
2048
2049 // Send https request and set alternative services if response header
2050 // advertises alternative service for mail.example.org.
2051 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402052 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462053 session_->http_server_properties();
2054
2055 const url::SchemeHostPort https_server(request_.url);
2056 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342057 EXPECT_EQ(
2058 2u,
2059 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462060
2061 // Send http request to the same origin but with diffrent scheme, should not
2062 // use QUIC.
2063 request_.url = GURL("http://mail.example.org:443");
2064 SendRequestAndExpectHttpResponse("hello world");
2065}
2066
zhongyie537a002017-06-27 16:48:212067TEST_P(QuicNetworkTransactionTest,
2068 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442069 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562070 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442071 if (version == version_)
2072 continue;
2073 supported_versions_.push_back(version);
2074 break;
2075 }
2076
Ryan Hamilton8380c652019-06-04 02:25:062077 quic::ParsedQuicVersionVector versions;
2078 for (quic::QuicTransportVersion version :
2079 quic::AllSupportedTransportVersions()) {
2080 versions.push_back(
2081 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2082 }
zhongyie537a002017-06-27 16:48:212083 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062084 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212085 std::string altsvc_header =
2086 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2087 advertised_versions_list_str.c_str());
2088 MockRead http_reads[] = {
2089 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2090 MockRead("hello world"),
2091 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2092 MockRead(ASYNC, OK)};
2093
Ryan Sleevib8d7ea02018-05-07 20:01:012094 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212095 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082096 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212097 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2098
Ryan Hamiltonabad59e2019-06-06 04:02:592099 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522100 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212101 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432102 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2103 mock_quic_data.AddWrite(
2104 SYNCHRONOUS,
2105 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332106 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432107 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432108 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332109 ASYNC, ConstructServerResponseHeadersPacket(
2110 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2111 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432112 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332113 mock_quic_data.AddRead(
2114 ASYNC, ConstructServerDataPacket(
2115 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412116 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432117 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212118 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2119 mock_quic_data.AddRead(ASYNC, 0); // EOF
2120
2121 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2122
2123 AddHangingNonAlternateProtocolSocketData();
2124
zhongyi86838d52017-06-30 01:19:442125 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212126
2127 SendRequestAndExpectHttpResponse("hello world");
2128 SendRequestAndExpectQuicResponse("hello!");
2129
2130 // Check alternative service is set with only mutually supported versions.
2131 const url::SchemeHostPort https_server(request_.url);
2132 const AlternativeServiceInfoVector alt_svc_info_vector =
2133 session_->http_server_properties()->GetAlternativeServiceInfos(
2134 https_server);
2135 EXPECT_EQ(1u, alt_svc_info_vector.size());
2136 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2137 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2138 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562139 std::sort(
2140 supported_versions_.begin(), supported_versions_.end(),
2141 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2142 return a.transport_version < b.transport_version;
2143 });
zhongyi86838d52017-06-30 01:19:442144 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212145 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442146 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212147 alt_svc_info_vector[0].advertised_versions()[1]);
2148}
2149
danzh3134c2562016-08-12 14:07:522150TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562151 std::string altsvc_header = base::StringPrintf(
2152 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072153 MockRead http_reads[] = {
2154 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2155 MockRead("hello world"),
2156 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2157 MockRead(ASYNC, OK)};
2158
Ryan Sleevib8d7ea02018-05-07 20:01:012159 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072160 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082161 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072162 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2163
Ryan Hamiltonabad59e2019-06-06 04:02:592164 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522165 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362166 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432167 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2168 mock_quic_data.AddWrite(
2169 SYNCHRONOUS,
2170 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332171 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432172 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432173 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332174 ASYNC, ConstructServerResponseHeadersPacket(
2175 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2176 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432177 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332178 mock_quic_data.AddRead(
2179 ASYNC, ConstructServerDataPacket(
2180 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412181 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432182 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072183 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592184 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072185
2186 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2187
rtennetib8e80fb2016-05-16 00:12:092188 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322189 CreateSession();
bnc8be55ebb2015-10-30 14:12:072190
2191 SendRequestAndExpectHttpResponse("hello world");
2192 SendRequestAndExpectQuicResponse("hello!");
2193}
2194
zhongyi6b5a3892016-03-12 04:46:202195TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562196 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092197 // Not available under version 99
2198 return;
2199 }
Ryan Hamiltonabad59e2019-06-06 04:02:592200 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522201 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362202 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432203 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2204 mock_quic_data.AddWrite(
2205 SYNCHRONOUS,
2206 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332207 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432208 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332209 mock_quic_data.AddRead(
2210 ASYNC, ConstructServerResponseHeadersPacket(
2211 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2212 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202213 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522214 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432215 mock_quic_data.AddRead(SYNCHRONOUS,
2216 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522217 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432218 "connection migration with port change only"));
2219 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432220 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332221 mock_quic_data.AddRead(
2222 SYNCHRONOUS, ConstructServerDataPacket(
2223 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412224 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332225 mock_quic_data.AddWrite(SYNCHRONOUS,
2226 ConstructClientAckAndRstPacket(
2227 4, GetNthClientInitiatedBidirectionalStreamId(0),
2228 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202229 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2230 mock_quic_data.AddRead(ASYNC, 0); // EOF
2231
2232 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2233
2234 // The non-alternate protocol job needs to hang in order to guarantee that
2235 // the alternate-protocol job will "win".
2236 AddHangingNonAlternateProtocolSocketData();
2237
2238 // In order for a new QUIC session to be established via alternate-protocol
2239 // without racing an HTTP connection, we need the host resolution to happen
2240 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2241 // connection to the the server, in this test we require confirmation
2242 // before encrypting so the HTTP job will still start.
2243 host_resolver_.set_synchronous_mode(true);
2244 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2245 "");
zhongyi6b5a3892016-03-12 04:46:202246
2247 CreateSession();
2248 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272249 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202250
bnc691fda62016-08-12 00:43:162251 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202252 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362253 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202255
2256 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522257 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012258 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202259
2260 // Check whether this transaction is correctly marked as received a go-away
2261 // because of migrating port.
2262 NetErrorDetails details;
2263 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162264 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202265 EXPECT_TRUE(details.quic_port_migration_detected);
2266}
2267
Zhongyi Shia6b68d112018-09-24 07:49:032268// This test verifies that a new QUIC connection will be attempted on the
2269// alternate network if the original QUIC connection fails with idle timeout
2270// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2271// alternate network as well, QUIC is marked as broken and the brokenness will
2272// not expire when default network changes.
2273TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2274 SetUpTestForRetryConnectionOnAlternateNetwork();
2275
2276 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032277 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032278
2279 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592280 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032281 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2282 int packet_num = 1;
2283 quic_data.AddWrite(SYNCHRONOUS,
2284 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2285 // Retranmit the handshake messages.
2286 quic_data.AddWrite(SYNCHRONOUS,
2287 client_maker_.MakeDummyCHLOPacket(packet_num++));
2288 quic_data.AddWrite(SYNCHRONOUS,
2289 client_maker_.MakeDummyCHLOPacket(packet_num++));
2290 quic_data.AddWrite(SYNCHRONOUS,
2291 client_maker_.MakeDummyCHLOPacket(packet_num++));
2292 quic_data.AddWrite(SYNCHRONOUS,
2293 client_maker_.MakeDummyCHLOPacket(packet_num++));
2294 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562295 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032296 quic_data.AddWrite(SYNCHRONOUS,
2297 client_maker_.MakeDummyCHLOPacket(packet_num++));
2298 }
2299 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2300 quic_data.AddWrite(SYNCHRONOUS,
2301 client_maker_.MakeConnectionClosePacket(
2302 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2303 "No recent network activity."));
2304 quic_data.AddSocketDataToFactory(&socket_factory_);
2305
2306 // Add successful TCP data so that TCP job will succeed.
2307 MockWrite http_writes[] = {
2308 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2309 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2310 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2311
2312 MockRead http_reads[] = {
2313 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2314 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2315 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2316 SequencedSocketData http_data(http_reads, http_writes);
2317 socket_factory_.AddSocketDataProvider(&http_data);
2318 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2319
2320 // Add data for the second QUIC connection to fail.
Ryan Hamiltonabad59e2019-06-06 04:02:592321 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032322 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2323 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2324 quic_data2.AddSocketDataToFactory(&socket_factory_);
2325
2326 // Resolve the host resolution synchronously.
2327 host_resolver_.set_synchronous_mode(true);
2328 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2329 "");
Zhongyi Shia6b68d112018-09-24 07:49:032330
2331 CreateSession();
2332 session_->quic_stream_factory()->set_require_confirmation(true);
2333 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032334 QuicStreamFactoryPeer::SetAlarmFactory(
2335 session_->quic_stream_factory(),
2336 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2337 &clock_));
2338 // Add alternate protocol mapping to race QUIC and TCP.
2339 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2340 // peer.
2341 AddQuicAlternateProtocolMapping(
2342 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2343
2344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2345 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362346 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2348
2349 // Pump the message loop to get the request started.
2350 // Request will be served with TCP job.
2351 base::RunLoop().RunUntilIdle();
2352 EXPECT_THAT(callback.WaitForResult(), IsOk());
2353 CheckResponseData(&trans, "TCP succeeds");
2354
2355 // Fire the retransmission alarm, from this point, connection will idle
2356 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062357 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182358 quic_fix_time_of_first_packet_sent_after_receiving)) {
2359 quic_task_runner_->RunNextTask();
2360 }
Zhongyi Shia6b68d112018-09-24 07:49:032361 // Fast forward to idle timeout the original connection. A new connection will
2362 // be kicked off on the alternate network.
2363 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2364 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2365 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2366
2367 // Run the message loop to execute posted tasks, which will report job status.
2368 base::RunLoop().RunUntilIdle();
2369
2370 // Verify that QUIC is marked as broken.
2371 ExpectBrokenAlternateProtocolMapping();
2372
2373 // Deliver a message to notify the new network becomes default, the brokenness
2374 // will not expire as QUIC is broken on both networks.
2375 scoped_mock_change_notifier_->mock_network_change_notifier()
2376 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2377 ExpectBrokenAlternateProtocolMapping();
2378
2379 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2380 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2381}
2382
2383// This test verifies that a new QUIC connection will be attempted on the
2384// alternate network if the original QUIC connection fails with idle timeout
2385// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2386// alternate network, QUIC is marked as broken. The brokenness will expire when
2387// the default network changes.
2388TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2389 SetUpTestForRetryConnectionOnAlternateNetwork();
2390
2391 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032392 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032393
2394 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592395 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032396 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2397 int packet_num = 1;
2398 quic_data.AddWrite(SYNCHRONOUS,
2399 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2400 // Retranmit the handshake messages.
2401 quic_data.AddWrite(SYNCHRONOUS,
2402 client_maker_.MakeDummyCHLOPacket(packet_num++));
2403 quic_data.AddWrite(SYNCHRONOUS,
2404 client_maker_.MakeDummyCHLOPacket(packet_num++));
2405 quic_data.AddWrite(SYNCHRONOUS,
2406 client_maker_.MakeDummyCHLOPacket(packet_num++));
2407 quic_data.AddWrite(SYNCHRONOUS,
2408 client_maker_.MakeDummyCHLOPacket(packet_num++));
2409 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562410 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032411 quic_data.AddWrite(SYNCHRONOUS,
2412 client_maker_.MakeDummyCHLOPacket(packet_num++));
2413 }
2414 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2415 quic_data.AddWrite(SYNCHRONOUS,
2416 client_maker_.MakeConnectionClosePacket(
2417 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2418 "No recent network activity."));
2419 quic_data.AddSocketDataToFactory(&socket_factory_);
2420
2421 // Add successful TCP data so that TCP job will succeed.
2422 MockWrite http_writes[] = {
2423 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2424 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2425 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2426
2427 MockRead http_reads[] = {
2428 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2429 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2430 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2431 SequencedSocketData http_data(http_reads, http_writes);
2432 socket_factory_.AddSocketDataProvider(&http_data);
2433 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2434
2435 // Quic connection will be retried on the alternate network after the initial
2436 // one fails on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:592437 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032438 quic::QuicStreamOffset header_stream_offset = 0;
2439 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2440 quic_data2.AddWrite(SYNCHRONOUS,
2441 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2442
2443 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2444 quic_data2.AddWrite(SYNCHRONOUS,
2445 ConstructInitialSettingsPacket(2, &header_stream_offset));
2446 quic_data2.AddSocketDataToFactory(&socket_factory_);
2447
2448 // Resolve the host resolution synchronously.
2449 host_resolver_.set_synchronous_mode(true);
2450 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2451 "");
Zhongyi Shia6b68d112018-09-24 07:49:032452
2453 CreateSession();
2454 session_->quic_stream_factory()->set_require_confirmation(true);
2455 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032456 QuicStreamFactoryPeer::SetAlarmFactory(
2457 session_->quic_stream_factory(),
2458 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2459 &clock_));
2460 // Add alternate protocol mapping to race QUIC and TCP.
2461 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2462 // peer.
2463 AddQuicAlternateProtocolMapping(
2464 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2465
2466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2467 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362468 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2470
2471 // Pump the message loop to get the request started.
2472 // Request will be served with TCP job.
2473 base::RunLoop().RunUntilIdle();
2474 EXPECT_THAT(callback.WaitForResult(), IsOk());
2475 CheckResponseData(&trans, "TCP succeeds");
2476
2477 // Fire the retransmission alarm, after which connection will idle
2478 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062479 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182480 quic_fix_time_of_first_packet_sent_after_receiving)) {
2481 quic_task_runner_->RunNextTask();
2482 }
Zhongyi Shia6b68d112018-09-24 07:49:032483 // Fast forward to idle timeout the original connection. A new connection will
2484 // be kicked off on the alternate network.
2485 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2486 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2487 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2488
2489 // The second connection hasn't finish handshake, verify that QUIC is not
2490 // marked as broken.
2491 ExpectQuicAlternateProtocolMapping();
2492 // Explicitly confirm the handshake on the second connection.
2493 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2494 quic::QuicSession::HANDSHAKE_CONFIRMED);
2495 // Run message loop to execute posted tasks, which will notify JoController
2496 // about the orphaned job status.
2497 base::RunLoop().RunUntilIdle();
2498
2499 // Verify that QUIC is marked as broken.
2500 ExpectBrokenAlternateProtocolMapping();
2501
2502 // Deliver a message to notify the new network becomes default, the previous
2503 // brokenness will be clear as the brokenness is bond with old default
2504 // network.
2505 scoped_mock_change_notifier_->mock_network_change_notifier()
2506 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2507 ExpectQuicAlternateProtocolMapping();
2508
2509 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2510 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2511}
2512
2513// This test verifies that a new QUIC connection will be attempted on the
2514// alternate network if the original QUIC connection fails with idle timeout
2515// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2516// alternative network succeeds, QUIC is not marked as broken.
2517TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2518 SetUpTestForRetryConnectionOnAlternateNetwork();
2519
2520 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032521 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032522
2523 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592524 MockQuicData quic_data(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032525 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2526 int packet_num = 1;
2527 quic_data.AddWrite(SYNCHRONOUS,
2528 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2529 // Retranmit the handshake messages.
2530 quic_data.AddWrite(SYNCHRONOUS,
2531 client_maker_.MakeDummyCHLOPacket(packet_num++));
2532 quic_data.AddWrite(SYNCHRONOUS,
2533 client_maker_.MakeDummyCHLOPacket(packet_num++));
2534 quic_data.AddWrite(SYNCHRONOUS,
2535 client_maker_.MakeDummyCHLOPacket(packet_num++));
2536 quic_data.AddWrite(SYNCHRONOUS,
2537 client_maker_.MakeDummyCHLOPacket(packet_num++));
2538 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2539 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562540 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032541 quic_data.AddWrite(SYNCHRONOUS,
2542 client_maker_.MakeDummyCHLOPacket(packet_num++));
2543 }
2544 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2545 quic_data.AddWrite(SYNCHRONOUS,
2546 client_maker_.MakeConnectionClosePacket(
2547 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2548 "No recent network activity."));
2549 quic_data.AddSocketDataToFactory(&socket_factory_);
2550
2551 // Add hanging TCP data so that TCP job will never succeeded.
2552 AddHangingNonAlternateProtocolSocketData();
2553
2554 // Quic connection will then be retried on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:592555 MockQuicData quic_data2(version_);
Zhongyi Shia6b68d112018-09-24 07:49:032556 quic::QuicStreamOffset header_stream_offset = 0;
2557 quic_data2.AddWrite(SYNCHRONOUS,
2558 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2559
Victor Vasiliev076657c2019-03-12 02:46:432560 const std::string body = "hello!";
2561 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412562
Zhongyi Shia6b68d112018-09-24 07:49:032563 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2564 quic_data2.AddWrite(SYNCHRONOUS,
2565 ConstructInitialSettingsPacket(2, &header_stream_offset));
2566 quic_data2.AddWrite(
2567 SYNCHRONOUS,
2568 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332569 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032570 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032571 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332572 ASYNC, ConstructServerResponseHeadersPacket(
2573 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2574 GetResponseHeaders("200 OK")));
2575 quic_data2.AddRead(
2576 ASYNC, ConstructServerDataPacket(
2577 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412578 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032579 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2580 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2581 quic_data2.AddSocketDataToFactory(&socket_factory_);
2582
2583 // Resolve the host resolution synchronously.
2584 host_resolver_.set_synchronous_mode(true);
2585 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2586 "");
Zhongyi Shia6b68d112018-09-24 07:49:032587
2588 CreateSession();
2589 session_->quic_stream_factory()->set_require_confirmation(true);
2590 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032591 QuicStreamFactoryPeer::SetAlarmFactory(
2592 session_->quic_stream_factory(),
2593 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2594 &clock_));
2595 // Add alternate protocol mapping to race QUIC and TCP.
2596 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2597 // peer.
2598 AddQuicAlternateProtocolMapping(
2599 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2600
2601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2602 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362603 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032604 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2605
2606 // Pump the message loop to get the request started.
2607 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062608 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182609 quic_fix_time_of_first_packet_sent_after_receiving)) {
2610 quic_task_runner_->RunNextTask();
2611 }
Zhongyi Shia6b68d112018-09-24 07:49:032612
2613 // Fast forward to idle timeout the original connection. A new connection will
2614 // be kicked off on the alternate network.
2615 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2616 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2617 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2618
2619 // Verify that QUIC is not marked as broken.
2620 ExpectQuicAlternateProtocolMapping();
2621 // Explicitly confirm the handshake on the second connection.
2622 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2623 quic::QuicSession::HANDSHAKE_CONFIRMED);
2624
2625 // Read the response.
2626 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412627 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032628 // Verify that QUIC is not marked as broken.
2629 ExpectQuicAlternateProtocolMapping();
2630
2631 // Deliver a message to notify the new network becomes default.
2632 scoped_mock_change_notifier_->mock_network_change_notifier()
2633 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2634 ExpectQuicAlternateProtocolMapping();
2635 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2636 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2637}
2638
rch9ecde09b2017-04-08 00:18:232639// Verify that if a QUIC connection times out, the QuicHttpStream will
2640// return QUIC_PROTOCOL_ERROR.
2641TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482642 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412643 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232644
2645 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592646 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522647 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132648 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232649 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2650
2651 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032652 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432653 quic_data.AddWrite(SYNCHRONOUS,
2654 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332655 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2656 true, priority, GetRequestHeaders("GET", "https", "/"),
2657 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232658
2659 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522660 quic::QuicStreamOffset settings_offset = header_stream_offset;
2661 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432662 quic_data.AddWrite(SYNCHRONOUS,
2663 client_maker_.MakeInitialSettingsPacketAndSaveData(
2664 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232665 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522666 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562667 SYNCHRONOUS,
2668 client_maker_.MakeDataPacket(
2669 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2670 true, false, 0, request_data));
2671 // TLP 2
2672 quic_data.AddWrite(
2673 SYNCHRONOUS,
2674 client_maker_.MakeDataPacket(
2675 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2676 true, false, settings_offset, settings_data));
2677 // RTO 1
2678 quic_data.AddWrite(
2679 SYNCHRONOUS,
2680 client_maker_.MakeDataPacket(
2681 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2682 true, false, 0, request_data));
2683 quic_data.AddWrite(
2684 SYNCHRONOUS,
2685 client_maker_.MakeDataPacket(
2686 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2687 true, false, settings_offset, settings_data));
2688 // RTO 2
2689 quic_data.AddWrite(
2690 SYNCHRONOUS,
2691 client_maker_.MakeDataPacket(
2692 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2693 true, false, 0, request_data));
2694 quic_data.AddWrite(
2695 SYNCHRONOUS,
2696 client_maker_.MakeDataPacket(
2697 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2698 true, false, settings_offset, settings_data));
2699 // RTO 3
2700 quic_data.AddWrite(
2701 SYNCHRONOUS,
2702 client_maker_.MakeDataPacket(
2703 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2704 true, false, 0, request_data));
2705 quic_data.AddWrite(
2706 SYNCHRONOUS,
2707 client_maker_.MakeDataPacket(
2708 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2709 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232710
Zhongyi Shi32f2fd02018-04-16 18:23:432711 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522712 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432713 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222714
rch9ecde09b2017-04-08 00:18:232715 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2716 quic_data.AddRead(ASYNC, OK);
2717 quic_data.AddSocketDataToFactory(&socket_factory_);
2718
2719 // In order for a new QUIC session to be established via alternate-protocol
2720 // without racing an HTTP connection, we need the host resolution to happen
2721 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2722 // connection to the the server, in this test we require confirmation
2723 // before encrypting so the HTTP job will still start.
2724 host_resolver_.set_synchronous_mode(true);
2725 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2726 "");
rch9ecde09b2017-04-08 00:18:232727
2728 CreateSession();
2729 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232730 QuicStreamFactoryPeer::SetAlarmFactory(
2731 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192732 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552733 &clock_));
rch9ecde09b2017-04-08 00:18:232734
Ryan Hamilton9835e662018-08-02 05:36:272735 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232736
2737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2738 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362739 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2741
2742 // Pump the message loop to get the request started.
2743 base::RunLoop().RunUntilIdle();
2744 // Explicitly confirm the handshake.
2745 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522746 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232747
2748 // Run the QUIC session to completion.
2749 quic_task_runner_->RunUntilIdle();
2750
2751 ExpectQuicAlternateProtocolMapping();
2752 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2753 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2754}
2755
2756// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2757// return QUIC_PROTOCOL_ERROR.
2758TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482759 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522760 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232761
2762 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592763 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522764 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132765 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232766 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2767
2768 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032769 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432770 quic_data.AddWrite(SYNCHRONOUS,
2771 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332772 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2773 true, priority, GetRequestHeaders("GET", "https", "/"),
2774 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232775
2776 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522777 quic::QuicStreamOffset settings_offset = header_stream_offset;
2778 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432779 quic_data.AddWrite(SYNCHRONOUS,
2780 client_maker_.MakeInitialSettingsPacketAndSaveData(
2781 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232782 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522783 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562784 SYNCHRONOUS,
2785 client_maker_.MakeDataPacket(
2786 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2787 true, false, 0, request_data));
2788 // TLP 2
2789 quic_data.AddWrite(
2790 SYNCHRONOUS,
2791 client_maker_.MakeDataPacket(
2792 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2793 true, false, settings_offset, settings_data));
2794 // RTO 1
2795 quic_data.AddWrite(
2796 SYNCHRONOUS,
2797 client_maker_.MakeDataPacket(
2798 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2799 true, false, 0, request_data));
2800 quic_data.AddWrite(
2801 SYNCHRONOUS,
2802 client_maker_.MakeDataPacket(
2803 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2804 true, false, settings_offset, settings_data));
2805 // RTO 2
2806 quic_data.AddWrite(
2807 SYNCHRONOUS,
2808 client_maker_.MakeDataPacket(
2809 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2810 true, false, 0, request_data));
2811 quic_data.AddWrite(
2812 SYNCHRONOUS,
2813 client_maker_.MakeDataPacket(
2814 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2815 true, false, settings_offset, settings_data));
2816 // RTO 3
2817 quic_data.AddWrite(
2818 SYNCHRONOUS,
2819 client_maker_.MakeDataPacket(
2820 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2821 true, false, 0, request_data));
2822 quic_data.AddWrite(
2823 SYNCHRONOUS,
2824 client_maker_.MakeDataPacket(
2825 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2826 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232827 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522828 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562829 SYNCHRONOUS,
2830 client_maker_.MakeDataPacket(
2831 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2832 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:092833 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562834 SYNCHRONOUS,
2835 client_maker_.MakeDataPacket(
2836 12, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2837 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232838 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432839 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522840 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432841 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232842
2843 quic_data.AddRead(ASYNC, OK);
2844 quic_data.AddSocketDataToFactory(&socket_factory_);
2845
2846 // In order for a new QUIC session to be established via alternate-protocol
2847 // without racing an HTTP connection, we need the host resolution to happen
2848 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2849 // connection to the the server, in this test we require confirmation
2850 // before encrypting so the HTTP job will still start.
2851 host_resolver_.set_synchronous_mode(true);
2852 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2853 "");
rch9ecde09b2017-04-08 00:18:232854
2855 CreateSession();
2856 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232857 QuicStreamFactoryPeer::SetAlarmFactory(
2858 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192859 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552860 &clock_));
rch9ecde09b2017-04-08 00:18:232861
Ryan Hamilton9835e662018-08-02 05:36:272862 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232863
2864 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2865 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362866 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2868
2869 // Pump the message loop to get the request started.
2870 base::RunLoop().RunUntilIdle();
2871 // Explicitly confirm the handshake.
2872 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522873 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232874
2875 // Run the QUIC session to completion.
2876 quic_task_runner_->RunUntilIdle();
2877
2878 ExpectQuicAlternateProtocolMapping();
2879 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2880 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2881}
2882
2883// Verify that if a QUIC connection RTOs, while there are no active streams
2884// QUIC will not be marked as broken.
2885TEST_P(QuicNetworkTransactionTest,
2886 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522887 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232888
2889 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:592890 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522891 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132892 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232893 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2894
2895 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032896 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432897 quic_data.AddWrite(SYNCHRONOUS,
2898 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332899 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2900 true, priority, GetRequestHeaders("GET", "https", "/"),
2901 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232902
2903 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522904 quic::QuicStreamOffset settings_offset = header_stream_offset;
2905 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432906 quic_data.AddWrite(SYNCHRONOUS,
2907 client_maker_.MakeInitialSettingsPacketAndSaveData(
2908 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232909
Fan Yang32c5a112018-12-10 20:06:332910 quic_data.AddWrite(SYNCHRONOUS,
2911 client_maker_.MakeRstPacket(
2912 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2913 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232914 // TLP 1
Nick Harper23290b82019-05-02 00:02:562915 quic_data.AddWrite(
2916 SYNCHRONOUS,
2917 client_maker_.MakeDataPacket(
2918 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2919 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232920 // TLP 2
Nick Harper23290b82019-05-02 00:02:562921 quic_data.AddWrite(
2922 SYNCHRONOUS,
2923 client_maker_.MakeDataPacket(
2924 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2925 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232926 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332927 quic_data.AddWrite(SYNCHRONOUS,
2928 client_maker_.MakeRstPacket(
2929 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2930 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:562931 quic_data.AddWrite(
2932 SYNCHRONOUS,
2933 client_maker_.MakeDataPacket(
2934 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2935 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232936 // RTO 2
Nick Harper23290b82019-05-02 00:02:562937 quic_data.AddWrite(
2938 SYNCHRONOUS,
2939 client_maker_.MakeDataPacket(
2940 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2941 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332942 quic_data.AddWrite(SYNCHRONOUS,
2943 client_maker_.MakeRstPacket(
2944 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2945 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232946 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522947 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562948 SYNCHRONOUS,
2949 client_maker_.MakeDataPacket(
2950 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2951 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:092952 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562953 SYNCHRONOUS,
2954 client_maker_.MakeDataPacket(
2955 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2956 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232957 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432958 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332959 SYNCHRONOUS, client_maker_.MakeRstPacket(
2960 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2961 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522962 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562963 SYNCHRONOUS,
2964 client_maker_.MakeDataPacket(
2965 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2966 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232967 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432968 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522969 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432970 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232971
2972 quic_data.AddRead(ASYNC, OK);
2973 quic_data.AddSocketDataToFactory(&socket_factory_);
2974
2975 // In order for a new QUIC session to be established via alternate-protocol
2976 // without racing an HTTP connection, we need the host resolution to happen
2977 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2978 // connection to the the server, in this test we require confirmation
2979 // before encrypting so the HTTP job will still start.
2980 host_resolver_.set_synchronous_mode(true);
2981 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2982 "");
rch9ecde09b2017-04-08 00:18:232983
2984 CreateSession();
2985 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232986 QuicStreamFactoryPeer::SetAlarmFactory(
2987 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192988 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552989 &clock_));
rch9ecde09b2017-04-08 00:18:232990
Ryan Hamilton9835e662018-08-02 05:36:272991 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232992
Jeremy Roman0579ed62017-08-29 15:56:192993 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232994 session_.get());
2995 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362996 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2998
2999 // Pump the message loop to get the request started.
3000 base::RunLoop().RunUntilIdle();
3001 // Explicitly confirm the handshake.
3002 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523003 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233004
3005 // Now cancel the request.
3006 trans.reset();
3007
3008 // Run the QUIC session to completion.
3009 quic_task_runner_->RunUntilIdle();
3010
3011 ExpectQuicAlternateProtocolMapping();
3012
3013 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3014}
3015
rch2f2991c2017-04-13 19:28:173016// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3017// the request fails with QUIC_PROTOCOL_ERROR.
3018TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:483019 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173020 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593021 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523022 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033023 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433024 quic_data.AddWrite(
3025 SYNCHRONOUS,
3026 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333027 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433028 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523029 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433030 quic_data.AddWrite(SYNCHRONOUS,
3031 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173032 // Peer sending data from an non-existing stream causes this end to raise
3033 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333034 quic_data.AddRead(
3035 ASYNC, ConstructServerRstPacket(
3036 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3037 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173038 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433039 quic_data.AddWrite(SYNCHRONOUS,
3040 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523041 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3042 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173043 quic_data.AddSocketDataToFactory(&socket_factory_);
3044
3045 // In order for a new QUIC session to be established via alternate-protocol
3046 // without racing an HTTP connection, we need the host resolution to happen
3047 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3048 // connection to the the server, in this test we require confirmation
3049 // before encrypting so the HTTP job will still start.
3050 host_resolver_.set_synchronous_mode(true);
3051 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3052 "");
rch2f2991c2017-04-13 19:28:173053
3054 CreateSession();
3055
Ryan Hamilton9835e662018-08-02 05:36:273056 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173057
3058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3059 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363060 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3062
3063 // Pump the message loop to get the request started.
3064 base::RunLoop().RunUntilIdle();
3065 // Explicitly confirm the handshake.
3066 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523067 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173068
3069 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3070
3071 // Run the QUIC session to completion.
3072 base::RunLoop().RunUntilIdle();
3073 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3074 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3075
3076 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3077 ExpectQuicAlternateProtocolMapping();
3078 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3079}
3080
rch9ecde09b2017-04-08 00:18:233081// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3082// connection times out, then QUIC will be marked as broken and the request
3083// retried over TCP.
3084TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413085 session_params_.mark_quic_broken_when_network_blackholes = true;
3086 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233087
3088 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593089 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523090 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133091 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233092 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3093
3094 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033095 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433096 quic_data.AddWrite(SYNCHRONOUS,
3097 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333098 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3099 true, priority, GetRequestHeaders("GET", "https", "/"),
3100 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233101
3102 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523103 quic::QuicStreamOffset settings_offset = header_stream_offset;
3104 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433105 quic_data.AddWrite(SYNCHRONOUS,
3106 client_maker_.MakeInitialSettingsPacketAndSaveData(
3107 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233108 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523109 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563110 SYNCHRONOUS,
3111 client_maker_.MakeDataPacket(
3112 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3113 true, false, 0, request_data));
3114 // TLP 2
3115 quic_data.AddWrite(
3116 SYNCHRONOUS,
3117 client_maker_.MakeDataPacket(
3118 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3119 true, false, settings_offset, settings_data));
3120 // RTO 1
3121 quic_data.AddWrite(
3122 SYNCHRONOUS,
3123 client_maker_.MakeDataPacket(
3124 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3125 true, false, 0, request_data));
3126 quic_data.AddWrite(
3127 SYNCHRONOUS,
3128 client_maker_.MakeDataPacket(
3129 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3130 true, false, settings_offset, settings_data));
3131 // RTO 2
3132 quic_data.AddWrite(
3133 SYNCHRONOUS,
3134 client_maker_.MakeDataPacket(
3135 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3136 true, false, 0, request_data));
3137 quic_data.AddWrite(
3138 SYNCHRONOUS,
3139 client_maker_.MakeDataPacket(
3140 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3141 true, false, settings_offset, settings_data));
3142 // RTO 3
3143 quic_data.AddWrite(
3144 SYNCHRONOUS,
3145 client_maker_.MakeDataPacket(
3146 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3147 true, false, 0, request_data));
3148 quic_data.AddWrite(
3149 SYNCHRONOUS,
3150 client_maker_.MakeDataPacket(
3151 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3152 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233153
Zhongyi Shi32f2fd02018-04-16 18:23:433154 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523155 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433156 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223157
rch9ecde09b2017-04-08 00:18:233158 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3159 quic_data.AddRead(ASYNC, OK);
3160 quic_data.AddSocketDataToFactory(&socket_factory_);
3161
3162 // After that fails, it will be resent via TCP.
3163 MockWrite http_writes[] = {
3164 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3165 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3166 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3167
3168 MockRead http_reads[] = {
3169 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3170 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3171 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013172 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233173 socket_factory_.AddSocketDataProvider(&http_data);
3174 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3175
3176 // In order for a new QUIC session to be established via alternate-protocol
3177 // without racing an HTTP connection, we need the host resolution to happen
3178 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3179 // connection to the the server, in this test we require confirmation
3180 // before encrypting so the HTTP job will still start.
3181 host_resolver_.set_synchronous_mode(true);
3182 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3183 "");
rch9ecde09b2017-04-08 00:18:233184
3185 CreateSession();
3186 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233187 QuicStreamFactoryPeer::SetAlarmFactory(
3188 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193189 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553190 &clock_));
rch9ecde09b2017-04-08 00:18:233191
Ryan Hamilton9835e662018-08-02 05:36:273192 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233193
3194 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3195 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363196 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233197 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3198
3199 // Pump the message loop to get the request started.
3200 base::RunLoop().RunUntilIdle();
3201 // Explicitly confirm the handshake.
3202 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523203 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233204
3205 // Run the QUIC session to completion.
3206 quic_task_runner_->RunUntilIdle();
3207 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3208
3209 // Let the transaction proceed which will result in QUIC being marked
3210 // as broken and the request falling back to TCP.
3211 EXPECT_THAT(callback.WaitForResult(), IsOk());
3212
3213 ExpectBrokenAlternateProtocolMapping();
3214 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3215 ASSERT_FALSE(http_data.AllReadDataConsumed());
3216
3217 // Read the response body over TCP.
3218 CheckResponseData(&trans, "hello world");
3219 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3220 ASSERT_TRUE(http_data.AllReadDataConsumed());
3221}
3222
rch2f2991c2017-04-13 19:28:173223// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3224// connection times out, then QUIC will be marked as broken and the request
3225// retried over TCP.
3226TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413227 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173228
3229 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593230 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523231 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133232 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173233 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3234
3235 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033236 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433237 quic_data.AddWrite(SYNCHRONOUS,
3238 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333239 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3240 true, priority, GetRequestHeaders("GET", "https", "/"),
3241 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173242
3243 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523244 quic::QuicStreamOffset settings_offset = header_stream_offset;
3245 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433246 quic_data.AddWrite(SYNCHRONOUS,
3247 client_maker_.MakeInitialSettingsPacketAndSaveData(
3248 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173249 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523250 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563251 SYNCHRONOUS,
3252 client_maker_.MakeDataPacket(
3253 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3254 true, false, 0, request_data));
3255 // TLP 2
3256 quic_data.AddWrite(
3257 SYNCHRONOUS,
3258 client_maker_.MakeDataPacket(
3259 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3260 true, false, settings_offset, settings_data));
3261 // RTO 1
3262 quic_data.AddWrite(
3263 SYNCHRONOUS,
3264 client_maker_.MakeDataPacket(
3265 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3266 true, false, 0, request_data));
3267 quic_data.AddWrite(
3268 SYNCHRONOUS,
3269 client_maker_.MakeDataPacket(
3270 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3271 true, false, settings_offset, settings_data));
3272 // RTO 2
3273 quic_data.AddWrite(
3274 SYNCHRONOUS,
3275 client_maker_.MakeDataPacket(
3276 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3277 true, false, 0, request_data));
3278 quic_data.AddWrite(
3279 SYNCHRONOUS,
3280 client_maker_.MakeDataPacket(
3281 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3282 true, false, settings_offset, settings_data));
3283 // RTO 3
3284 quic_data.AddWrite(
3285 SYNCHRONOUS,
3286 client_maker_.MakeDataPacket(
3287 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3288 true, false, 0, request_data));
3289 quic_data.AddWrite(
3290 SYNCHRONOUS,
3291 client_maker_.MakeDataPacket(
3292 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3293 true, false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173294
Zhongyi Shi32f2fd02018-04-16 18:23:433295 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523296 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433297 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223298
rch2f2991c2017-04-13 19:28:173299 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3300 quic_data.AddRead(ASYNC, OK);
3301 quic_data.AddSocketDataToFactory(&socket_factory_);
3302
3303 // After that fails, it will be resent via TCP.
3304 MockWrite http_writes[] = {
3305 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3306 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3307 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3308
3309 MockRead http_reads[] = {
3310 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3311 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3312 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013313 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173314 socket_factory_.AddSocketDataProvider(&http_data);
3315 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3316
3317 // In order for a new QUIC session to be established via alternate-protocol
3318 // without racing an HTTP connection, we need the host resolution to happen
3319 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3320 // connection to the the server, in this test we require confirmation
3321 // before encrypting so the HTTP job will still start.
3322 host_resolver_.set_synchronous_mode(true);
3323 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3324 "");
rch2f2991c2017-04-13 19:28:173325
3326 CreateSession();
3327 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173328 QuicStreamFactoryPeer::SetAlarmFactory(
3329 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193330 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553331 &clock_));
rch2f2991c2017-04-13 19:28:173332
Ryan Hamilton9835e662018-08-02 05:36:273333 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173334
3335 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3336 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363337 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3339
3340 // Pump the message loop to get the request started.
3341 base::RunLoop().RunUntilIdle();
3342 // Explicitly confirm the handshake.
3343 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523344 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173345
3346 // Run the QUIC session to completion.
3347 quic_task_runner_->RunUntilIdle();
3348 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3349
3350 ExpectQuicAlternateProtocolMapping();
3351
3352 // Let the transaction proceed which will result in QUIC being marked
3353 // as broken and the request falling back to TCP.
3354 EXPECT_THAT(callback.WaitForResult(), IsOk());
3355
3356 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3357 ASSERT_FALSE(http_data.AllReadDataConsumed());
3358
3359 // Read the response body over TCP.
3360 CheckResponseData(&trans, "hello world");
3361 ExpectBrokenAlternateProtocolMapping();
3362 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3363 ASSERT_TRUE(http_data.AllReadDataConsumed());
3364}
3365
rch9ecde09b2017-04-08 00:18:233366// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3367// connection times out, then QUIC will be marked as broken but the request
3368// will not be retried over TCP.
3369TEST_P(QuicNetworkTransactionTest,
3370 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413371 session_params_.mark_quic_broken_when_network_blackholes = true;
3372 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233373
3374 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593375 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523376 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133377 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233378 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3379
3380 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033381 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433382 quic_data.AddWrite(SYNCHRONOUS,
3383 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333384 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3385 true, priority, GetRequestHeaders("GET", "https", "/"),
3386 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233387
3388 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523389 quic::QuicStreamOffset settings_offset = header_stream_offset;
3390 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433391 quic_data.AddWrite(SYNCHRONOUS,
3392 client_maker_.MakeInitialSettingsPacketAndSaveData(
3393 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233394
Zhongyi Shi32f2fd02018-04-16 18:23:433395 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333396 1, GetNthClientInitiatedBidirectionalStreamId(0),
3397 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433398 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523399 quic_data.AddWrite(
3400 SYNCHRONOUS,
3401 ConstructClientAckPacket(3, 1, 1, 1,
3402 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233403
3404 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523405 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563406 SYNCHRONOUS,
3407 client_maker_.MakeDataPacket(
3408 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3409 false, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233410 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093411 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563412 SYNCHRONOUS,
3413 client_maker_.MakeDataPacket(
3414 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3415 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233416 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523417 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563418 SYNCHRONOUS,
3419 client_maker_.MakeDataPacket(
3420 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3421 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093422 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563423 SYNCHRONOUS,
3424 client_maker_.MakeDataPacket(
3425 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3426 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233427 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523428 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563429 SYNCHRONOUS,
3430 client_maker_.MakeDataPacket(
3431 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3432 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093433 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563434 SYNCHRONOUS,
3435 client_maker_.MakeDataPacket(
3436 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3437 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233438 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523439 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563440 SYNCHRONOUS,
3441 client_maker_.MakeDataPacket(
3442 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3443 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093444 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563445 SYNCHRONOUS,
3446 client_maker_.MakeDataPacket(
3447 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3448 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233449
Michael Warres112212822018-12-26 17:51:063450 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183451 quic_fix_time_of_first_packet_sent_after_receiving)) {
3452 quic_data.AddWrite(
3453 SYNCHRONOUS,
3454 client_maker_.MakeAckAndConnectionClosePacket(
3455 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3456 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3457
3458 } else {
3459 quic_data.AddWrite(
3460 SYNCHRONOUS,
3461 client_maker_.MakeAckAndConnectionClosePacket(
3462 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3463 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3464 }
Fan Yang928f1632017-12-14 18:55:223465
rch9ecde09b2017-04-08 00:18:233466 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3467 quic_data.AddRead(ASYNC, OK);
3468 quic_data.AddSocketDataToFactory(&socket_factory_);
3469
3470 // In order for a new QUIC session to be established via alternate-protocol
3471 // without racing an HTTP connection, we need the host resolution to happen
3472 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3473 // connection to the the server, in this test we require confirmation
3474 // before encrypting so the HTTP job will still start.
3475 host_resolver_.set_synchronous_mode(true);
3476 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3477 "");
rch9ecde09b2017-04-08 00:18:233478
3479 CreateSession();
3480 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233481 QuicStreamFactoryPeer::SetAlarmFactory(
3482 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193483 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553484 &clock_));
rch9ecde09b2017-04-08 00:18:233485
Ryan Hamilton9835e662018-08-02 05:36:273486 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233487
3488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3489 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363490 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3492
3493 // Pump the message loop to get the request started.
3494 base::RunLoop().RunUntilIdle();
3495 // Explicitly confirm the handshake.
3496 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523497 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233498
3499 // Pump the message loop to get the request started.
3500 base::RunLoop().RunUntilIdle();
3501
3502 // Run the QUIC session to completion.
3503 quic_task_runner_->RunUntilIdle();
3504 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3505
3506 // Let the transaction proceed which will result in QUIC being marked
3507 // as broken and the request falling back to TCP.
3508 EXPECT_THAT(callback.WaitForResult(), IsOk());
3509
3510 ExpectBrokenAlternateProtocolMapping();
3511 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3512
3513 std::string response_data;
3514 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3515 IsError(ERR_QUIC_PROTOCOL_ERROR));
3516}
3517
3518// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3519// connection RTOs, then QUIC will be marked as broken and the request retried
3520// over TCP.
3521TEST_P(QuicNetworkTransactionTest,
3522 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413523 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523524 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233525
3526 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593527 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523528 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133529 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233530 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3531
3532 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033533 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433534 quic_data.AddWrite(SYNCHRONOUS,
3535 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333536 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3537 true, priority, GetRequestHeaders("GET", "https", "/"),
3538 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233539
3540 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523541 quic::QuicStreamOffset settings_offset = header_stream_offset;
3542 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433543 quic_data.AddWrite(SYNCHRONOUS,
3544 client_maker_.MakeInitialSettingsPacketAndSaveData(
3545 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233546 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523547 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563548 SYNCHRONOUS,
3549 client_maker_.MakeDataPacket(
3550 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3551 true, false, 0, request_data));
3552 // TLP 2
3553 quic_data.AddWrite(
3554 SYNCHRONOUS,
3555 client_maker_.MakeDataPacket(
3556 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3557 true, false, settings_offset, settings_data));
3558 // RTO 1
3559 quic_data.AddWrite(
3560 SYNCHRONOUS,
3561 client_maker_.MakeDataPacket(
3562 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3563 true, false, 0, request_data));
3564 quic_data.AddWrite(
3565 SYNCHRONOUS,
3566 client_maker_.MakeDataPacket(
3567 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3568 true, false, settings_offset, settings_data));
3569 // RTO 2
3570 quic_data.AddWrite(
3571 SYNCHRONOUS,
3572 client_maker_.MakeDataPacket(
3573 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3574 true, false, 0, request_data));
3575 quic_data.AddWrite(
3576 SYNCHRONOUS,
3577 client_maker_.MakeDataPacket(
3578 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3579 true, false, settings_offset, settings_data));
3580 // RTO 3
3581 quic_data.AddWrite(
3582 SYNCHRONOUS,
3583 client_maker_.MakeDataPacket(
3584 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3585 true, false, 0, request_data));
3586 quic_data.AddWrite(
3587 SYNCHRONOUS,
3588 client_maker_.MakeDataPacket(
3589 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3590 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233591 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523592 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563593 SYNCHRONOUS,
3594 client_maker_.MakeDataPacket(
3595 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3596 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093597 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563598 SYNCHRONOUS,
3599 client_maker_.MakeDataPacket(
3600 12, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3601 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233602
Zhongyi Shi32f2fd02018-04-16 18:23:433603 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523604 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433605 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233606
3607 quic_data.AddRead(ASYNC, OK);
3608 quic_data.AddSocketDataToFactory(&socket_factory_);
3609
3610 // After that fails, it will be resent via TCP.
3611 MockWrite http_writes[] = {
3612 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3613 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3614 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3615
3616 MockRead http_reads[] = {
3617 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3618 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3619 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013620 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233621 socket_factory_.AddSocketDataProvider(&http_data);
3622 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3623
3624 // In order for a new QUIC session to be established via alternate-protocol
3625 // without racing an HTTP connection, we need the host resolution to happen
3626 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3627 // connection to the the server, in this test we require confirmation
3628 // before encrypting so the HTTP job will still start.
3629 host_resolver_.set_synchronous_mode(true);
3630 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3631 "");
rch9ecde09b2017-04-08 00:18:233632
3633 CreateSession();
3634 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233635 QuicStreamFactoryPeer::SetAlarmFactory(
3636 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193637 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553638 &clock_));
rch9ecde09b2017-04-08 00:18:233639
Ryan Hamilton9835e662018-08-02 05:36:273640 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233641
3642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3643 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363644 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3646
3647 // Pump the message loop to get the request started.
3648 base::RunLoop().RunUntilIdle();
3649 // Explicitly confirm the handshake.
3650 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523651 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233652
3653 // Run the QUIC session to completion.
3654 quic_task_runner_->RunUntilIdle();
3655 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3656
3657 // Let the transaction proceed which will result in QUIC being marked
3658 // as broken and the request falling back to TCP.
3659 EXPECT_THAT(callback.WaitForResult(), IsOk());
3660
3661 ExpectBrokenAlternateProtocolMapping();
3662 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3663 ASSERT_FALSE(http_data.AllReadDataConsumed());
3664
3665 // Read the response body over TCP.
3666 CheckResponseData(&trans, "hello world");
3667 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3668 ASSERT_TRUE(http_data.AllReadDataConsumed());
3669}
3670
3671// Verify that if a QUIC connection RTOs, while there are no active streams
3672// QUIC will be marked as broken.
3673TEST_P(QuicNetworkTransactionTest,
3674 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413675 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523676 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233677
3678 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593679 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523680 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133681 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233682 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3683
3684 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033685 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433686 quic_data.AddWrite(SYNCHRONOUS,
3687 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333688 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3689 true, priority, GetRequestHeaders("GET", "https", "/"),
3690 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233691
3692 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523693 quic::QuicStreamOffset settings_offset = header_stream_offset;
3694 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433695 quic_data.AddWrite(SYNCHRONOUS,
3696 client_maker_.MakeInitialSettingsPacketAndSaveData(
3697 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233698
Fan Yang32c5a112018-12-10 20:06:333699 quic_data.AddWrite(SYNCHRONOUS,
3700 client_maker_.MakeRstPacket(
3701 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3702 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233703 // TLP 1
Nick Harper23290b82019-05-02 00:02:563704 quic_data.AddWrite(
3705 SYNCHRONOUS,
3706 client_maker_.MakeDataPacket(
3707 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3708 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233709 // TLP 2
Nick Harper23290b82019-05-02 00:02:563710 quic_data.AddWrite(
3711 SYNCHRONOUS,
3712 client_maker_.MakeDataPacket(
3713 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3714 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233715 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333716 quic_data.AddWrite(SYNCHRONOUS,
3717 client_maker_.MakeRstPacket(
3718 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3719 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:563720 quic_data.AddWrite(
3721 SYNCHRONOUS,
3722 client_maker_.MakeDataPacket(
3723 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3724 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233725 // RTO 2
Nick Harper23290b82019-05-02 00:02:563726 quic_data.AddWrite(
3727 SYNCHRONOUS,
3728 client_maker_.MakeDataPacket(
3729 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3730 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333731 quic_data.AddWrite(SYNCHRONOUS,
3732 client_maker_.MakeRstPacket(
3733 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3734 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233735 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523736 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563737 SYNCHRONOUS,
3738 client_maker_.MakeDataPacket(
3739 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3740 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093741 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563742 SYNCHRONOUS,
3743 client_maker_.MakeDataPacket(
3744 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3745 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233746 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433747 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333748 SYNCHRONOUS, client_maker_.MakeRstPacket(
3749 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3750 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523751 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563752 SYNCHRONOUS,
3753 client_maker_.MakeDataPacket(
3754 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3755 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233756 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433757 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523758 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433759 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233760
3761 quic_data.AddRead(ASYNC, OK);
3762 quic_data.AddSocketDataToFactory(&socket_factory_);
3763
3764 // In order for a new QUIC session to be established via alternate-protocol
3765 // without racing an HTTP connection, we need the host resolution to happen
3766 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3767 // connection to the the server, in this test we require confirmation
3768 // before encrypting so the HTTP job will still start.
3769 host_resolver_.set_synchronous_mode(true);
3770 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3771 "");
rch9ecde09b2017-04-08 00:18:233772
3773 CreateSession();
3774 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233775 QuicStreamFactoryPeer::SetAlarmFactory(
3776 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193777 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553778 &clock_));
rch9ecde09b2017-04-08 00:18:233779
Ryan Hamilton9835e662018-08-02 05:36:273780 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233781
Jeremy Roman0579ed62017-08-29 15:56:193782 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233783 session_.get());
3784 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363785 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233786 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3787
3788 // Pump the message loop to get the request started.
3789 base::RunLoop().RunUntilIdle();
3790 // Explicitly confirm the handshake.
3791 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523792 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233793
3794 // Now cancel the request.
3795 trans.reset();
3796
3797 // Run the QUIC session to completion.
3798 quic_task_runner_->RunUntilIdle();
3799
3800 ExpectBrokenAlternateProtocolMapping();
3801
3802 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3803}
3804
rch2f2991c2017-04-13 19:28:173805// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3806// protocol error occurs after the handshake is confirmed, the request
3807// retried over TCP and the QUIC will be marked as broken.
3808TEST_P(QuicNetworkTransactionTest,
3809 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413810 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173811
3812 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593813 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523814 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033815 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433816 quic_data.AddWrite(
3817 SYNCHRONOUS,
3818 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333819 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433820 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523821 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433822 quic_data.AddWrite(SYNCHRONOUS,
3823 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173824 // Peer sending data from an non-existing stream causes this end to raise
3825 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333826 quic_data.AddRead(
3827 ASYNC, ConstructServerRstPacket(
3828 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3829 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173830 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433831 quic_data.AddWrite(SYNCHRONOUS,
3832 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523833 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3834 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173835 quic_data.AddSocketDataToFactory(&socket_factory_);
3836
3837 // After that fails, it will be resent via TCP.
3838 MockWrite http_writes[] = {
3839 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3840 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3841 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3842
3843 MockRead http_reads[] = {
3844 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3845 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3846 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013847 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173848 socket_factory_.AddSocketDataProvider(&http_data);
3849 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3850
3851 // In order for a new QUIC session to be established via alternate-protocol
3852 // without racing an HTTP connection, we need the host resolution to happen
3853 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3854 // connection to the the server, in this test we require confirmation
3855 // before encrypting so the HTTP job will still start.
3856 host_resolver_.set_synchronous_mode(true);
3857 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3858 "");
rch2f2991c2017-04-13 19:28:173859
3860 CreateSession();
3861
Ryan Hamilton9835e662018-08-02 05:36:273862 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173863
3864 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3865 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363866 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173867 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3868
3869 // Pump the message loop to get the request started.
3870 base::RunLoop().RunUntilIdle();
3871 // Explicitly confirm the handshake.
3872 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523873 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173874
3875 // Run the QUIC session to completion.
3876 base::RunLoop().RunUntilIdle();
3877 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3878
3879 ExpectQuicAlternateProtocolMapping();
3880
3881 // Let the transaction proceed which will result in QUIC being marked
3882 // as broken and the request falling back to TCP.
3883 EXPECT_THAT(callback.WaitForResult(), IsOk());
3884
3885 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3886 ASSERT_FALSE(http_data.AllReadDataConsumed());
3887
3888 // Read the response body over TCP.
3889 CheckResponseData(&trans, "hello world");
3890 ExpectBrokenAlternateProtocolMapping();
3891 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3892 ASSERT_TRUE(http_data.AllReadDataConsumed());
3893}
3894
rch30943ee2017-06-12 21:28:443895// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3896// request is reset from, then QUIC will be marked as broken and the request
3897// retried over TCP.
3898TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443899 // The request will initially go out over QUIC.
Ryan Hamiltonabad59e2019-06-06 04:02:593900 MockQuicData quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523901 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133902 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443903 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3904
3905 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033906 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433907 quic_data.AddWrite(SYNCHRONOUS,
3908 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333909 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3910 true, priority, GetRequestHeaders("GET", "https", "/"),
3911 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443912
3913 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523914 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3915 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433916 quic_data.AddWrite(SYNCHRONOUS,
3917 client_maker_.MakeInitialSettingsPacketAndSaveData(
3918 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443919
Fan Yang32c5a112018-12-10 20:06:333920 quic_data.AddRead(ASYNC,
3921 ConstructServerRstPacket(
3922 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3923 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443924
3925 quic_data.AddRead(ASYNC, OK);
3926 quic_data.AddSocketDataToFactory(&socket_factory_);
3927
3928 // After that fails, it will be resent via TCP.
3929 MockWrite http_writes[] = {
3930 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3931 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3932 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3933
3934 MockRead http_reads[] = {
3935 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3936 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3937 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013938 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443939 socket_factory_.AddSocketDataProvider(&http_data);
3940 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3941
3942 // In order for a new QUIC session to be established via alternate-protocol
3943 // without racing an HTTP connection, we need the host resolution to happen
3944 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3945 // connection to the the server, in this test we require confirmation
3946 // before encrypting so the HTTP job will still start.
3947 host_resolver_.set_synchronous_mode(true);
3948 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3949 "");
rch30943ee2017-06-12 21:28:443950
3951 CreateSession();
3952
Ryan Hamilton9835e662018-08-02 05:36:273953 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443954
3955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3956 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363957 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3959
3960 // Pump the message loop to get the request started.
3961 base::RunLoop().RunUntilIdle();
3962 // Explicitly confirm the handshake.
3963 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523964 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443965
3966 // Run the QUIC session to completion.
3967 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3968
3969 ExpectQuicAlternateProtocolMapping();
3970
3971 // Let the transaction proceed which will result in QUIC being marked
3972 // as broken and the request falling back to TCP.
3973 EXPECT_THAT(callback.WaitForResult(), IsOk());
3974
3975 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3976 ASSERT_FALSE(http_data.AllReadDataConsumed());
3977
3978 // Read the response body over TCP.
3979 CheckResponseData(&trans, "hello world");
3980 ExpectBrokenAlternateProtocolMapping();
3981 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3982 ASSERT_TRUE(http_data.AllReadDataConsumed());
3983}
3984
Ryan Hamilton6c2a2a82017-12-15 02:06:283985// Verify that when an origin has two alt-svc advertisements, one local and one
3986// remote, that when the local is broken the request will go over QUIC via
3987// the remote Alt-Svc.
3988// This is a regression test for crbug/825646.
3989TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3990 session_params_.quic_allow_remote_alt_svc = true;
3991
3992 GURL origin1 = request_.url; // mail.example.org
3993 GURL origin2("https://www.example.org/");
3994 ASSERT_NE(origin1.host(), origin2.host());
3995
3996 scoped_refptr<X509Certificate> cert(
3997 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243998 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3999 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284000
4001 ProofVerifyDetailsChromium verify_details;
4002 verify_details.cert_verify_result.verified_cert = cert;
4003 verify_details.cert_verify_result.is_issued_by_known_root = true;
4004 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4005
Ryan Hamiltonabad59e2019-06-06 04:02:594006 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524007 quic::QuicStreamOffset request_header_offset(0);
4008 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:284009 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434010 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4011 mock_quic_data.AddWrite(
4012 SYNCHRONOUS,
4013 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334014 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434015 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4016 mock_quic_data.AddRead(
4017 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334018 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434019 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434020 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434021 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334022 ASYNC, ConstructServerDataPacket(
4023 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414024 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434025 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284026 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4027 mock_quic_data.AddRead(ASYNC, 0); // EOF
4028
4029 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Ryan Hamiltonabad59e2019-06-06 04:02:594030 MockQuicData mock_quic_data2(version_);
Ryan Hamilton6c2a2a82017-12-15 02:06:284031 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4032 AddHangingNonAlternateProtocolSocketData();
4033
4034 CreateSession();
4035
4036 // Set up alternative service for |origin1|.
4037 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4038 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4039 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4040 AlternativeServiceInfoVector alternative_services;
4041 alternative_services.push_back(
4042 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4043 local_alternative, expiration,
4044 session_->params().quic_supported_versions));
4045 alternative_services.push_back(
4046 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4047 remote_alternative, expiration,
4048 session_->params().quic_supported_versions));
4049 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4050 alternative_services);
4051
4052 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4053
4054 SendRequestAndExpectQuicResponse("hello!");
4055}
4056
rch30943ee2017-06-12 21:28:444057// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4058// request is reset from, then QUIC will be marked as broken and the request
4059// retried over TCP. Then, subsequent requests will go over a new QUIC
4060// connection instead of going back to the broken QUIC connection.
4061// This is a regression tests for crbug/731303.
4062TEST_P(QuicNetworkTransactionTest,
4063 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344064 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444065
4066 GURL origin1 = request_.url;
4067 GURL origin2("https://www.example.org/");
4068 ASSERT_NE(origin1.host(), origin2.host());
4069
Ryan Hamiltonabad59e2019-06-06 04:02:594070 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524071 quic::QuicStreamOffset request_header_offset(0);
4072 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444073
4074 scoped_refptr<X509Certificate> cert(
4075 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244076 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4077 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444078
4079 ProofVerifyDetailsChromium verify_details;
4080 verify_details.cert_verify_result.verified_cert = cert;
4081 verify_details.cert_verify_result.is_issued_by_known_root = true;
4082 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4083
4084 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434085 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444086 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434087 mock_quic_data.AddWrite(
4088 SYNCHRONOUS,
4089 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334090 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434091 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4092 mock_quic_data.AddRead(
4093 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334094 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434095 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434096 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434097 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334098 ASYNC, ConstructServerDataPacket(
4099 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414100 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434101 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444102
4103 // Second request will go over the pooled QUIC connection, but will be
4104 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054105 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174106 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4107 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054108 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174109 QuicTestPacketMaker server_maker2(
4110 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4111 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434112 mock_quic_data.AddWrite(
4113 SYNCHRONOUS,
4114 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334115 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434116 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334117 GetNthClientInitiatedBidirectionalStreamId(0),
4118 &request_header_offset));
4119 mock_quic_data.AddRead(
4120 ASYNC, ConstructServerRstPacket(
4121 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4122 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444123 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4124 mock_quic_data.AddRead(ASYNC, 0); // EOF
4125
4126 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4127
4128 // After that fails, it will be resent via TCP.
4129 MockWrite http_writes[] = {
4130 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4131 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4132 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4133
4134 MockRead http_reads[] = {
4135 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4136 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4137 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014138 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444139 socket_factory_.AddSocketDataProvider(&http_data);
4140 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4141
Ryan Hamilton6c2a2a82017-12-15 02:06:284142 // Then the next request to the second origin will be sent over TCP.
4143 socket_factory_.AddSocketDataProvider(&http_data);
4144 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444145
4146 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564147 QuicStreamFactoryPeer::SetAlarmFactory(
4148 session_->quic_stream_factory(),
4149 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4150 &clock_));
rch30943ee2017-06-12 21:28:444151
4152 // Set up alternative service for |origin1|.
4153 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244154 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214155 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244156 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444157 supported_versions_);
rch30943ee2017-06-12 21:28:444158
4159 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244160 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214161 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244162 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444163 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344164
rch30943ee2017-06-12 21:28:444165 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524166 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444167 SendRequestAndExpectQuicResponse("hello!");
4168
4169 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524170 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444171 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4172 request_.url = origin2;
4173 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284174 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244175 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284176 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244177 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444178
4179 // The third request should use a new QUIC connection, not the broken
4180 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284181 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444182}
4183
bnc8be55ebb2015-10-30 14:12:074184TEST_P(QuicNetworkTransactionTest,
4185 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564186 std::string altsvc_header =
4187 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4188 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074189 MockRead http_reads[] = {
4190 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4191 MockRead("hello world"),
4192 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4193 MockRead(ASYNC, OK)};
4194
Ryan Sleevib8d7ea02018-05-07 20:01:014195 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074196 socket_factory_.AddSocketDataProvider(&http_data);
4197 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4198 socket_factory_.AddSocketDataProvider(&http_data);
4199 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4200
rch3f4b8452016-02-23 16:59:324201 CreateSession();
bnc8be55ebb2015-10-30 14:12:074202
4203 SendRequestAndExpectHttpResponse("hello world");
4204 SendRequestAndExpectHttpResponse("hello world");
4205}
4206
Xida Chen9bfe0b62018-04-24 19:52:214207// When multiple alternative services are advertised, HttpStreamFactory should
4208// select the alternative service which uses existing QUIC session if available.
4209// If no existing QUIC session can be used, use the first alternative service
4210// from the list.
zhongyi32569c62016-01-08 02:54:304211TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344212 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524213 MockRead http_reads[] = {
4214 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294215 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524216 MockRead("hello world"),
4217 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4218 MockRead(ASYNC, OK)};
4219
Ryan Sleevib8d7ea02018-05-07 20:01:014220 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524221 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084222 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564223 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524224
Ryan Hamilton8d9ee76e2018-05-29 23:52:524225 quic::QuicStreamOffset request_header_offset = 0;
4226 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304227 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294228 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304229 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594230 MockQuicData mock_quic_data(version_);
rch5cb522462017-04-25 20:18:364231 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434232 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4233 mock_quic_data.AddWrite(
4234 SYNCHRONOUS,
4235 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334236 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434237 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304238
4239 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294240 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4241 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434242 mock_quic_data.AddRead(
4243 ASYNC,
4244 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334245 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434246 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434247 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434248 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334249 ASYNC, ConstructServerDataPacket(
4250 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414251 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434252 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304253
4254 // Second QUIC request data.
4255 // Connection pooling, using existing session, no need to include version
4256 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584257 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334258 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4259 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4260 true, GetRequestHeaders("GET", "https", "/"),
4261 GetNthClientInitiatedBidirectionalStreamId(0),
4262 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434263 mock_quic_data.AddRead(
4264 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334265 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434266 GetResponseHeaders("200 OK"), &response_header_offset));
4267 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334268 ASYNC, ConstructServerDataPacket(
4269 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414270 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434271 mock_quic_data.AddWrite(
4272 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524273 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594274 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524275
4276 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4277
rtennetib8e80fb2016-05-16 00:12:094278 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324279 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564280 QuicStreamFactoryPeer::SetAlarmFactory(
4281 session_->quic_stream_factory(),
4282 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4283 &clock_));
bncc958faa2015-07-31 18:14:524284
4285 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304286
bnc359ed2a2016-04-29 20:43:454287 SendRequestAndExpectQuicResponse("hello!");
4288 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304289}
4290
tbansal6490783c2016-09-20 17:55:274291// Check that an existing QUIC connection to an alternative proxy server is
4292// used.
4293TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4294 base::HistogramTester histogram_tester;
4295
Ryan Hamilton8d9ee76e2018-05-29 23:52:524296 quic::QuicStreamOffset request_header_offset = 0;
4297 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274298 // First QUIC request data.
4299 // Open a session to foo.example.org:443 using the first entry of the
4300 // alternative service list.
Ryan Hamiltonabad59e2019-06-06 04:02:594301 MockQuicData mock_quic_data(version_);
rch5cb522462017-04-25 20:18:364302 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434303 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4304 mock_quic_data.AddWrite(
4305 SYNCHRONOUS,
4306 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334307 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434308 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274309
4310 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434311 mock_quic_data.AddRead(
4312 ASYNC,
4313 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334314 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434315 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434316 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434317 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334318 ASYNC, ConstructServerDataPacket(
4319 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414320 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434321 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274322
4323 // Second QUIC request data.
4324 // Connection pooling, using existing session, no need to include version
4325 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274326 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334327 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4328 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4329 true, GetRequestHeaders("GET", "http", "/"),
4330 GetNthClientInitiatedBidirectionalStreamId(0),
4331 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434332 mock_quic_data.AddRead(
4333 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334334 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434335 GetResponseHeaders("200 OK"), &response_header_offset));
4336 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334337 ASYNC, ConstructServerDataPacket(
4338 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414339 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434340 mock_quic_data.AddWrite(
4341 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274342 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4343 mock_quic_data.AddRead(ASYNC, 0); // EOF
4344
4345 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4346
4347 AddHangingNonAlternateProtocolSocketData();
4348
4349 TestProxyDelegate test_proxy_delegate;
4350
Lily Houghton8c2f97d2018-01-22 05:06:594351 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494352 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274353
4354 test_proxy_delegate.set_alternative_proxy_server(
4355 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524356 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274357
4358 request_.url = GURL("http://mail.example.org/");
4359
4360 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564361 QuicStreamFactoryPeer::SetAlarmFactory(
4362 session_->quic_stream_factory(),
4363 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4364 &clock_));
tbansal6490783c2016-09-20 17:55:274365
4366 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4367 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4368 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4369 1);
4370
4371 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4372 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4373 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4374 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4375 1);
4376}
4377
Ryan Hamilton8d9ee76e2018-05-29 23:52:524378// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454379// even if alternative service destination is different.
4380TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344381 session_params_.quic_allow_remote_alt_svc = true;
Ryan Hamiltonabad59e2019-06-06 04:02:594382 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524383 quic::QuicStreamOffset request_header_offset(0);
4384 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454385
rch5cb522462017-04-25 20:18:364386 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434387 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454388 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434389 mock_quic_data.AddWrite(
4390 SYNCHRONOUS,
4391 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334392 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434393 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4394 mock_quic_data.AddRead(
4395 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334396 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434397 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434398 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434399 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334400 ASYNC, ConstructServerDataPacket(
4401 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414402 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434403 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304404
bnc359ed2a2016-04-29 20:43:454405 // Second request.
alyssar2adf3ac2016-05-03 17:12:584406 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334407 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4408 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4409 true, GetRequestHeaders("GET", "https", "/"),
4410 GetNthClientInitiatedBidirectionalStreamId(0),
4411 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434412 mock_quic_data.AddRead(
4413 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334414 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434415 GetResponseHeaders("200 OK"), &response_header_offset));
4416 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334417 ASYNC, ConstructServerDataPacket(
4418 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414419 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434420 mock_quic_data.AddWrite(
4421 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304422 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4423 mock_quic_data.AddRead(ASYNC, 0); // EOF
4424
4425 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454426
4427 AddHangingNonAlternateProtocolSocketData();
4428 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304429
rch3f4b8452016-02-23 16:59:324430 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564431 QuicStreamFactoryPeer::SetAlarmFactory(
4432 session_->quic_stream_factory(),
4433 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4434 &clock_));
zhongyi32569c62016-01-08 02:54:304435
bnc359ed2a2016-04-29 20:43:454436 const char destination1[] = "first.example.com";
4437 const char destination2[] = "second.example.com";
4438
4439 // Set up alternative service entry to destination1.
4440 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214441 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454442 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214443 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444444 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454445 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524446 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454447 SendRequestAndExpectQuicResponse("hello!");
4448
4449 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214450 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214451 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444452 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524453 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454454 // even though alternative service destination is different.
4455 SendRequestAndExpectQuicResponse("hello!");
4456}
4457
4458// Pool to existing session with matching destination and matching certificate
4459// even if origin is different, and even if the alternative service with
4460// matching destination is not the first one on the list.
4461TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344462 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454463 GURL origin1 = request_.url;
4464 GURL origin2("https://www.example.org/");
4465 ASSERT_NE(origin1.host(), origin2.host());
4466
Ryan Hamiltonabad59e2019-06-06 04:02:594467 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524468 quic::QuicStreamOffset request_header_offset(0);
4469 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454470
rch5cb522462017-04-25 20:18:364471 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434472 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454473 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434474 mock_quic_data.AddWrite(
4475 SYNCHRONOUS,
4476 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334477 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434478 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4479 mock_quic_data.AddRead(
4480 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334481 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434482 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434483 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434484 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334485 ASYNC, ConstructServerDataPacket(
4486 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414487 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434488 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454489
4490 // Second request.
Yixin Wang079ad542018-01-11 04:06:054491 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174492 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4493 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054494 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174495 QuicTestPacketMaker server_maker2(
4496 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4497 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584498 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434499 SYNCHRONOUS,
4500 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334501 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434502 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334503 GetNthClientInitiatedBidirectionalStreamId(0),
4504 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434505 mock_quic_data.AddRead(
4506 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334507 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434508 GetResponseHeaders("200 OK"), &response_header_offset));
4509 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334510 ASYNC, ConstructServerDataPacket(
4511 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414512 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434513 mock_quic_data.AddWrite(
4514 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454515 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4516 mock_quic_data.AddRead(ASYNC, 0); // EOF
4517
4518 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4519
4520 AddHangingNonAlternateProtocolSocketData();
4521 AddHangingNonAlternateProtocolSocketData();
4522
4523 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564524 QuicStreamFactoryPeer::SetAlarmFactory(
4525 session_->quic_stream_factory(),
4526 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4527 &clock_));
bnc359ed2a2016-04-29 20:43:454528
4529 const char destination1[] = "first.example.com";
4530 const char destination2[] = "second.example.com";
4531
4532 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214533 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454534 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214535 http_server_properties_.SetQuicAlternativeService(
4536 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444537 supported_versions_);
bnc359ed2a2016-04-29 20:43:454538
4539 // Set up multiple alternative service entries for |origin2|,
4540 // the first one with a different destination as for |origin1|,
4541 // the second one with the same. The second one should be used,
4542 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214543 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454544 AlternativeServiceInfoVector alternative_services;
4545 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214546 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4547 alternative_service2, expiration,
4548 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454549 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214550 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4551 alternative_service1, expiration,
4552 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454553 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4554 alternative_services);
bnc359ed2a2016-04-29 20:43:454555 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524556 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454557 SendRequestAndExpectQuicResponse("hello!");
4558
4559 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524560 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454561 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584562
bnc359ed2a2016-04-29 20:43:454563 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304564}
4565
4566// Multiple origins have listed the same alternative services. When there's a
4567// existing QUIC session opened by a request to other origin,
4568// if the cert is valid, should select this QUIC session to make the request
4569// if this is also the first existing QUIC session.
4570TEST_P(QuicNetworkTransactionTest,
4571 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344572 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294573 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304574
rch9ae5b3b2016-02-11 00:36:294575 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304576 MockRead http_reads[] = {
4577 MockRead("HTTP/1.1 200 OK\r\n"),
4578 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294579 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304580 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4581 MockRead(ASYNC, OK)};
4582
Ryan Sleevib8d7ea02018-05-07 20:01:014583 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304584 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084585 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304586 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4587
4588 // HTTP data for request to mail.example.org.
4589 MockRead http_reads2[] = {
4590 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294591 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304592 MockRead("hello world from mail.example.org"),
4593 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4594 MockRead(ASYNC, OK)};
4595
Ryan Sleevib8d7ea02018-05-07 20:01:014596 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304597 socket_factory_.AddSocketDataProvider(&http_data2);
4598 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4599
Ryan Hamilton8d9ee76e2018-05-29 23:52:524600 quic::QuicStreamOffset request_header_offset = 0;
4601 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304602
Yixin Wang079ad542018-01-11 04:06:054603 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174604 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4605 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054606 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584607 server_maker_.set_hostname("www.example.org");
4608 client_maker_.set_hostname("www.example.org");
Ryan Hamiltonabad59e2019-06-06 04:02:594609 MockQuicData mock_quic_data(version_);
rch5cb522462017-04-25 20:18:364610 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434611 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304612 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584613 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434614 SYNCHRONOUS,
4615 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334616 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434617 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4618
4619 mock_quic_data.AddRead(
4620 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334621 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434622 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434623 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334624 mock_quic_data.AddRead(
4625 ASYNC, ConstructServerDataPacket(
4626 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414627 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434628 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4629 // Second QUIC request data.
4630 mock_quic_data.AddWrite(
4631 SYNCHRONOUS,
4632 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334633 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434634 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334635 GetNthClientInitiatedBidirectionalStreamId(0),
4636 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434637 mock_quic_data.AddRead(
4638 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334639 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434640 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334641 mock_quic_data.AddRead(
4642 ASYNC, ConstructServerDataPacket(
4643 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414644 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434645 mock_quic_data.AddWrite(
4646 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304647 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4648 mock_quic_data.AddRead(ASYNC, 0); // EOF
4649
4650 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304651
rtennetib8e80fb2016-05-16 00:12:094652 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324653 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564654 QuicStreamFactoryPeer::SetAlarmFactory(
4655 session_->quic_stream_factory(),
4656 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4657 &clock_));
zhongyi32569c62016-01-08 02:54:304658
4659 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294660 request_.url = GURL("https://www.example.org/");
4661 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304662 request_.url = GURL("https://mail.example.org/");
4663 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4664
rch9ae5b3b2016-02-11 00:36:294665 // Open a QUIC session to mail.example.org:443 when making request
4666 // to mail.example.org.
4667 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454668 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304669
rch9ae5b3b2016-02-11 00:36:294670 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304671 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454672 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524673}
4674
4675TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524676 MockRead http_reads[] = {
4677 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564678 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524679 MockRead("hello world"),
4680 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4681 MockRead(ASYNC, OK)};
4682
Ryan Sleevib8d7ea02018-05-07 20:01:014683 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524684 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084685 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564686 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524687
rtennetib8e80fb2016-05-16 00:12:094688 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324689 CreateSession();
bncc958faa2015-07-31 18:14:524690
4691 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454692
4693 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344694 AlternativeServiceInfoVector alternative_service_info_vector =
4695 http_server_properties_.GetAlternativeServiceInfos(http_server);
4696 ASSERT_EQ(1u, alternative_service_info_vector.size());
4697 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544698 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344699 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4700 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4701 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524702}
4703
4704TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524705 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564706 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4707 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524708 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4709 MockRead(ASYNC, OK)};
4710
Ryan Sleevib8d7ea02018-05-07 20:01:014711 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524712 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084713 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564714 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524715
Ryan Hamiltonabad59e2019-06-06 04:02:594716 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524717 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364718 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434719 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4720 mock_quic_data.AddWrite(
4721 SYNCHRONOUS,
4722 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334723 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434724 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434725 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334726 ASYNC, ConstructServerResponseHeadersPacket(
4727 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4728 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434729 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334730 mock_quic_data.AddRead(
4731 ASYNC, ConstructServerDataPacket(
4732 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414733 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434734 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524735 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4736 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524737
4738 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4739
rtennetib8e80fb2016-05-16 00:12:094740 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324741 CreateSession();
bncc958faa2015-07-31 18:14:524742
bnc3472afd2016-11-17 15:27:214743 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524744 HostPortPair::FromURL(request_.url));
4745 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4746 alternative_service);
4747 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4748 alternative_service));
4749
4750 SendRequestAndExpectHttpResponse("hello world");
4751 SendRequestAndExpectQuicResponse("hello!");
4752
mmenkee24011922015-12-17 22:12:594753 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524754
4755 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4756 alternative_service));
rchac7f35e2017-03-15 20:42:304757 EXPECT_NE(nullptr,
4758 http_server_properties_.GetServerNetworkStats(
4759 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524760}
4761
bncc958faa2015-07-31 18:14:524762TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524763 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564764 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4765 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524766 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4767 MockRead(ASYNC, OK)};
4768
Ryan Sleevib8d7ea02018-05-07 20:01:014769 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524770 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564771 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524772
Ryan Hamiltonabad59e2019-06-06 04:02:594773 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524774 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364775 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434776 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4777 mock_quic_data.AddWrite(
4778 SYNCHRONOUS,
4779 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334780 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434781 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434782 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334783 ASYNC, ConstructServerResponseHeadersPacket(
4784 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4785 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434786 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334787 mock_quic_data.AddRead(
4788 ASYNC, ConstructServerDataPacket(
4789 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414790 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434791 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524792 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4793
4794 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4795
4796 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324797 CreateSession();
bncc958faa2015-07-31 18:14:524798
4799 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4800 SendRequestAndExpectHttpResponse("hello world");
4801}
4802
tbansalc3308d72016-08-27 10:25:044803// Tests that the connection to an HTTPS proxy is raced with an available
4804// alternative proxy server.
4805TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274806 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594807 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494808 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044809
Ryan Hamiltonabad59e2019-06-06 04:02:594810 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524811 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364812 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434813 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4814 mock_quic_data.AddWrite(
4815 SYNCHRONOUS,
4816 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334817 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434818 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434819 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334820 ASYNC, ConstructServerResponseHeadersPacket(
4821 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4822 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434823 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334824 mock_quic_data.AddRead(
4825 ASYNC, ConstructServerDataPacket(
4826 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414827 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434828 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044829 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4830 mock_quic_data.AddRead(ASYNC, 0); // EOF
4831
4832 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4833
4834 // There is no need to set up main job, because no attempt will be made to
4835 // speak to the proxy over TCP.
4836 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044837 TestProxyDelegate test_proxy_delegate;
4838 const HostPortPair host_port_pair("mail.example.org", 443);
4839
4840 test_proxy_delegate.set_alternative_proxy_server(
4841 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524842 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044843 CreateSession();
4844 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4845
4846 // The main job needs to hang in order to guarantee that the alternative
4847 // proxy server job will "win".
4848 AddHangingNonAlternateProtocolSocketData();
4849
4850 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4851
4852 // Verify that the alternative proxy server is not marked as broken.
4853 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4854
4855 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594856 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274857
4858 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4859 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4860 1);
tbansalc3308d72016-08-27 10:25:044861}
4862
bnc1c196c6e2016-05-28 13:51:484863TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304864 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274865 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304866
4867 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564868 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294869 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564870 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304871
4872 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564873 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484874 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564875 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304876
Ryan Sleevib8d7ea02018-05-07 20:01:014877 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504878 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084879 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504880 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304881
4882 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454883 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304884 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454885 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304886 };
Ryan Sleevib8d7ea02018-05-07 20:01:014887 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504888 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304889
4890 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014891 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504892 socket_factory_.AddSocketDataProvider(&http_data2);
4893 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304894
bnc912a04b2016-04-20 14:19:504895 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304896
4897 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304898 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174899 ASSERT_TRUE(http_data.AllReadDataConsumed());
4900 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304901
4902 // Now run the second request in which the QUIC socket hangs,
4903 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304904 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454905 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304906
rch37de576c2015-05-17 20:28:174907 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4908 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454909 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304910}
4911
[email protected]1e960032013-12-20 19:00:204912TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594913 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524914 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:034915 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434916 mock_quic_data.AddWrite(
4917 SYNCHRONOUS,
4918 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334919 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434920 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434921 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334922 ASYNC, ConstructServerResponseHeadersPacket(
4923 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4924 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434925 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334926 mock_quic_data.AddRead(
4927 ASYNC, ConstructServerDataPacket(
4928 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414929 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434930 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504931 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594932 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484933
rcha5399e02015-04-21 19:32:044934 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484935
rtennetib8e80fb2016-05-16 00:12:094936 // The non-alternate protocol job needs to hang in order to guarantee that
4937 // the alternate-protocol job will "win".
4938 AddHangingNonAlternateProtocolSocketData();
4939
rch3f4b8452016-02-23 16:59:324940 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274941 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194942 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304943
4944 EXPECT_EQ(nullptr,
4945 http_server_properties_.GetServerNetworkStats(
4946 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484947}
4948
[email protected]1e960032013-12-20 19:00:204949TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
Ryan Hamiltonabad59e2019-06-06 04:02:594950 MockQuicData mock_quic_data(version_);
Michael Warres167db3e2019-03-01 21:38:034951 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334952 mock_quic_data.AddWrite(
4953 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4954 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4955 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434956 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334957 ASYNC, ConstructServerResponseHeadersPacket(
4958 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4959 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434960 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334961 mock_quic_data.AddRead(
4962 ASYNC, ConstructServerDataPacket(
4963 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414964 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434965 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504966 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594967 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044968 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274969
4970 // In order for a new QUIC session to be established via alternate-protocol
4971 // without racing an HTTP connection, we need the host resolution to happen
4972 // synchronously.
4973 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294974 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564975 "");
[email protected]3a120a6b2013-06-25 01:08:274976
rtennetib8e80fb2016-05-16 00:12:094977 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324978 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274979 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274980 SendRequestAndExpectQuicResponse("hello!");
4981}
4982
[email protected]0fc924b2014-03-31 04:34:154983TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494984 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4985 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154986
4987 // Since we are using a proxy, the QUIC job will not succeed.
4988 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294989 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4990 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564991 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154992
4993 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564994 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484995 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564996 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154997
Ryan Sleevib8d7ea02018-05-07 20:01:014998 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154999 socket_factory_.AddSocketDataProvider(&http_data);
5000
5001 // In order for a new QUIC session to be established via alternate-protocol
5002 // without racing an HTTP connection, we need the host resolution to happen
5003 // synchronously.
5004 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295005 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565006 "");
[email protected]0fc924b2014-03-31 04:34:155007
rch9ae5b3b2016-02-11 00:36:295008 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325009 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275010 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155011 SendRequestAndExpectHttpResponse("hello world");
5012}
5013
[email protected]1e960032013-12-20 19:00:205014TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
Ryan Hamiltonabad59e2019-06-06 04:02:595015 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525016 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365017 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435018 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5019 mock_quic_data.AddWrite(
5020 SYNCHRONOUS,
5021 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335022 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435023 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435024 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335025 ASYNC, ConstructServerResponseHeadersPacket(
5026 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5027 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435028 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335029 mock_quic_data.AddRead(
5030 ASYNC, ConstructServerDataPacket(
5031 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415032 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435033 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595034 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045035 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125036
rtennetib8e80fb2016-05-16 00:12:095037 // The non-alternate protocol job needs to hang in order to guarantee that
5038 // the alternate-protocol job will "win".
5039 AddHangingNonAlternateProtocolSocketData();
5040
[email protected]11c05872013-08-20 02:04:125041 // In order for a new QUIC session to be established via alternate-protocol
5042 // without racing an HTTP connection, we need the host resolution to happen
5043 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5044 // connection to the the server, in this test we require confirmation
5045 // before encrypting so the HTTP job will still start.
5046 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295047 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565048 "");
[email protected]11c05872013-08-20 02:04:125049
rch3f4b8452016-02-23 16:59:325050 CreateSession();
[email protected]11c05872013-08-20 02:04:125051 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275052 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125053
bnc691fda62016-08-12 00:43:165054 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125055 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365056 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015057 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125058
5059 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525060 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015061 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505062
bnc691fda62016-08-12 00:43:165063 CheckWasQuicResponse(&trans);
5064 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125065}
5066
Steven Valdez58097ec32018-07-16 18:29:045067TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
Ryan Hamiltonabad59e2019-06-06 04:02:595068 MockQuicData mock_quic_data(version_);
Steven Valdez58097ec32018-07-16 18:29:045069 quic::QuicStreamOffset client_header_stream_offset = 0;
5070 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035071 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045072 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335073 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5074 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5075 true, GetRequestHeaders("GET", "https", "/"),
5076 &client_header_stream_offset));
5077 mock_quic_data.AddRead(
5078 ASYNC,
5079 ConstructServerResponseHeadersPacket(
5080 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5081 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5082 mock_quic_data.AddWrite(SYNCHRONOUS,
5083 ConstructClientAckAndRstPacket(
5084 2, GetNthClientInitiatedBidirectionalStreamId(0),
5085 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045086
5087 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5088
5089 spdy::SpdySettingsIR settings_frame;
5090 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5091 quic::kDefaultMaxUncompressedHeaderSize);
5092 spdy::SpdySerializedFrame spdy_frame(
5093 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5094 mock_quic_data.AddWrite(
5095 SYNCHRONOUS,
5096 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565097 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5098 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045099 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5100 client_header_stream_offset += spdy_frame.size();
5101
5102 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335103 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5104 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5105 true, GetRequestHeaders("GET", "https", "/"),
5106 GetNthClientInitiatedBidirectionalStreamId(0),
5107 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045108 mock_quic_data.AddRead(
5109 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335110 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045111 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:435112 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045113 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335114 ASYNC, ConstructServerDataPacket(
5115 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415116 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045117 mock_quic_data.AddWrite(
5118 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5119 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5120 mock_quic_data.AddRead(ASYNC, 0); // EOF
5121
5122 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5123
5124 // In order for a new QUIC session to be established via alternate-protocol
5125 // without racing an HTTP connection, we need the host resolution to happen
5126 // synchronously.
5127 host_resolver_.set_synchronous_mode(true);
5128 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5129 "");
Steven Valdez58097ec32018-07-16 18:29:045130
5131 AddHangingNonAlternateProtocolSocketData();
5132 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275133 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565134 QuicStreamFactoryPeer::SetAlarmFactory(
5135 session_->quic_stream_factory(),
5136 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5137 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045138
5139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5140 TestCompletionCallback callback;
5141 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5143
5144 // Confirm the handshake after the 425 Too Early.
5145 base::RunLoop().RunUntilIdle();
5146
5147 // The handshake hasn't been confirmed yet, so the retry should not have
5148 // succeeded.
5149 EXPECT_FALSE(callback.have_result());
5150
5151 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5152 quic::QuicSession::HANDSHAKE_CONFIRMED);
5153
5154 EXPECT_THAT(callback.WaitForResult(), IsOk());
5155 CheckWasQuicResponse(&trans);
5156 CheckResponseData(&trans, "hello!");
5157}
5158
5159TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
Ryan Hamiltonabad59e2019-06-06 04:02:595160 MockQuicData mock_quic_data(version_);
Steven Valdez58097ec32018-07-16 18:29:045161 quic::QuicStreamOffset client_header_stream_offset = 0;
5162 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035163 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045164 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335165 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5166 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5167 true, GetRequestHeaders("GET", "https", "/"),
5168 &client_header_stream_offset));
5169 mock_quic_data.AddRead(
5170 ASYNC,
5171 ConstructServerResponseHeadersPacket(
5172 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5173 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5174 mock_quic_data.AddWrite(SYNCHRONOUS,
5175 ConstructClientAckAndRstPacket(
5176 2, GetNthClientInitiatedBidirectionalStreamId(0),
5177 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045178
5179 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5180
5181 spdy::SpdySettingsIR settings_frame;
5182 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5183 quic::kDefaultMaxUncompressedHeaderSize);
5184 spdy::SpdySerializedFrame spdy_frame(
5185 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5186 mock_quic_data.AddWrite(
5187 SYNCHRONOUS,
5188 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565189 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5190 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045191 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5192 client_header_stream_offset += spdy_frame.size();
5193
5194 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335195 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5196 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5197 true, GetRequestHeaders("GET", "https", "/"),
5198 GetNthClientInitiatedBidirectionalStreamId(0),
5199 &client_header_stream_offset));
5200 mock_quic_data.AddRead(
5201 ASYNC,
5202 ConstructServerResponseHeadersPacket(
5203 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5204 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5205 mock_quic_data.AddWrite(SYNCHRONOUS,
5206 ConstructClientAckAndRstPacket(
5207 5, GetNthClientInitiatedBidirectionalStreamId(1),
5208 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045209 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5210 mock_quic_data.AddRead(ASYNC, 0); // EOF
5211
5212 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5213
5214 // In order for a new QUIC session to be established via alternate-protocol
5215 // without racing an HTTP connection, we need the host resolution to happen
5216 // synchronously.
5217 host_resolver_.set_synchronous_mode(true);
5218 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5219 "");
Steven Valdez58097ec32018-07-16 18:29:045220
5221 AddHangingNonAlternateProtocolSocketData();
5222 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275223 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565224 QuicStreamFactoryPeer::SetAlarmFactory(
5225 session_->quic_stream_factory(),
5226 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5227 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045228
5229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5230 TestCompletionCallback callback;
5231 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5233
5234 // Confirm the handshake after the 425 Too Early.
5235 base::RunLoop().RunUntilIdle();
5236
5237 // The handshake hasn't been confirmed yet, so the retry should not have
5238 // succeeded.
5239 EXPECT_FALSE(callback.have_result());
5240
5241 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5242 quic::QuicSession::HANDSHAKE_CONFIRMED);
5243
5244 EXPECT_THAT(callback.WaitForResult(), IsOk());
5245 const HttpResponseInfo* response = trans.GetResponseInfo();
5246 ASSERT_TRUE(response != nullptr);
5247 ASSERT_TRUE(response->headers.get() != nullptr);
5248 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5249 EXPECT_TRUE(response->was_fetched_via_spdy);
5250 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565251 EXPECT_EQ(
5252 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5253 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045254}
5255
zhongyica364fbb2015-12-12 03:39:125256TEST_P(QuicNetworkTransactionTest,
5257 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485258 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595259 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525260 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365261 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435262 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5263 mock_quic_data.AddWrite(
5264 SYNCHRONOUS,
5265 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335266 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435267 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125268 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525269 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435270 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125271 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5272
5273 // The non-alternate protocol job needs to hang in order to guarantee that
5274 // the alternate-protocol job will "win".
5275 AddHangingNonAlternateProtocolSocketData();
5276
5277 // In order for a new QUIC session to be established via alternate-protocol
5278 // without racing an HTTP connection, we need the host resolution to happen
5279 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5280 // connection to the the server, in this test we require confirmation
5281 // before encrypting so the HTTP job will still start.
5282 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295283 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125284 "");
zhongyica364fbb2015-12-12 03:39:125285
rch3f4b8452016-02-23 16:59:325286 CreateSession();
zhongyica364fbb2015-12-12 03:39:125287 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275288 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125289
bnc691fda62016-08-12 00:43:165290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125291 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365292 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015293 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125294
5295 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525296 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015297 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125298
5299 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525300 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125301
bnc691fda62016-08-12 00:43:165302 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125303 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525304 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5305 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125306}
5307
5308TEST_P(QuicNetworkTransactionTest,
5309 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485310 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595311 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525312 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365313 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435314 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5315 mock_quic_data.AddWrite(
5316 SYNCHRONOUS,
5317 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335318 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435319 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215320 // Peer sending data from an non-existing stream causes this end to raise
5321 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335322 mock_quic_data.AddRead(
5323 ASYNC, ConstructServerRstPacket(
5324 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5325 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215326 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525327 mock_quic_data.AddWrite(
5328 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5329 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5330 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5332
5333 // The non-alternate protocol job needs to hang in order to guarantee that
5334 // the alternate-protocol job will "win".
5335 AddHangingNonAlternateProtocolSocketData();
5336
5337 // In order for a new QUIC session to be established via alternate-protocol
5338 // without racing an HTTP connection, we need the host resolution to happen
5339 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5340 // connection to the the server, in this test we require confirmation
5341 // before encrypting so the HTTP job will still start.
5342 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295343 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125344 "");
zhongyica364fbb2015-12-12 03:39:125345
rch3f4b8452016-02-23 16:59:325346 CreateSession();
zhongyica364fbb2015-12-12 03:39:125347 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275348 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125349
bnc691fda62016-08-12 00:43:165350 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125351 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365352 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015353 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125354
5355 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525356 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015357 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125358 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525359 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125360
bnc691fda62016-08-12 00:43:165361 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525362 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125363}
5364
rchcd5f1c62016-06-23 02:43:485365TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
Ryan Hamiltonabad59e2019-06-06 04:02:595366 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525367 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365368 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435369 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5370 mock_quic_data.AddWrite(
5371 SYNCHRONOUS,
5372 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335373 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435374 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485375 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335376 mock_quic_data.AddRead(
5377 ASYNC, ConstructServerResponseHeadersPacket(
5378 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5379 GetResponseHeaders("200 OK")));
5380 mock_quic_data.AddRead(
5381 ASYNC, ConstructServerRstPacket(
5382 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5383 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435384 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485385 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5386 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5387
5388 // The non-alternate protocol job needs to hang in order to guarantee that
5389 // the alternate-protocol job will "win".
5390 AddHangingNonAlternateProtocolSocketData();
5391
5392 // In order for a new QUIC session to be established via alternate-protocol
5393 // without racing an HTTP connection, we need the host resolution to happen
5394 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5395 // connection to the the server, in this test we require confirmation
5396 // before encrypting so the HTTP job will still start.
5397 host_resolver_.set_synchronous_mode(true);
5398 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5399 "");
rchcd5f1c62016-06-23 02:43:485400
5401 CreateSession();
5402 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275403 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485404
bnc691fda62016-08-12 00:43:165405 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485406 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365407 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485409
5410 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525411 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485412 // Read the headers.
robpercival214763f2016-07-01 23:27:015413 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485414
bnc691fda62016-08-12 00:43:165415 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485416 ASSERT_TRUE(response != nullptr);
5417 ASSERT_TRUE(response->headers.get() != nullptr);
5418 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5419 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525420 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565421 EXPECT_EQ(
5422 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5423 response->connection_info);
rchcd5f1c62016-06-23 02:43:485424
5425 std::string response_data;
bnc691fda62016-08-12 00:43:165426 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485427}
5428
5429TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485430 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltonabad59e2019-06-06 04:02:595431 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525432 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365433 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435434 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5435 mock_quic_data.AddWrite(
5436 SYNCHRONOUS,
5437 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335438 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435439 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335440 mock_quic_data.AddRead(
5441 ASYNC, ConstructServerRstPacket(
5442 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5443 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485444 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5445 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5446
5447 // The non-alternate protocol job needs to hang in order to guarantee that
5448 // the alternate-protocol job will "win".
5449 AddHangingNonAlternateProtocolSocketData();
5450
5451 // In order for a new QUIC session to be established via alternate-protocol
5452 // without racing an HTTP connection, we need the host resolution to happen
5453 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5454 // connection to the the server, in this test we require confirmation
5455 // before encrypting so the HTTP job will still start.
5456 host_resolver_.set_synchronous_mode(true);
5457 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5458 "");
rchcd5f1c62016-06-23 02:43:485459
5460 CreateSession();
5461 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275462 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485463
bnc691fda62016-08-12 00:43:165464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485465 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365466 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485468
5469 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525470 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485471 // Read the headers.
robpercival214763f2016-07-01 23:27:015472 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485473}
5474
[email protected]1e960032013-12-20 19:00:205475TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305476 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525477 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585478 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305479 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505480 MockRead(ASYNC, close->data(), close->length()),
5481 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5482 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305483 };
Ryan Sleevib8d7ea02018-05-07 20:01:015484 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305485 socket_factory_.AddSocketDataProvider(&quic_data);
5486
5487 // Main job which will succeed even though the alternate job fails.
5488 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025489 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5490 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5491 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305492
Ryan Sleevib8d7ea02018-05-07 20:01:015493 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305494 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565495 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305496
rch3f4b8452016-02-23 16:59:325497 CreateSession();
David Schinazic8281052019-01-24 06:14:175498 AddQuicAlternateProtocolMapping(
5499 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195500 SendRequestAndExpectHttpResponse("hello from http");
5501 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305502}
5503
[email protected]1e960032013-12-20 19:00:205504TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595505 // Alternate-protocol job
5506 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025507 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595508 };
Ryan Sleevib8d7ea02018-05-07 20:01:015509 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595510 socket_factory_.AddSocketDataProvider(&quic_data);
5511
5512 // Main job which will succeed even though the alternate job fails.
5513 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025514 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5515 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5516 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595517
Ryan Sleevib8d7ea02018-05-07 20:01:015518 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595519 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565520 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595521
rch3f4b8452016-02-23 16:59:325522 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595523
Ryan Hamilton9835e662018-08-02 05:36:275524 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195525 SendRequestAndExpectHttpResponse("hello from http");
5526 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595527}
5528
[email protected]00c159f2014-05-21 22:38:165529TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535530 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165531 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025532 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165533 };
Ryan Sleevib8d7ea02018-05-07 20:01:015534 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165535 socket_factory_.AddSocketDataProvider(&quic_data);
5536
[email protected]eb71ab62014-05-23 07:57:535537 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165538 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025539 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165540 };
5541
Ryan Sleevib8d7ea02018-05-07 20:01:015542 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165543 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5544 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565545 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165546
rtennetib8e80fb2016-05-16 00:12:095547 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325548 CreateSession();
[email protected]00c159f2014-05-21 22:38:165549
Ryan Hamilton9835e662018-08-02 05:36:275550 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165551 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165552 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165553 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5555 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165556 ExpectQuicAlternateProtocolMapping();
5557}
5558
Zhongyi Shia0cef1082017-08-25 01:49:505559TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5560 // Tests that TCP job is delayed and QUIC job does not require confirmation
5561 // if QUIC was recently supported on the same IP on start.
5562
5563 // Set QUIC support on the last IP address, which is same with the local IP
5564 // address. Require confirmation mode will be turned off immediately when
5565 // local IP address is sorted out after we configure the UDP socket.
5566 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5567
Ryan Hamiltonabad59e2019-06-06 04:02:595568 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525569 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035570 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435571 mock_quic_data.AddWrite(
5572 SYNCHRONOUS,
5573 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335574 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435575 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435576 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335577 ASYNC, ConstructServerResponseHeadersPacket(
5578 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5579 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435580 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335581 mock_quic_data.AddRead(
5582 ASYNC, ConstructServerDataPacket(
5583 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415584 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435585 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505586 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5587 mock_quic_data.AddRead(ASYNC, 0); // EOF
5588
5589 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5590 // No HTTP data is mocked as TCP job never starts in this case.
5591
5592 CreateSession();
5593 // QuicStreamFactory by default requires confirmation on construction.
5594 session_->quic_stream_factory()->set_require_confirmation(true);
5595
Ryan Hamilton9835e662018-08-02 05:36:275596 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505597
5598 // Stall host resolution so that QUIC job will not succeed synchronously.
5599 // Socket will not be configured immediately and QUIC support is not sorted
5600 // out, TCP job will still be delayed as server properties indicates QUIC
5601 // support on last IP address.
5602 host_resolver_.set_synchronous_mode(false);
5603
5604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5605 TestCompletionCallback callback;
5606 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5607 IsError(ERR_IO_PENDING));
5608 // Complete host resolution in next message loop so that QUIC job could
5609 // proceed.
5610 base::RunLoop().RunUntilIdle();
5611 EXPECT_THAT(callback.WaitForResult(), IsOk());
5612
5613 CheckWasQuicResponse(&trans);
5614 CheckResponseData(&trans, "hello!");
5615}
5616
5617TEST_P(QuicNetworkTransactionTest,
5618 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5619 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5620 // was recently supported on a different IP address on start.
5621
5622 // Set QUIC support on the last IP address, which is different with the local
5623 // IP address. Require confirmation mode will remain when local IP address is
5624 // sorted out after we configure the UDP socket.
5625 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5626
Ryan Hamiltonabad59e2019-06-06 04:02:595627 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525628 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505629 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435630 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5631 mock_quic_data.AddWrite(
5632 SYNCHRONOUS,
5633 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335634 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435635 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435636 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335637 ASYNC, ConstructServerResponseHeadersPacket(
5638 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5639 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435640 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335641 mock_quic_data.AddRead(
5642 ASYNC, ConstructServerDataPacket(
5643 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415644 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435645 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505646 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5647 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5648 // No HTTP data is mocked as TCP job will be delayed and never starts.
5649
5650 CreateSession();
5651 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275652 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505653
5654 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5655 // Socket will not be configured immediately and QUIC support is not sorted
5656 // out, TCP job will still be delayed as server properties indicates QUIC
5657 // support on last IP address.
5658 host_resolver_.set_synchronous_mode(false);
5659
5660 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5661 TestCompletionCallback callback;
5662 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5663 IsError(ERR_IO_PENDING));
5664
5665 // Complete host resolution in next message loop so that QUIC job could
5666 // proceed.
5667 base::RunLoop().RunUntilIdle();
5668 // Explicitly confirm the handshake so that QUIC job could succeed.
5669 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525670 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505671 EXPECT_THAT(callback.WaitForResult(), IsOk());
5672
5673 CheckWasQuicResponse(&trans);
5674 CheckResponseData(&trans, "hello!");
5675}
5676
Ryan Hamilton75f197262017-08-17 14:00:075677TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5678 // Test that NetErrorDetails is correctly populated, even if the
5679 // handshake has not yet been confirmed and no stream has been created.
5680
5681 // QUIC job will pause. When resumed, it will fail.
Ryan Hamiltonabad59e2019-06-06 04:02:595682 MockQuicData mock_quic_data(version_);
Ryan Hamilton75f197262017-08-17 14:00:075683 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5684 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5685 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5686
5687 // Main job will also fail.
5688 MockRead http_reads[] = {
5689 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5690 };
5691
Ryan Sleevib8d7ea02018-05-07 20:01:015692 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075693 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5694 socket_factory_.AddSocketDataProvider(&http_data);
5695 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5696
5697 AddHangingNonAlternateProtocolSocketData();
5698 CreateSession();
5699 // Require handshake confirmation to ensure that no QUIC streams are
5700 // created, and to ensure that the TCP job does not wait for the QUIC
5701 // job to fail before it starts.
5702 session_->quic_stream_factory()->set_require_confirmation(true);
5703
Ryan Hamilton9835e662018-08-02 05:36:275704 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075705 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5706 TestCompletionCallback callback;
5707 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5708 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5709 // Allow the TCP job to fail.
5710 base::RunLoop().RunUntilIdle();
5711 // Now let the QUIC job fail.
5712 mock_quic_data.Resume();
5713 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5714 ExpectQuicAlternateProtocolMapping();
5715 NetErrorDetails details;
5716 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525717 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075718}
5719
[email protected]1e960032013-12-20 19:00:205720TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455721 // Alternate-protocol job
5722 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025723 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455724 };
Ryan Sleevib8d7ea02018-05-07 20:01:015725 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455726 socket_factory_.AddSocketDataProvider(&quic_data);
5727
[email protected]c92c1b52014-05-31 04:16:065728 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015729 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065730 socket_factory_.AddSocketDataProvider(&quic_data2);
5731
[email protected]4d283b32013-10-17 12:57:275732 // Final job that will proceed when the QUIC job fails.
5733 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025734 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5735 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5736 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275737
Ryan Sleevib8d7ea02018-05-07 20:01:015738 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275739 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565740 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275741
rtennetiafccbc062016-05-16 18:21:145742 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325743 CreateSession();
[email protected]77c6c162013-08-17 02:57:455744
Ryan Hamilton9835e662018-08-02 05:36:275745 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455746
[email protected]4d283b32013-10-17 12:57:275747 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455748
5749 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275750
rch37de576c2015-05-17 20:28:175751 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5752 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455753}
5754
[email protected]93b31772014-06-19 08:03:355755TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035756 // Alternate-protocol job
5757 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595758 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035759 };
Ryan Sleevib8d7ea02018-05-07 20:01:015760 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035761 socket_factory_.AddSocketDataProvider(&quic_data);
5762
5763 // Main job that will proceed when the QUIC job fails.
5764 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025765 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5766 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5767 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035768
Ryan Sleevib8d7ea02018-05-07 20:01:015769 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035770 socket_factory_.AddSocketDataProvider(&http_data);
5771
rtennetib8e80fb2016-05-16 00:12:095772 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325773 CreateSession();
[email protected]65768442014-06-06 23:37:035774
Ryan Hamilton9835e662018-08-02 05:36:275775 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035776
5777 SendRequestAndExpectHttpResponse("hello from http");
5778}
5779
[email protected]eb71ab62014-05-23 07:57:535780TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335781 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015782 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495783 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335784 socket_factory_.AddSocketDataProvider(&quic_data);
5785
5786 // Main job which will succeed even though the alternate job fails.
5787 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025788 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5789 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5790 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335791
Ryan Sleevib8d7ea02018-05-07 20:01:015792 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335793 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565794 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335795
rch3f4b8452016-02-23 16:59:325796 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275797 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335798 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535799
5800 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335801}
5802
[email protected]4fee9672014-01-08 14:47:155803TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Ryan Hamiltonabad59e2019-06-06 04:02:595804 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175805 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5806 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045807 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155808
5809 // When the QUIC connection fails, we will try the request again over HTTP.
5810 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485811 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565812 MockRead("hello world"),
5813 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5814 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155815
Ryan Sleevib8d7ea02018-05-07 20:01:015816 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155817 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565818 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155819
5820 // In order for a new QUIC session to be established via alternate-protocol
5821 // without racing an HTTP connection, we need the host resolution to happen
5822 // synchronously.
5823 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295824 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565825 "");
[email protected]4fee9672014-01-08 14:47:155826
rch3f4b8452016-02-23 16:59:325827 CreateSession();
David Schinazic8281052019-01-24 06:14:175828 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5829 AddQuicAlternateProtocolMapping(
5830 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155831 SendRequestAndExpectHttpResponse("hello world");
5832}
5833
tbansalc3308d72016-08-27 10:25:045834// For an alternative proxy that supports QUIC, test that the request is
5835// successfully fetched by the main job when the alternate proxy job encounters
5836// an error.
5837TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5838 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5839}
5840TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5841 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5842}
5843TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5844 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5845}
5846TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5847 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5848}
5849TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5850 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5851}
5852TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5853 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5854}
5855TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5856 TestAlternativeProxy(ERR_IO_PENDING);
5857}
5858TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5859 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5860}
5861
5862TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
Ryan Hamiltonabad59e2019-06-06 04:02:595863 MockQuicData mock_quic_data(version_);
David Schinazic8281052019-01-24 06:14:175864 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5865 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335866 mock_quic_data.AddWrite(
5867 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5868 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5869 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435870 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045871 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5872
5873 // When the QUIC connection fails, we will try the request again over HTTP.
5874 MockRead http_reads[] = {
5875 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5876 MockRead("hello world"),
5877 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5878 MockRead(ASYNC, OK)};
5879
Ryan Sleevib8d7ea02018-05-07 20:01:015880 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045881 socket_factory_.AddSocketDataProvider(&http_data);
5882 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5883
5884 TestProxyDelegate test_proxy_delegate;
5885 const HostPortPair host_port_pair("myproxy.org", 443);
5886 test_proxy_delegate.set_alternative_proxy_server(
5887 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5888 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5889
Ramin Halavatica8d5252018-03-12 05:33:495890 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5891 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525892 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045893 request_.url = GURL("http://mail.example.org/");
5894
5895 // In order for a new QUIC session to be established via alternate-protocol
5896 // without racing an HTTP connection, we need the host resolution to happen
5897 // synchronously.
5898 host_resolver_.set_synchronous_mode(true);
5899 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045900
5901 CreateSession();
David Schinazic8281052019-01-24 06:14:175902 crypto_client_stream_factory_.set_handshake_mode(
5903 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045904 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595905 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165906 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045907}
5908
bnc508835902015-05-12 20:10:295909TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585910 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385911 EXPECT_FALSE(
5912 test_socket_performance_watcher_factory_.rtt_notification_received());
Ryan Hamiltonabad59e2019-06-06 04:02:595913 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525914 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365915 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435916 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5917 mock_quic_data.AddWrite(
5918 SYNCHRONOUS,
5919 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335920 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435921 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435922 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335923 ASYNC, ConstructServerResponseHeadersPacket(
5924 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5925 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435926 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335927 mock_quic_data.AddRead(
5928 ASYNC, ConstructServerDataPacket(
5929 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415930 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435931 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505932 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295933 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5934
bncb07c05532015-05-14 19:07:205935 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095936 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325937 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275938 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295939 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385940 EXPECT_TRUE(
5941 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295942}
5943
zhongyi363c91c2017-03-23 23:16:085944// TODO(zhongyi): disabled this broken test as it was not testing the correct
5945// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5946TEST_P(QuicNetworkTransactionTest,
5947 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275948 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595949 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495950 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045951
5952 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045953
5954 test_proxy_delegate.set_alternative_proxy_server(
5955 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525956 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045957
5958 request_.url = GURL("http://mail.example.org/");
5959
5960 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5961 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015962 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045963 socket_factory_.AddSocketDataProvider(&socket_data);
5964
5965 // The non-alternate protocol job needs to hang in order to guarantee that
5966 // the alternate-protocol job will "win".
5967 AddHangingNonAlternateProtocolSocketData();
5968
5969 CreateSession();
5970 request_.method = "POST";
5971 ChunkedUploadDataStream upload_data(0);
5972 upload_data.AppendData("1", 1, true);
5973
5974 request_.upload_data_stream = &upload_data;
5975
5976 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5977 TestCompletionCallback callback;
5978 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5980 EXPECT_NE(OK, callback.WaitForResult());
5981
5982 // Verify that the alternative proxy server is not marked as broken.
5983 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5984
5985 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595986 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275987
5988 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5989 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5990 1);
tbansalc3308d72016-08-27 10:25:045991}
5992
rtenneti56977812016-01-15 19:26:565993TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415994 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575995 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565996
5997 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5998 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015999 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:566000 socket_factory_.AddSocketDataProvider(&socket_data);
6001
rtennetib8e80fb2016-05-16 00:12:096002 // The non-alternate protocol job needs to hang in order to guarantee that
6003 // the alternate-protocol job will "win".
6004 AddHangingNonAlternateProtocolSocketData();
6005
rtenneti56977812016-01-15 19:26:566006 CreateSession();
6007 request_.method = "POST";
6008 ChunkedUploadDataStream upload_data(0);
6009 upload_data.AppendData("1", 1, true);
6010
6011 request_.upload_data_stream = &upload_data;
6012
bnc691fda62016-08-12 00:43:166013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566014 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166015 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566017 EXPECT_NE(OK, callback.WaitForResult());
6018}
6019
rche11300ef2016-09-02 01:44:286020TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486021 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286022 ScopedMockNetworkChangeNotifier network_change_notifier;
6023 MockNetworkChangeNotifier* mock_ncn =
6024 network_change_notifier.mock_network_change_notifier();
6025 mock_ncn->ForceNetworkHandlesSupported();
6026 mock_ncn->SetConnectedNetworksList(
6027 {kDefaultNetworkForTests, kNewNetworkForTests});
6028
mmenke6ddfbea2017-05-31 21:48:416029 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286030 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316031 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286032
Ryan Hamiltonabad59e2019-06-06 04:02:596033 MockQuicData socket_data(version_);
rche11300ef2016-09-02 01:44:286034 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526035 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436036 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336037 socket_data.AddWrite(
6038 SYNCHRONOUS,
6039 ConstructClientRequestHeadersPacket(
6040 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6041 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286042 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6043 socket_data.AddSocketDataToFactory(&socket_factory_);
6044
Ryan Hamiltonabad59e2019-06-06 04:02:596045 MockQuicData socket_data2(version_);
rche11300ef2016-09-02 01:44:286046 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6047 socket_data2.AddSocketDataToFactory(&socket_factory_);
6048
6049 // The non-alternate protocol job needs to hang in order to guarantee that
6050 // the alternate-protocol job will "win".
6051 AddHangingNonAlternateProtocolSocketData();
6052
6053 CreateSession();
6054 request_.method = "POST";
6055 ChunkedUploadDataStream upload_data(0);
6056
6057 request_.upload_data_stream = &upload_data;
6058
rdsmith1d343be52016-10-21 20:37:506059 std::unique_ptr<HttpNetworkTransaction> trans(
6060 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286061 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506062 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6064
6065 base::RunLoop().RunUntilIdle();
6066 upload_data.AppendData("1", 1, true);
6067 base::RunLoop().RunUntilIdle();
6068
6069 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506070 trans.reset();
rche11300ef2016-09-02 01:44:286071 session_.reset();
6072}
6073
Ryan Hamilton4b3574532017-10-30 20:17:256074TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6075 session_params_.origins_to_force_quic_on.insert(
6076 HostPortPair::FromString("mail.example.org:443"));
6077
Ryan Hamiltonabad59e2019-06-06 04:02:596078 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526079 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436080 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256081 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336082 socket_data.AddWrite(
6083 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6084 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6085 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436086 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336087 ASYNC, ConstructServerResponseHeadersPacket(
6088 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6089 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436090 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336091 socket_data.AddRead(
6092 ASYNC, ConstructServerDataPacket(
6093 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416094 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436095 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256096 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166097 socket_data.AddWrite(
6098 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6099 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6100 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256101
6102 socket_data.AddSocketDataToFactory(&socket_factory_);
6103
6104 CreateSession();
6105
6106 SendRequestAndExpectQuicResponse("hello!");
6107 session_.reset();
6108}
6109
6110TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6111 session_params_.origins_to_force_quic_on.insert(
6112 HostPortPair::FromString("mail.example.org:443"));
6113
Ryan Hamiltonabad59e2019-06-06 04:02:596114 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526115 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436116 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256117 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336118 socket_data.AddWrite(
6119 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6120 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6121 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436122 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336123 ASYNC, ConstructServerResponseHeadersPacket(
6124 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6125 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436126 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336127 socket_data.AddRead(
6128 ASYNC, ConstructServerDataPacket(
6129 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416130 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436131 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256132 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166133 socket_data.AddWrite(
6134 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6135 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6136 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256137
6138 socket_data.AddSocketDataToFactory(&socket_factory_);
6139
6140 CreateSession();
6141
6142 SendRequestAndExpectQuicResponse("hello!");
6143 session_.reset();
6144}
6145
Ryan Hamilton9edcf1a2017-11-22 05:55:176146TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486147 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256148 session_params_.origins_to_force_quic_on.insert(
6149 HostPortPair::FromString("mail.example.org:443"));
6150
Ryan Hamiltonabad59e2019-06-06 04:02:596151 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526152 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256153 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436154 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176155 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256156 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6157 }
6158 socket_data.AddSocketDataToFactory(&socket_factory_);
6159
6160 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176161 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176162 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6163 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256164
Ryan Hamilton8d9ee76e2018-05-29 23:52:526165 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256166 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6167 TestCompletionCallback callback;
6168 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6169 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176170 while (!callback.have_result()) {
6171 base::RunLoop().RunUntilIdle();
6172 quic_task_runner_->RunUntilIdle();
6173 }
6174 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256175 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176176 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6177 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6178 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526179 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6180 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256181}
6182
Ryan Hamilton9edcf1a2017-11-22 05:55:176183TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486184 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256185 session_params_.origins_to_force_quic_on.insert(
6186 HostPortPair::FromString("mail.example.org:443"));
6187
Ryan Hamiltonabad59e2019-06-06 04:02:596188 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526189 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256190 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436191 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176192 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256193 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6194 }
6195 socket_data.AddSocketDataToFactory(&socket_factory_);
6196
6197 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176198 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176199 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6200 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256201
Ryan Hamilton8d9ee76e2018-05-29 23:52:526202 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6204 TestCompletionCallback callback;
6205 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176207 while (!callback.have_result()) {
6208 base::RunLoop().RunUntilIdle();
6209 quic_task_runner_->RunUntilIdle();
6210 }
6211 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256212 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176213 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6214 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6215 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526216 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6217 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256218}
6219
Cherie Shi7596de632018-02-22 07:28:186220TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486221 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186222 session_params_.origins_to_force_quic_on.insert(
6223 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436224 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526225 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6226 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186227
Ryan Hamiltonabad59e2019-06-06 04:02:596228 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526229 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186230 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436231 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186232 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6233 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526234 socket_data.AddWrite(
6235 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6236 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186237 socket_data.AddSocketDataToFactory(&socket_factory_);
6238
6239 CreateSession();
6240
6241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6242 TestCompletionCallback callback;
6243 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6245 base::RunLoop().RunUntilIdle();
6246 ASSERT_TRUE(callback.have_result());
6247 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6248 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6249 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6250}
6251
ckrasic769733c2016-06-30 00:42:136252// Adds coverage to catch regression such as https://crbug.com/622043
6253TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416254 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136255 HostPortPair::FromString("mail.example.org:443"));
6256
Ryan Hamiltonabad59e2019-06-06 04:02:596257 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526258 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236259 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436260 mock_quic_data.AddWrite(
6261 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6262 &header_stream_offset));
6263 mock_quic_data.AddWrite(
6264 SYNCHRONOUS,
6265 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336266 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6267 true, true, GetRequestHeaders("GET", "https", "/"),
6268 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526269 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436270 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336271 ASYNC, ConstructServerPushPromisePacket(
6272 1, GetNthClientInitiatedBidirectionalStreamId(0),
6273 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6274 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6275 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576276 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566277 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336278 mock_quic_data.AddWrite(SYNCHRONOUS,
6279 ConstructClientPriorityPacket(
6280 client_packet_number++, false,
6281 GetNthServerInitiatedUnidirectionalStreamId(0),
6282 GetNthClientInitiatedBidirectionalStreamId(0),
6283 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576284 }
Zhongyi Shi32f2fd02018-04-16 18:23:436285 mock_quic_data.AddRead(
6286 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336287 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436288 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576289 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436290 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6291 mock_quic_data.AddRead(
6292 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336293 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6294 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436295 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436296 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336297 ASYNC, ConstructServerDataPacket(
6298 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416299 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576300 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436301 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436302 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436303 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336304 ASYNC, ConstructServerDataPacket(
6305 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416306 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336307 mock_quic_data.AddWrite(SYNCHRONOUS,
6308 ConstructClientAckAndRstPacket(
6309 client_packet_number++,
6310 GetNthServerInitiatedUnidirectionalStreamId(0),
6311 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136312 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6313 mock_quic_data.AddRead(ASYNC, 0); // EOF
6314 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6315
6316 // The non-alternate protocol job needs to hang in order to guarantee that
6317 // the alternate-protocol job will "win".
6318 AddHangingNonAlternateProtocolSocketData();
6319
6320 CreateSession();
6321
6322 // PUSH_PROMISE handling in the http layer gets exercised here.
6323 SendRequestAndExpectQuicResponse("hello!");
6324
6325 request_.url = GURL("https://mail.example.org/pushed.jpg");
6326 SendRequestAndExpectQuicResponse("and hello!");
6327
6328 // Check that the NetLog was filled reasonably.
6329 TestNetLogEntry::List entries;
6330 net_log_.GetEntries(&entries);
6331 EXPECT_LT(0u, entries.size());
6332
6333 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6334 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006335 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6336 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136337 EXPECT_LT(0, pos);
6338}
6339
rch56ec40a2017-06-23 14:48:446340// Regression test for http://crbug.com/719461 in which a promised stream
6341// is closed before the pushed headers arrive, but after the connection
6342// is closed and before the callbacks are executed.
6343TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486344 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446345 session_params_.origins_to_force_quic_on.insert(
6346 HostPortPair::FromString("mail.example.org:443"));
6347
Ryan Hamiltonabad59e2019-06-06 04:02:596348 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526349 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236350 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446351 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436352 mock_quic_data.AddWrite(
6353 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6354 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446355 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436356 mock_quic_data.AddWrite(
6357 SYNCHRONOUS,
6358 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336359 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6360 true, true, GetRequestHeaders("GET", "https", "/"),
6361 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526362 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446363 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436364 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336365 ASYNC, ConstructServerPushPromisePacket(
6366 1, GetNthClientInitiatedBidirectionalStreamId(0),
6367 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6368 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6369 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576370 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566371 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336372 mock_quic_data.AddWrite(SYNCHRONOUS,
6373 ConstructClientPriorityPacket(
6374 client_packet_number++, false,
6375 GetNthServerInitiatedUnidirectionalStreamId(0),
6376 GetNthClientInitiatedBidirectionalStreamId(0),
6377 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576378 }
rch56ec40a2017-06-23 14:48:446379 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436380 mock_quic_data.AddRead(
6381 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336382 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436383 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446384 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576385 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436386 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446387 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436388 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436389 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336390 ASYNC, ConstructServerDataPacket(
6391 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416392 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446393 // Write error for the third request.
6394 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6395 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6396 mock_quic_data.AddRead(ASYNC, 0); // EOF
6397 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6398
6399 CreateSession();
6400
6401 // Send a request which triggers a push promise from the server.
6402 SendRequestAndExpectQuicResponse("hello!");
6403
6404 // Start a push transaction that will be cancelled after the connection
6405 // is closed, but before the callback is executed.
6406 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196407 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446408 session_.get());
6409 TestCompletionCallback callback2;
6410 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6412 base::RunLoop().RunUntilIdle();
6413
6414 // Cause the connection to close on a write error.
6415 HttpRequestInfo request3;
6416 request3.method = "GET";
6417 request3.url = GURL("https://mail.example.org/");
6418 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106419 request3.traffic_annotation =
6420 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446421 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6422 TestCompletionCallback callback3;
6423 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6424 IsError(ERR_IO_PENDING));
6425
6426 base::RunLoop().RunUntilIdle();
6427
6428 // When |trans2| is destroyed, the underlying stream will be closed.
6429 EXPECT_FALSE(callback2.have_result());
6430 trans2 = nullptr;
6431
6432 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6433}
6434
ckrasicda193a82016-07-09 00:39:366435TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416436 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366437 HostPortPair::FromString("mail.example.org:443"));
6438
Ryan Hamiltonabad59e2019-06-06 04:02:596439 MockQuicData mock_quic_data(version_);
ckrasicda193a82016-07-09 00:39:366440
Ryan Hamilton8d9ee76e2018-05-29 23:52:526441 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416442 int write_packet_index = 1;
6443 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6444 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366445
Victor Vasiliev076657c2019-03-12 02:46:436446 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566447 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416448 mock_quic_data.AddWrite(
6449 SYNCHRONOUS,
6450 ConstructClientRequestHeadersAndDataFramesPacket(
6451 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6452 true, true, DEFAULT_PRIORITY,
6453 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6454 {"1"}));
6455 } else {
6456 mock_quic_data.AddWrite(
6457 SYNCHRONOUS,
6458 ConstructClientRequestHeadersAndDataFramesPacket(
6459 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6460 true, true, DEFAULT_PRIORITY,
6461 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6462 {header, "1"}));
6463 }
ckrasicda193a82016-07-09 00:39:366464
Zhongyi Shi32f2fd02018-04-16 18:23:436465 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336466 ASYNC, ConstructServerResponseHeadersPacket(
6467 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6468 GetResponseHeaders("200 OK")));
6469
Victor Vasiliev076657c2019-03-12 02:46:436470 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336471 mock_quic_data.AddRead(
6472 ASYNC, ConstructServerDataPacket(
6473 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416474 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366475
Renjief49758b2019-01-11 23:32:416476 mock_quic_data.AddWrite(
6477 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366478
6479 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6480 mock_quic_data.AddRead(ASYNC, 0); // EOF
6481 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6482
6483 // The non-alternate protocol job needs to hang in order to guarantee that
6484 // the alternate-protocol job will "win".
6485 AddHangingNonAlternateProtocolSocketData();
6486
6487 CreateSession();
6488 request_.method = "POST";
6489 ChunkedUploadDataStream upload_data(0);
6490 upload_data.AppendData("1", 1, true);
6491
6492 request_.upload_data_stream = &upload_data;
6493
6494 SendRequestAndExpectQuicResponse("hello!");
6495}
6496
allada71b2efb2016-09-09 04:57:486497class QuicURLRequestContext : public URLRequestContext {
6498 public:
6499 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6500 MockClientSocketFactory* socket_factory)
6501 : storage_(this) {
6502 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076503 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046504 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486505 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046506 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596507 storage_.set_proxy_resolution_service(
6508 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076509 storage_.set_ssl_config_service(
6510 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486511 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116512 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486513 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076514 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046515 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486516 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046517 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6518 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6519 false));
allada71b2efb2016-09-09 04:57:486520 }
6521
6522 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6523
6524 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6525
6526 private:
6527 MockClientSocketFactory* socket_factory_;
6528 URLRequestContextStorage storage_;
6529};
6530
6531TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416532 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486533 HostPortPair::FromString("mail.example.org:443"));
6534
Ryan Hamiltonabad59e2019-06-06 04:02:596535 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526536 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366537 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436538 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136539 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486540 headers["user-agent"] = "";
6541 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336542 mock_quic_data.AddWrite(
6543 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6544 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6545 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486546
Ryan Hamilton8d9ee76e2018-05-29 23:52:526547 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336548 mock_quic_data.AddRead(
6549 ASYNC,
6550 ConstructServerResponseHeadersPacket(
6551 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6552 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486553
Victor Vasiliev076657c2019-03-12 02:46:436554 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366555 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336556 ASYNC, ConstructServerDataPacket(
6557 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6558 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436559 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486560
6561 mock_quic_data.AddRead(ASYNC, 0); // EOF
6562
6563 CreateSession();
6564
6565 TestDelegate delegate;
6566 QuicURLRequestContext quic_url_request_context(std::move(session_),
6567 &socket_factory_);
6568
6569 mock_quic_data.AddSocketDataToFactory(
6570 &quic_url_request_context.socket_factory());
6571 TestNetworkDelegate network_delegate;
6572 quic_url_request_context.set_network_delegate(&network_delegate);
6573
6574 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296575 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6576 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486577 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6578 &ssl_data_);
6579
6580 request->Start();
Wez2a31b222018-06-07 22:07:156581 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486582
6583 EXPECT_LT(0, request->GetTotalSentBytes());
6584 EXPECT_LT(0, request->GetTotalReceivedBytes());
6585 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6586 request->GetTotalSentBytes());
6587 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6588 request->GetTotalReceivedBytes());
6589 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6590 request->raw_header_size());
Wez0e717112018-06-18 23:09:226591
6592 // Pump the message loop to allow all data to be consumed.
6593 base::RunLoop().RunUntilIdle();
6594
allada71b2efb2016-09-09 04:57:486595 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6596 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6597}
6598
6599TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416600 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486601 HostPortPair::FromString("mail.example.org:443"));
6602
Ryan Hamiltonabad59e2019-06-06 04:02:596603 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526604 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236605 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436606 mock_quic_data.AddWrite(
6607 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6608 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136609 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486610 headers["user-agent"] = "";
6611 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436612 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336613 SYNCHRONOUS,
6614 ConstructClientRequestHeadersPacket(
6615 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6616 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486617
Ryan Hamilton8d9ee76e2018-05-29 23:52:526618 quic::QuicStreamOffset server_header_offset = 0;
6619 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486620
Zhongyi Shi32f2fd02018-04-16 18:23:436621 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336622 ASYNC, ConstructServerPushPromisePacket(
6623 1, GetNthClientInitiatedBidirectionalStreamId(0),
6624 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6625 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6626 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486627
Yixin Wangb470bc882018-02-15 18:43:576628 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566629 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336630 mock_quic_data.AddWrite(SYNCHRONOUS,
6631 ConstructClientPriorityPacket(
6632 client_packet_number++, false,
6633 GetNthServerInitiatedUnidirectionalStreamId(0),
6634 GetNthClientInitiatedBidirectionalStreamId(0),
6635 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576636 }
6637
allada71b2efb2016-09-09 04:57:486638 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436639 mock_quic_data.AddRead(
6640 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336641 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436642 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486643 expected_raw_header_response_size =
6644 server_header_offset - expected_raw_header_response_size;
6645
Yixin Wangb470bc882018-02-15 18:43:576646 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436647 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486648
ckrasicbf2f59c2017-05-04 23:54:366649 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436650 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336651 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6652 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436653 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436654 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336655 ASYNC, ConstructServerDataPacket(
6656 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416657 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486658
Yixin Wangb470bc882018-02-15 18:43:576659 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436660 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436661 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366662 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336663 ASYNC, ConstructServerDataPacket(
6664 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416665 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486666
Zhongyi Shi32f2fd02018-04-16 18:23:436667 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486668
6669 CreateSession();
6670
6671 TestDelegate delegate;
6672 QuicURLRequestContext quic_url_request_context(std::move(session_),
6673 &socket_factory_);
6674
6675 mock_quic_data.AddSocketDataToFactory(
6676 &quic_url_request_context.socket_factory());
6677 TestNetworkDelegate network_delegate;
6678 quic_url_request_context.set_network_delegate(&network_delegate);
6679
6680 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296681 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6682 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486683 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6684 &ssl_data_);
6685
6686 request->Start();
Wez2a31b222018-06-07 22:07:156687 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486688
6689 EXPECT_LT(0, request->GetTotalSentBytes());
6690 EXPECT_LT(0, request->GetTotalReceivedBytes());
6691 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6692 request->GetTotalSentBytes());
6693 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6694 request->GetTotalReceivedBytes());
6695 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6696 request->raw_header_size());
Wez0e717112018-06-18 23:09:226697
6698 // Pump the message loop to allow all data to be consumed.
6699 base::RunLoop().RunUntilIdle();
6700
allada71b2efb2016-09-09 04:57:486701 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6702 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6703}
6704
Yixin Wang10f477ed2017-11-21 04:20:206705TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6706 session_params_.quic_host_whitelist.insert("mail.example.org");
6707
6708 MockRead http_reads[] = {
6709 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6710 MockRead("hello world"),
6711 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6712 MockRead(ASYNC, OK)};
6713
Ryan Sleevib8d7ea02018-05-07 20:01:016714 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206715 socket_factory_.AddSocketDataProvider(&http_data);
6716 AddCertificate(&ssl_data_);
6717 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6718
Ryan Hamiltonabad59e2019-06-06 04:02:596719 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526720 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206721 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436722 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6723 mock_quic_data.AddWrite(
6724 SYNCHRONOUS,
6725 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336726 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436727 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436728 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336729 ASYNC, ConstructServerResponseHeadersPacket(
6730 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6731 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436732 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336733 mock_quic_data.AddRead(
6734 ASYNC, ConstructServerDataPacket(
6735 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416736 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436737 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206738 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6739 mock_quic_data.AddRead(ASYNC, 0); // EOF
6740
6741 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6742
6743 AddHangingNonAlternateProtocolSocketData();
6744 CreateSession();
6745
6746 SendRequestAndExpectHttpResponse("hello world");
6747 SendRequestAndExpectQuicResponse("hello!");
6748}
6749
6750TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6751 session_params_.quic_host_whitelist.insert("mail.example.com");
6752
6753 MockRead http_reads[] = {
6754 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6755 MockRead("hello world"),
6756 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6757 MockRead(ASYNC, OK)};
6758
Ryan Sleevib8d7ea02018-05-07 20:01:016759 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206760 socket_factory_.AddSocketDataProvider(&http_data);
6761 AddCertificate(&ssl_data_);
6762 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6763 socket_factory_.AddSocketDataProvider(&http_data);
6764 AddCertificate(&ssl_data_);
6765 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6766
6767 AddHangingNonAlternateProtocolSocketData();
6768 CreateSession();
6769
6770 SendRequestAndExpectHttpResponse("hello world");
6771 SendRequestAndExpectHttpResponse("hello world");
6772}
6773
bnc359ed2a2016-04-29 20:43:456774class QuicNetworkTransactionWithDestinationTest
6775 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016776 public ::testing::WithParamInterface<PoolingTestParams>,
6777 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456778 protected:
6779 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556780 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056781 client_headers_include_h2_stream_dependency_(
6782 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:566783 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456784 destination_type_(GetParam().destination_type),
6785 cert_transparency_verifier_(new MultiLogCTVerifier()),
6786 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596787 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116788 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456789 random_generator_(0),
6790 ssl_data_(ASYNC, OK) {}
6791
6792 void SetUp() override {
6793 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556794 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456795
mmenke6ddfbea2017-05-31 21:48:416796 HttpNetworkSession::Params session_params;
6797 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346798 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446799 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056800 session_params.quic_headers_include_h2_stream_dependency =
6801 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416802
6803 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456804
Ryan Hamilton8d9ee76e2018-05-29 23:52:526805 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416806 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456807
6808 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276809 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416810 session_context.quic_crypto_client_stream_factory =
6811 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456812
mmenke6ddfbea2017-05-31 21:48:416813 session_context.quic_random = &random_generator_;
6814 session_context.client_socket_factory = &socket_factory_;
6815 session_context.host_resolver = &host_resolver_;
6816 session_context.cert_verifier = &cert_verifier_;
6817 session_context.transport_security_state = &transport_security_state_;
6818 session_context.cert_transparency_verifier =
6819 cert_transparency_verifier_.get();
6820 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6821 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456822 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416823 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596824 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416825 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6826 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456827
mmenke6ddfbea2017-05-31 21:48:416828 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456829 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456830 }
6831
6832 void TearDown() override {
6833 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6834 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556835 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456836 PlatformTest::TearDown();
6837 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556838 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406839 session_.reset();
bnc359ed2a2016-04-29 20:43:456840 }
6841
zhongyie537a002017-06-27 16:48:216842 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456843 HostPortPair destination;
6844 switch (destination_type_) {
6845 case SAME_AS_FIRST:
6846 destination = HostPortPair(origin1_, 443);
6847 break;
6848 case SAME_AS_SECOND:
6849 destination = HostPortPair(origin2_, 443);
6850 break;
6851 case DIFFERENT:
6852 destination = HostPortPair(kDifferentHostname, 443);
6853 break;
6854 }
bnc3472afd2016-11-17 15:27:216855 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456856 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216857 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456858 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446859 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456860 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526861 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236862 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526863 quic::QuicStreamId stream_id,
6864 bool should_include_version,
6865 quic::QuicStreamOffset* offset,
6866 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486867 return ConstructClientRequestHeadersPacket(
6868 packet_number, stream_id, should_include_version, 0, offset, maker);
6869 }
bnc359ed2a2016-04-29 20:43:456870
Ryan Hamilton8d9ee76e2018-05-29 23:52:526871 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236872 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526873 quic::QuicStreamId stream_id,
6874 bool should_include_version,
6875 quic::QuicStreamId parent_stream_id,
6876 quic::QuicStreamOffset* offset,
6877 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136878 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456879 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136880 spdy::SpdyHeaderBlock headers(
6881 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456882 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6883 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486884 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456885 }
6886
Ryan Hamilton8d9ee76e2018-05-29 23:52:526887 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236888 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526889 quic::QuicStreamId stream_id,
6890 bool should_include_version,
6891 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586892 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456893 packet_number, stream_id, should_include_version, nullptr, maker);
6894 }
6895
Ryan Hamilton8d9ee76e2018-05-29 23:52:526896 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236897 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526898 quic::QuicStreamId stream_id,
6899 quic::QuicStreamOffset* offset,
6900 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136901 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456902 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266903 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456904 }
6905
Ryan Hamilton8d9ee76e2018-05-29 23:52:526906 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236907 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526908 quic::QuicStreamId stream_id,
6909 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586910 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6911 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456912 }
6913
Ryan Hamilton8d9ee76e2018-05-29 23:52:526914 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236915 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526916 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456917 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436918 std::string header = "";
Nick Harper23290b82019-05-02 00:02:566919 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416920 quic::HttpEncoder encoder;
6921 std::unique_ptr<char[]> buffer;
6922 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436923 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416924 }
bnc359ed2a2016-04-29 20:43:456925 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416926 header + "hello");
bnc359ed2a2016-04-29 20:43:456927 }
6928
Ryan Hamilton8d9ee76e2018-05-29 23:52:526929 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236930 uint64_t packet_number,
6931 uint64_t largest_received,
6932 uint64_t smallest_received,
6933 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456934 QuicTestPacketMaker* maker) {
6935 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496936 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456937 }
6938
Ryan Hamilton8d9ee76e2018-05-29 23:52:526939 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236940 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526941 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376942 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366943 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376944 }
6945
bnc359ed2a2016-04-29 20:43:456946 void AddRefusedSocketData() {
6947 std::unique_ptr<StaticSocketDataProvider> refused_data(
6948 new StaticSocketDataProvider());
6949 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6950 refused_data->set_connect_data(refused_connect);
6951 socket_factory_.AddSocketDataProvider(refused_data.get());
6952 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6953 }
6954
6955 void AddHangingSocketData() {
6956 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6957 new StaticSocketDataProvider());
6958 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6959 hanging_data->set_connect_data(hanging_connect);
6960 socket_factory_.AddSocketDataProvider(hanging_data.get());
6961 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6962 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6963 }
6964
6965 bool AllDataConsumed() {
6966 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6967 if (!socket_data_ptr->AllReadDataConsumed() ||
6968 !socket_data_ptr->AllWriteDataConsumed()) {
6969 return false;
6970 }
6971 }
6972 return true;
6973 }
6974
6975 void SendRequestAndExpectQuicResponse(const std::string& host) {
6976 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6977 HttpRequestInfo request;
6978 std::string url("https://");
6979 url.append(host);
6980 request.url = GURL(url);
6981 request.load_flags = 0;
6982 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106983 request.traffic_annotation =
6984 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456985 TestCompletionCallback callback;
6986 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016987 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456988
6989 std::string response_data;
robpercival214763f2016-07-01 23:27:016990 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456991 EXPECT_EQ("hello", response_data);
6992
6993 const HttpResponseInfo* response = trans.GetResponseInfo();
6994 ASSERT_TRUE(response != nullptr);
6995 ASSERT_TRUE(response->headers.get() != nullptr);
6996 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6997 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526998 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:566999 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
7000 version_.transport_version),
bnc359ed2a2016-04-29 20:43:457001 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377002 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457003 }
7004
Fan Yang32c5a112018-12-10 20:06:337005 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567006 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7007 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367008 }
7009
Ryan Hamilton8d9ee76e2018-05-29 23:52:527010 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:567011 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057012 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567013 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457014 DestinationType destination_type_;
7015 std::string origin1_;
7016 std::string origin2_;
7017 std::unique_ptr<HttpNetworkSession> session_;
7018 MockClientSocketFactory socket_factory_;
7019 MockHostResolver host_resolver_;
7020 MockCertVerifier cert_verifier_;
7021 TransportSecurityState transport_security_state_;
7022 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237023 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457024 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077025 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597026 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457027 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527028 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457029 HttpServerPropertiesImpl http_server_properties_;
7030 BoundTestNetLog net_log_;
7031 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7032 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7033 static_socket_data_provider_vector_;
7034 SSLSocketDataProvider ssl_data_;
7035};
7036
Victor Costane635086f2019-01-27 05:20:307037INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7038 QuicNetworkTransactionWithDestinationTest,
7039 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457040
7041// A single QUIC request fails because the certificate does not match the origin
7042// hostname, regardless of whether it matches the alternative service hostname.
7043TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7044 if (destination_type_ == DIFFERENT)
7045 return;
7046
7047 GURL url("https://mail.example.com/");
7048 origin1_ = url.host();
7049
7050 // Not used for requests, but this provides a test case where the certificate
7051 // is valid for the hostname of the alternative service.
7052 origin2_ = "mail.example.org";
7053
zhongyie537a002017-06-27 16:48:217054 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457055
7056 scoped_refptr<X509Certificate> cert(
7057 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247058 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7059 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457060
7061 ProofVerifyDetailsChromium verify_details;
7062 verify_details.cert_verify_result.verified_cert = cert;
7063 verify_details.cert_verify_result.is_issued_by_known_root = true;
7064 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7065
Ryan Hamiltonabad59e2019-06-06 04:02:597066 MockQuicData mock_quic_data(version_);
bnc359ed2a2016-04-29 20:43:457067 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7068 mock_quic_data.AddRead(ASYNC, 0);
7069
7070 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7071
7072 AddRefusedSocketData();
7073
7074 HttpRequestInfo request;
7075 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107076 request.traffic_annotation =
7077 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457078
7079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7080 TestCompletionCallback callback;
7081 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017082 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457083
7084 EXPECT_TRUE(AllDataConsumed());
7085}
7086
7087// First request opens QUIC session to alternative service. Second request
7088// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527089// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457090TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7091 origin1_ = "mail.example.org";
7092 origin2_ = "news.example.org";
7093
zhongyie537a002017-06-27 16:48:217094 SetQuicAlternativeService(origin1_);
7095 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457096
7097 scoped_refptr<X509Certificate> cert(
7098 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247099 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7100 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7101 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457102
7103 ProofVerifyDetailsChromium verify_details;
7104 verify_details.cert_verify_result.verified_cert = cert;
7105 verify_details.cert_verify_result.is_issued_by_known_root = true;
7106 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7107
Yixin Wang079ad542018-01-11 04:06:057108 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177109 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7110 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057111 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177112 QuicTestPacketMaker server_maker(
7113 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7114 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457115
Ryan Hamilton8d9ee76e2018-05-29 23:52:527116 quic::QuicStreamOffset request_header_offset(0);
7117 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457118
Ryan Hamiltonabad59e2019-06-06 04:02:597119 MockQuicData mock_quic_data(version_);
Yixin Wang079ad542018-01-11 04:06:057120 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437121 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057122 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337123 mock_quic_data.AddWrite(
7124 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7125 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7126 &request_header_offset, &client_maker));
7127 mock_quic_data.AddRead(ASYNC,
7128 ConstructServerResponseHeadersPacket(
7129 1, GetNthClientInitiatedBidirectionalStreamId(0),
7130 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437131 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337132 ASYNC,
7133 ConstructServerDataPacket(
7134 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437135 mock_quic_data.AddWrite(SYNCHRONOUS,
7136 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457137
Yixin Wang079ad542018-01-11 04:06:057138 client_maker.set_hostname(origin2_);
7139 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457140
Zhongyi Shi32f2fd02018-04-16 18:23:437141 mock_quic_data.AddWrite(
7142 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337143 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7144 GetNthClientInitiatedBidirectionalStreamId(0),
7145 &request_header_offset, &client_maker));
7146 mock_quic_data.AddRead(ASYNC,
7147 ConstructServerResponseHeadersPacket(
7148 3, GetNthClientInitiatedBidirectionalStreamId(1),
7149 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437150 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337151 ASYNC,
7152 ConstructServerDataPacket(
7153 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437154 mock_quic_data.AddWrite(SYNCHRONOUS,
7155 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457156 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7157 mock_quic_data.AddRead(ASYNC, 0); // EOF
7158
7159 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7160
7161 AddHangingSocketData();
7162 AddHangingSocketData();
7163
Nick Harpereb483e12019-05-14 00:18:097164 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:567165 QuicStreamFactoryPeer::SetAlarmFactory(
7166 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097167 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:567168 &clock_));
7169
bnc359ed2a2016-04-29 20:43:457170 SendRequestAndExpectQuicResponse(origin1_);
7171 SendRequestAndExpectQuicResponse(origin2_);
7172
7173 EXPECT_TRUE(AllDataConsumed());
7174}
7175
7176// First request opens QUIC session to alternative service. Second request does
7177// not pool to it, even though destination matches, because certificate is not
7178// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527179// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457180TEST_P(QuicNetworkTransactionWithDestinationTest,
7181 DoNotPoolIfCertificateInvalid) {
7182 origin1_ = "news.example.org";
7183 origin2_ = "mail.example.com";
7184
zhongyie537a002017-06-27 16:48:217185 SetQuicAlternativeService(origin1_);
7186 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457187
7188 scoped_refptr<X509Certificate> cert1(
7189 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247190 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7191 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7192 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457193
7194 scoped_refptr<X509Certificate> cert2(
7195 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247196 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7197 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457198
7199 ProofVerifyDetailsChromium verify_details1;
7200 verify_details1.cert_verify_result.verified_cert = cert1;
7201 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7202 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7203
7204 ProofVerifyDetailsChromium verify_details2;
7205 verify_details2.cert_verify_result.verified_cert = cert2;
7206 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7207 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7208
Yixin Wang079ad542018-01-11 04:06:057209 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177210 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7211 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057212 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177213 QuicTestPacketMaker server_maker1(
7214 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7215 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457216
Ryan Hamiltonabad59e2019-06-06 04:02:597217 MockQuicData mock_quic_data1(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527218 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457219 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437220 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7221 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337222 mock_quic_data1.AddWrite(
7223 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7224 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7225 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437226 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337227 ASYNC,
7228 ConstructServerResponseHeadersPacket(
7229 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437230 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337231 ASYNC,
7232 ConstructServerDataPacket(
7233 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437234 mock_quic_data1.AddWrite(
7235 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457236 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7237 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7238
7239 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7240
Yixin Wang079ad542018-01-11 04:06:057241 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177242 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7243 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057244 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177245 QuicTestPacketMaker server_maker2(
7246 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7247 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457248
Ryan Hamiltonabad59e2019-06-06 04:02:597249 MockQuicData mock_quic_data2(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527250 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457251 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437252 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7253 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337254 mock_quic_data2.AddWrite(
7255 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7256 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7257 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437258 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337259 ASYNC,
7260 ConstructServerResponseHeadersPacket(
7261 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437262 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337263 ASYNC,
7264 ConstructServerDataPacket(
7265 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437266 mock_quic_data2.AddWrite(
7267 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457268 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7269 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7270
7271 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7272
bnc359ed2a2016-04-29 20:43:457273 SendRequestAndExpectQuicResponse(origin1_);
7274 SendRequestAndExpectQuicResponse(origin2_);
7275
7276 EXPECT_TRUE(AllDataConsumed());
7277}
7278
ckrasicdee37572017-04-06 22:42:277279// crbug.com/705109 - this confirms that matching request with a body
7280// triggers a crash (pre-fix).
7281TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417282 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277283 HostPortPair::FromString("mail.example.org:443"));
7284
Ryan Hamiltonabad59e2019-06-06 04:02:597285 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527286 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237287 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437288 mock_quic_data.AddWrite(
7289 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7290 &header_stream_offset));
7291 mock_quic_data.AddWrite(
7292 SYNCHRONOUS,
7293 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337294 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7295 true, true, GetRequestHeaders("GET", "https", "/"),
7296 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527297 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437298 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337299 ASYNC, ConstructServerPushPromisePacket(
7300 1, GetNthClientInitiatedBidirectionalStreamId(0),
7301 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7302 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7303 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577304 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:567305 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337306 mock_quic_data.AddWrite(SYNCHRONOUS,
7307 ConstructClientPriorityPacket(
7308 client_packet_number++, false,
7309 GetNthServerInitiatedUnidirectionalStreamId(0),
7310 GetNthClientInitiatedBidirectionalStreamId(0),
7311 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577312 }
Zhongyi Shi32f2fd02018-04-16 18:23:437313 mock_quic_data.AddRead(
7314 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337315 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437316 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577317 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437318 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7319 mock_quic_data.AddRead(
7320 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337321 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7322 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437323 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437324 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337325 ASYNC, ConstructServerDataPacket(
7326 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417327 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577328 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437329 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417330
Victor Vasiliev076657c2019-03-12 02:46:437331 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437332 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337333 ASYNC, ConstructServerDataPacket(
7334 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417335 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277336
7337 // Because the matching request has a body, we will see the push
7338 // stream get cancelled, and the matching request go out on the
7339 // wire.
Fan Yang32c5a112018-12-10 20:06:337340 mock_quic_data.AddWrite(SYNCHRONOUS,
7341 ConstructClientAckAndRstPacket(
7342 client_packet_number++,
7343 GetNthServerInitiatedUnidirectionalStreamId(0),
7344 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277345 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437346 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567347 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417348 mock_quic_data.AddWrite(
7349 SYNCHRONOUS,
7350 ConstructClientRequestHeadersAndDataFramesPacket(
7351 client_packet_number++,
7352 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7353 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7354 GetNthServerInitiatedUnidirectionalStreamId(0),
7355 &header_stream_offset, nullptr, {kBody}));
7356 } else {
7357 mock_quic_data.AddWrite(
7358 SYNCHRONOUS,
7359 ConstructClientRequestHeadersAndDataFramesPacket(
7360 client_packet_number++,
7361 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7362 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7363 GetNthServerInitiatedUnidirectionalStreamId(0),
7364 &header_stream_offset, nullptr, {header3, kBody}));
7365 }
ckrasicdee37572017-04-06 22:42:277366
7367 // We see the same response as for the earlier pushed and cancelled
7368 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437369 mock_quic_data.AddRead(
7370 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337371 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437372 GetResponseHeaders("200 OK"), &server_header_offset));
7373 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337374 ASYNC, ConstructServerDataPacket(
7375 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417376 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277377
Yixin Wangb470bc882018-02-15 18:43:577378 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437379 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277380 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7381 mock_quic_data.AddRead(ASYNC, 0); // EOF
7382 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7383
7384 // The non-alternate protocol job needs to hang in order to guarantee that
7385 // the alternate-protocol job will "win".
7386 AddHangingNonAlternateProtocolSocketData();
7387
7388 CreateSession();
7389
7390 // PUSH_PROMISE handling in the http layer gets exercised here.
7391 SendRequestAndExpectQuicResponse("hello!");
7392
7393 request_.url = GURL("https://mail.example.org/pushed.jpg");
7394 ChunkedUploadDataStream upload_data(0);
7395 upload_data.AppendData("1", 1, true);
7396 request_.upload_data_stream = &upload_data;
7397 SendRequestAndExpectQuicResponse("and hello!");
7398}
7399
Bence Béky7538a952018-02-01 16:59:527400// Regression test for https://crbug.com/797825: If pushed headers describe a
7401// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7402// not be called (otherwise a DCHECK fails).
7403TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137404 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527405 pushed_request_headers[":authority"] = "";
7406 pushed_request_headers[":method"] = "GET";
7407 pushed_request_headers[":path"] = "/";
7408 pushed_request_headers[":scheme"] = "nosuchscheme";
7409
7410 session_params_.origins_to_force_quic_on.insert(
7411 HostPortPair::FromString("mail.example.org:443"));
7412
Ryan Hamiltonabad59e2019-06-06 04:02:597413 MockQuicData mock_quic_data(version_);
Bence Béky7538a952018-02-01 16:59:527414
Ryan Hamilton8d9ee76e2018-05-29 23:52:527415 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527416 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437417 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7418 mock_quic_data.AddWrite(
7419 SYNCHRONOUS,
7420 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337421 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437422 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527423
Ryan Hamilton8d9ee76e2018-05-29 23:52:527424 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337425 mock_quic_data.AddRead(
7426 ASYNC, ConstructServerPushPromisePacket(
7427 1, GetNthClientInitiatedBidirectionalStreamId(0),
7428 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7429 std::move(pushed_request_headers), &server_header_offset,
7430 &server_maker_));
7431 mock_quic_data.AddWrite(SYNCHRONOUS,
7432 ConstructClientRstPacket(
7433 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7434 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527435
Zhongyi Shi32f2fd02018-04-16 18:23:437436 mock_quic_data.AddRead(
7437 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337438 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437439 GetResponseHeaders("200 OK"), &server_header_offset));
7440 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527441
Zhongyi Shi32f2fd02018-04-16 18:23:437442 mock_quic_data.AddRead(
7443 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337444 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7445 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437446 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437447 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337448 ASYNC, ConstructServerDataPacket(
7449 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417450 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437451 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527452
7453 mock_quic_data.AddRead(ASYNC, 0);
7454 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7455
7456 // The non-alternate protocol job needs to hang in order to guarantee that
7457 // the alternate-protocol job will "win".
7458 AddHangingNonAlternateProtocolSocketData();
7459
7460 CreateSession();
7461
7462 // PUSH_PROMISE handling in the http layer gets exercised here.
7463 SendRequestAndExpectQuicResponse("hello!");
7464
7465 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7466 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7467}
7468
Yixin Wang46a273ec302018-01-23 17:59:567469// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147470TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567471 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147472 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567473 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497474 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567475
Ryan Hamiltonabad59e2019-06-06 04:02:597476 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527477 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567478 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357479 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337480 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357481 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7482 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047483 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7484 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357485 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337486 mock_quic_data.AddRead(
7487 ASYNC, ConstructServerResponseHeadersPacket(
7488 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7489 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567490
7491 const char get_request[] =
7492 "GET / HTTP/1.1\r\n"
7493 "Host: mail.example.org\r\n"
7494 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437495 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567496 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417497 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357498 SYNCHRONOUS,
7499 ConstructClientAckAndDataPacket(
7500 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7501 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417502 } else {
7503 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417504 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357505 ConstructClientAckAndMultipleDataFramesPacket(
7506 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437507 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417508 }
7509
Yixin Wang46a273ec302018-01-23 17:59:567510 const char get_response[] =
7511 "HTTP/1.1 200 OK\r\n"
7512 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437513 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437514 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337515 ASYNC, ConstructServerDataPacket(
7516 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437517 0, header2 + std::string(get_response)));
7518 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337519 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417520 SYNCHRONOUS, ConstructServerDataPacket(
7521 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7522 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437523 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357524 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567525 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7526
7527 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417528 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357529 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7530 quic::QUIC_STREAM_CANCELLED,
7531 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567532
7533 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7534
7535 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7536
7537 CreateSession();
7538
7539 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097540 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7542 HeadersHandler headers_handler;
7543 trans.SetBeforeHeadersSentCallback(
7544 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7545 base::Unretained(&headers_handler)));
7546 RunTransaction(&trans);
7547 CheckWasHttpResponse(&trans);
7548 CheckResponsePort(&trans, 70);
7549 CheckResponseData(&trans, "0123456789");
7550 EXPECT_TRUE(headers_handler.was_proxied());
7551 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7552
7553 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7554 // proxy socket to disconnect.
7555 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7556
7557 base::RunLoop().RunUntilIdle();
7558 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7559 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7560}
7561
7562// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147563TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567564 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147565 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567566 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497567 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567568
Ryan Hamiltonabad59e2019-06-06 04:02:597569 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527570 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567571 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357572 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337573 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357574 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7575 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047576 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7577 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357578 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337579 mock_quic_data.AddRead(
7580 ASYNC, ConstructServerResponseHeadersPacket(
7581 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7582 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567583
7584 SpdyTestUtil spdy_util;
7585
Ryan Hamilton0239aac2018-05-19 00:03:137586 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567587 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437588 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567589 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417590 mock_quic_data.AddWrite(
7591 SYNCHRONOUS,
7592 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357593 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7594 false, 0,
Renjief49758b2019-01-11 23:32:417595 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7596 } else {
7597 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417598 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357599 ConstructClientAckAndMultipleDataFramesPacket(
7600 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7601 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437602 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417603 }
Ryan Hamilton0239aac2018-05-19 00:03:137604 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567605 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437606 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437607 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337608 ASYNC,
7609 ConstructServerDataPacket(
7610 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437611 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567612
Ryan Hamilton0239aac2018-05-19 00:03:137613 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197614 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437615 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437616 mock_quic_data.AddRead(
7617 SYNCHRONOUS,
7618 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337619 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417620 resp_frame.size() + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437621 header3 + std::string(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357622 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567623 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7624
7625 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437626 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357627 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7628 quic::QUIC_STREAM_CANCELLED,
7629 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567630
7631 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7632
7633 SSLSocketDataProvider ssl_data(ASYNC, OK);
7634 ssl_data.next_proto = kProtoHTTP2;
7635 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7636
7637 CreateSession();
7638
7639 request_.url = GURL("https://mail.example.org/");
7640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7641 HeadersHandler headers_handler;
7642 trans.SetBeforeHeadersSentCallback(
7643 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7644 base::Unretained(&headers_handler)));
7645 RunTransaction(&trans);
7646 CheckWasSpdyResponse(&trans);
7647 CheckResponsePort(&trans, 70);
7648 CheckResponseData(&trans, "0123456789");
7649 EXPECT_TRUE(headers_handler.was_proxied());
7650 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7651
Wez0e717112018-06-18 23:09:227652 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7653 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567654 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7655
7656 base::RunLoop().RunUntilIdle();
7657 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7658 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7659}
7660
7661// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7662// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147663TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567664 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147665 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567666 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497667 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567668
Ryan Hamiltonabad59e2019-06-06 04:02:597669 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527670 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417671 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567672 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417673 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7674 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337675 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417676 SYNCHRONOUS,
7677 ConstructClientRequestHeadersPacket(
7678 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047679 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7680 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjief49758b2019-01-11 23:32:417681 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337682 mock_quic_data.AddRead(
7683 ASYNC, ConstructServerResponseHeadersPacket(
7684 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7685 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567686
Ryan Hamilton8d9ee76e2018-05-29 23:52:527687 quic::QuicStreamOffset client_data_offset = 0;
7688 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567689 const char get_request_1[] =
7690 "GET / HTTP/1.1\r\n"
7691 "Host: mail.example.org\r\n"
7692 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437693 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567694 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417695 mock_quic_data.AddWrite(
7696 SYNCHRONOUS,
7697 ConstructClientAckAndDataPacket(
7698 write_packet_index++, false,
7699 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7700 client_data_offset, quic::QuicStringPiece(get_request_1)));
7701 } else {
7702 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417703 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357704 ConstructClientAckAndMultipleDataFramesPacket(
7705 write_packet_index++, false,
7706 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
Victor Vasiliev076657c2019-03-12 02:46:437707 client_data_offset, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417708 }
7709
7710 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567711
7712 const char get_response_1[] =
7713 "HTTP/1.1 200 OK\r\n"
7714 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437715 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437716 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437717 ASYNC, ConstructServerDataPacket(
7718 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7719 server_data_offset, header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417720 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567721
Victor Vasiliev076657c2019-03-12 02:46:437722 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337723 mock_quic_data.AddRead(
7724 SYNCHRONOUS,
7725 ConstructServerDataPacket(
7726 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437727 server_data_offset, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417728 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567729
Renjief49758b2019-01-11 23:32:417730 mock_quic_data.AddWrite(
7731 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567732
7733 const char get_request_2[] =
7734 "GET /2 HTTP/1.1\r\n"
7735 "Host: mail.example.org\r\n"
7736 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437737 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:567738 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417739 mock_quic_data.AddWrite(
7740 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357741 ConstructClientMultipleDataFramesPacket(
7742 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7743 false, false, client_data_offset,
Victor Vasiliev076657c2019-03-12 02:46:437744 {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357745 client_data_offset += header4.length() + strlen(get_request_2);
7746 } else {
7747 mock_quic_data.AddWrite(
7748 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417749 ConstructClientDataPacket(write_packet_index++,
7750 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357751 false, false, client_data_offset,
7752 quic::QuicStringPiece(get_request_2)));
7753 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417754 }
Yixin Wang46a273ec302018-01-23 17:59:567755
7756 const char get_response_2[] =
7757 "HTTP/1.1 200 OK\r\n"
7758 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437759 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437760 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437761 ASYNC, ConstructServerDataPacket(
7762 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7763 server_data_offset, header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417764 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567765
Victor Vasiliev076657c2019-03-12 02:46:437766 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527767 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337768 SYNCHRONOUS,
7769 ConstructServerDataPacket(
7770 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437771 server_data_offset, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417772 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567773
Renjief49758b2019-01-11 23:32:417774 mock_quic_data.AddWrite(
7775 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567776 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7777
Renjief49758b2019-01-11 23:32:417778 mock_quic_data.AddWrite(
7779 SYNCHRONOUS,
7780 ConstructClientRstPacket(
7781 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7782 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567783
7784 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7785
7786 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7787
7788 CreateSession();
7789
7790 request_.url = GURL("https://mail.example.org/");
7791 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7792 HeadersHandler headers_handler_1;
7793 trans_1.SetBeforeHeadersSentCallback(
7794 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7795 base::Unretained(&headers_handler_1)));
7796 RunTransaction(&trans_1);
7797 CheckWasHttpResponse(&trans_1);
7798 CheckResponsePort(&trans_1, 70);
7799 CheckResponseData(&trans_1, "0123456789");
7800 EXPECT_TRUE(headers_handler_1.was_proxied());
7801 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7802
7803 request_.url = GURL("https://mail.example.org/2");
7804 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7805 HeadersHandler headers_handler_2;
7806 trans_2.SetBeforeHeadersSentCallback(
7807 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7808 base::Unretained(&headers_handler_2)));
7809 RunTransaction(&trans_2);
7810 CheckWasHttpResponse(&trans_2);
7811 CheckResponsePort(&trans_2, 70);
7812 CheckResponseData(&trans_2, "0123456");
7813 EXPECT_TRUE(headers_handler_2.was_proxied());
7814 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7815
7816 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7817 // proxy socket to disconnect.
7818 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7819
7820 base::RunLoop().RunUntilIdle();
7821 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7822 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7823}
7824
7825// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7826// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7827// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147828TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567829 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147830 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567831 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497832 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567833
Ryan Hamiltonabad59e2019-06-06 04:02:597834 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527835 quic::QuicStreamOffset client_header_stream_offset = 0;
7836 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357837 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7838 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567839
7840 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337841 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357842 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7843 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047844 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7845 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357846 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437847 mock_quic_data.AddRead(
7848 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337849 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437850 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567851
7852 // GET request, response, and data over QUIC tunnel for first request
7853 const char get_request[] =
7854 "GET / HTTP/1.1\r\n"
7855 "Host: mail.example.org\r\n"
7856 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437857 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567858 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417859 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357860 SYNCHRONOUS,
7861 ConstructClientAckAndDataPacket(
7862 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7863 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417864 } else {
7865 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417866 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357867 ConstructClientAckAndMultipleDataFramesPacket(
7868 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437869 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417870 }
7871
Yixin Wang46a273ec302018-01-23 17:59:567872 const char get_response[] =
7873 "HTTP/1.1 200 OK\r\n"
7874 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437875 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567876 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337877 ASYNC, ConstructServerDataPacket(
7878 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437879 0, header2 + std::string(get_response)));
7880 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337881 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417882 SYNCHRONOUS, ConstructServerDataPacket(
7883 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7884 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437885 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357886 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567887
7888 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437889 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047890 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7891 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
7892 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7893 ConnectRequestHeaders("different.example.org:443"),
7894 GetNthClientInitiatedBidirectionalStreamId(0),
7895 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437896 mock_quic_data.AddRead(
7897 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337898 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437899 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567900
7901 // GET request, response, and data over QUIC tunnel for second request
7902 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137903 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567904 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437905 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567906 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417907 mock_quic_data.AddWrite(
7908 SYNCHRONOUS,
7909 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357910 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7911 false, 0,
Renjief49758b2019-01-11 23:32:417912 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7913 } else {
7914 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417915 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357916 ConstructClientAckAndMultipleDataFramesPacket(
7917 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7918 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437919 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417920 }
Yixin Wang46a273ec302018-01-23 17:59:567921
Ryan Hamilton0239aac2018-05-19 00:03:137922 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567923 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437924 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437925 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337926 ASYNC,
7927 ConstructServerDataPacket(
7928 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437929 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567930
Ryan Hamilton0239aac2018-05-19 00:03:137931 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197932 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437933 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437934 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437935 ASYNC, ConstructServerDataPacket(
7936 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7937 resp_frame.size() + header5.length(),
7938 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567939
Renjied172e812019-01-16 05:12:357940 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567941 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7942
7943 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417944 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357945 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7946 quic::QUIC_STREAM_CANCELLED,
7947 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567948 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437949 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357950 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7951 quic::QUIC_STREAM_CANCELLED,
7952 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567953
7954 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7955
7956 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7957
7958 SSLSocketDataProvider ssl_data(ASYNC, OK);
7959 ssl_data.next_proto = kProtoHTTP2;
7960 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7961
7962 CreateSession();
7963
7964 request_.url = GURL("https://mail.example.org/");
7965 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7966 HeadersHandler headers_handler_1;
7967 trans_1.SetBeforeHeadersSentCallback(
7968 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7969 base::Unretained(&headers_handler_1)));
7970 RunTransaction(&trans_1);
7971 CheckWasHttpResponse(&trans_1);
7972 CheckResponsePort(&trans_1, 70);
7973 CheckResponseData(&trans_1, "0123456789");
7974 EXPECT_TRUE(headers_handler_1.was_proxied());
7975 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7976
7977 request_.url = GURL("https://different.example.org/");
7978 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7979 HeadersHandler headers_handler_2;
7980 trans_2.SetBeforeHeadersSentCallback(
7981 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7982 base::Unretained(&headers_handler_2)));
7983 RunTransaction(&trans_2);
7984 CheckWasSpdyResponse(&trans_2);
7985 CheckResponsePort(&trans_2, 70);
7986 CheckResponseData(&trans_2, "0123456");
7987 EXPECT_TRUE(headers_handler_2.was_proxied());
7988 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7989
7990 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7991 // proxy socket to disconnect.
7992 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7993
7994 base::RunLoop().RunUntilIdle();
7995 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7996 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7997}
7998
7999// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148000TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568001 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148002 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568003 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498004 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568005
Ryan Hamiltonabad59e2019-06-06 04:02:598006 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528007 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568008 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438009 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528010 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338011 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8012 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048013 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8014 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338015 &header_stream_offset));
8016 mock_quic_data.AddRead(
8017 ASYNC, ConstructServerResponseHeadersPacket(
8018 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8019 GetResponseHeaders("500")));
8020 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8021 mock_quic_data.AddWrite(SYNCHRONOUS,
8022 ConstructClientAckAndRstPacket(
8023 3, GetNthClientInitiatedBidirectionalStreamId(0),
8024 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568025
8026 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8027
8028 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8029
8030 CreateSession();
8031
8032 request_.url = GURL("https://mail.example.org/");
8033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8034 HeadersHandler headers_handler;
8035 trans.SetBeforeHeadersSentCallback(
8036 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8037 base::Unretained(&headers_handler)));
8038 TestCompletionCallback callback;
8039 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8040 EXPECT_EQ(ERR_IO_PENDING, rv);
8041 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8042 EXPECT_EQ(false, headers_handler.was_proxied());
8043
8044 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8045 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8046}
8047
8048// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148049TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568050 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148051 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568052 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498053 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568054
Ryan Hamiltonabad59e2019-06-06 04:02:598055 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528056 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568057 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438058 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338059 mock_quic_data.AddWrite(
8060 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8061 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048062 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8063 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338064 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568065 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8066
8067 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8068
8069 CreateSession();
8070
8071 request_.url = GURL("https://mail.example.org/");
8072 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8073 HeadersHandler headers_handler;
8074 trans.SetBeforeHeadersSentCallback(
8075 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8076 base::Unretained(&headers_handler)));
8077 TestCompletionCallback callback;
8078 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8079 EXPECT_EQ(ERR_IO_PENDING, rv);
8080 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8081
8082 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8083 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8084}
8085
8086// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8087// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148088TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568089 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148090 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568091 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498092 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568093
Ryan Hamiltonabad59e2019-06-06 04:02:598094 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528095 quic::QuicStreamOffset client_header_stream_offset = 0;
8096 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358097 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8098 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338099 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358100 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8101 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048102 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8103 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:358104 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438105 mock_quic_data.AddRead(
8106 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338107 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438108 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358109 mock_quic_data.AddWrite(SYNCHRONOUS,
8110 ConstructClientAckAndRstPacket(
8111 3, GetNthClientInitiatedBidirectionalStreamId(0),
8112 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568113
Zhongyi Shi32f2fd02018-04-16 18:23:438114 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358115 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8116 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Matt Menke6e879bd2019-03-18 17:26:048117 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8118 ConnectRequestHeaders("mail.example.org:443"),
Renjied172e812019-01-16 05:12:358119 GetNthClientInitiatedBidirectionalStreamId(0),
8120 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438121 mock_quic_data.AddRead(
8122 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338123 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438124 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568125
8126 const char get_request[] =
8127 "GET / HTTP/1.1\r\n"
8128 "Host: mail.example.org\r\n"
8129 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438130 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568131 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418132 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358133 SYNCHRONOUS,
8134 ConstructClientAckAndDataPacket(
8135 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8136 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418137 } else {
8138 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418139 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358140 ConstructClientAckAndMultipleDataFramesPacket(
8141 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Victor Vasiliev076657c2019-03-12 02:46:438142 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418143 }
Yixin Wang46a273ec302018-01-23 17:59:568144 const char get_response[] =
8145 "HTTP/1.1 200 OK\r\n"
8146 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438147 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438148 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338149 ASYNC, ConstructServerDataPacket(
8150 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438151 0, header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528152
Victor Vasiliev076657c2019-03-12 02:46:438153 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338154 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418155 SYNCHRONOUS, ConstructServerDataPacket(
8156 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8157 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:438158 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:358159 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568160 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8161
8162 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418163 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358164 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8165 quic::QUIC_STREAM_CANCELLED,
8166 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568167
8168 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8169
8170 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8171 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8172
8173 SSLSocketDataProvider ssl_data(ASYNC, OK);
8174 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8175
8176 CreateSession();
8177
8178 request_.url = GURL("https://mail.example.org/");
8179 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8180 HeadersHandler headers_handler;
8181 trans.SetBeforeHeadersSentCallback(
8182 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8183 base::Unretained(&headers_handler)));
8184 TestCompletionCallback callback;
8185 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8186 EXPECT_EQ(ERR_IO_PENDING, rv);
8187 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8188
8189 rv = trans.RestartIgnoringLastError(callback.callback());
8190 EXPECT_EQ(ERR_IO_PENDING, rv);
8191 EXPECT_EQ(OK, callback.WaitForResult());
8192
8193 CheckWasHttpResponse(&trans);
8194 CheckResponsePort(&trans, 70);
8195 CheckResponseData(&trans, "0123456789");
8196 EXPECT_EQ(true, headers_handler.was_proxied());
8197 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8198
8199 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8200 // proxy socket to disconnect.
8201 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8202
8203 base::RunLoop().RunUntilIdle();
8204 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8205 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8206}
8207
8208// Checks if a request's specified "user-agent" header shows up correctly in the
8209// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148210TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008211 const char kConfiguredUserAgent[] = "Configured User-Agent";
8212 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568213 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148214 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568215 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498216 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568217
Ryan Hamiltonabad59e2019-06-06 04:02:598218 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528219 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568220 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438221 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568222
Ryan Hamilton0239aac2018-05-19 00:03:138223 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008224 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338225 mock_quic_data.AddWrite(
8226 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8227 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048228 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8229 std::move(headers), 0, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568230 // Return an error, so the transaction stops here (this test isn't interested
8231 // in the rest).
8232 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8233
8234 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8235
Matt Menked732ea42019-03-08 12:05:008236 StaticHttpUserAgentSettings http_user_agent_settings(
8237 std::string() /* accept_language */, kConfiguredUserAgent);
8238 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568239 CreateSession();
8240
8241 request_.url = GURL("https://mail.example.org/");
8242 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008243 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568244 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8245 HeadersHandler headers_handler;
8246 trans.SetBeforeHeadersSentCallback(
8247 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8248 base::Unretained(&headers_handler)));
8249 TestCompletionCallback callback;
8250 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8251 EXPECT_EQ(ERR_IO_PENDING, rv);
8252 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8253
8254 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8255 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8256}
8257
Yixin Wang00fc44c2018-01-23 21:12:208258// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8259// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148260TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208261 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148262 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208263 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498264 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208265
8266 const RequestPriority request_priority = MEDIUM;
8267
Ryan Hamiltonabad59e2019-06-06 04:02:598268 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528269 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208270 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438271 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8272 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048273 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8274 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8275 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8276 ConnectRequestHeaders("mail.example.org:443"), 0,
8277 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208278 // Return an error, so the transaction stops here (this test isn't interested
8279 // in the rest).
8280 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8281
8282 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8283
8284 CreateSession();
8285
8286 request_.url = GURL("https://mail.example.org/");
8287 HttpNetworkTransaction trans(request_priority, session_.get());
8288 TestCompletionCallback callback;
8289 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8290 EXPECT_EQ(ERR_IO_PENDING, rv);
8291 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8292
8293 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8294 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8295}
8296
Matt Menkeedaf3b82019-03-14 21:39:448297// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8298// HTTP/2 stream dependency and weights given the request priority.
8299TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8300 session_params_.enable_quic = true;
8301 session_params_.enable_quic_proxies_for_https_urls = true;
8302 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8303 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8304
8305 const RequestPriority kRequestPriority = MEDIUM;
8306 const RequestPriority kRequestPriority2 = LOWEST;
8307
Ryan Hamiltonabad59e2019-06-06 04:02:598308 MockQuicData mock_quic_data(version_);
Matt Menkeedaf3b82019-03-14 21:39:448309 quic::QuicStreamOffset header_stream_offset = 0;
8310 mock_quic_data.AddWrite(
8311 ASYNC, ConstructInitialSettingsPacket(1, &header_stream_offset));
8312 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8313 // This should never be reached.
8314 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8315 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8316
8317 // Second connection attempt just fails - result doesn't really matter.
Ryan Hamiltonabad59e2019-06-06 04:02:598318 MockQuicData mock_quic_data2(version_);
Matt Menkeedaf3b82019-03-14 21:39:448319 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8320 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8321
8322 int original_max_sockets_per_group =
8323 ClientSocketPoolManager::max_sockets_per_group(
8324 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8325 ClientSocketPoolManager::set_max_sockets_per_group(
8326 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8327 int original_max_sockets_per_pool =
8328 ClientSocketPoolManager::max_sockets_per_pool(
8329 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8330 ClientSocketPoolManager::set_max_sockets_per_pool(
8331 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8332 CreateSession();
8333
8334 request_.url = GURL("https://mail.example.org/");
8335 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8336 TestCompletionCallback callback;
8337 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8338 EXPECT_EQ(ERR_IO_PENDING, rv);
8339
8340 HttpRequestInfo request2;
8341 request2.url = GURL("https://mail.example.org/some/other/path/");
8342 request2.traffic_annotation =
8343 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8344
8345 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8346 TestCompletionCallback callback2;
8347 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8348 EXPECT_EQ(ERR_IO_PENDING, rv2);
8349
8350 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8351 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8352
8353 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8354
8355 ClientSocketPoolManager::set_max_sockets_per_pool(
8356 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8357 original_max_sockets_per_pool);
8358 ClientSocketPoolManager::set_max_sockets_per_group(
8359 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8360 original_max_sockets_per_group);
8361}
8362
Yixin Wang46a273ec302018-01-23 17:59:568363// Test the request-challenge-retry sequence for basic auth, over a QUIC
8364// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148365TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568366 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8367 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568368
8369 std::unique_ptr<QuicTestPacketMaker> client_maker;
8370 std::unique_ptr<QuicTestPacketMaker> server_maker;
8371
8372 // On the second pass, the body read of the auth challenge is synchronous, so
8373 // IsConnectedAndIdle returns false. The socket should still be drained and
8374 // reused. See http://crbug.com/544255.
8375 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338376 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178377 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8378 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338379 client_headers_include_h2_stream_dependency_));
8380 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178381 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8382 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568383
8384 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148385 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568386 proxy_resolution_service_ =
8387 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498388 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568389
Ryan Hamiltonabad59e2019-06-06 04:02:598390 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528391 quic::QuicStreamOffset client_header_stream_offset = 0;
8392 quic::QuicStreamOffset server_header_stream_offset = 0;
8393 quic::QuicStreamOffset client_data_offset = 0;
8394 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568395
Zhongyi Shi32f2fd02018-04-16 18:23:438396 mock_quic_data.AddWrite(SYNCHRONOUS,
8397 client_maker->MakeInitialSettingsPacket(
8398 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568399
8400 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438401 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568402 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338403 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
Matt Menke6e879bd2019-03-18 17:26:048404 ConvertRequestPriorityToQuicPriority(
8405 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568406 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8407 &client_header_stream_offset));
8408
Ryan Hamilton0239aac2018-05-19 00:03:138409 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568410 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8411 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8412 headers["content-length"] = "10";
8413 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438414 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338415 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8416 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568417
8418 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438419 mock_quic_data.AddRead(
8420 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338421 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8422 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568423 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438424 mock_quic_data.AddRead(
8425 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338426 2, GetNthClientInitiatedBidirectionalStreamId(0),
8427 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568428 }
8429 server_data_offset += 10;
8430
Zhongyi Shi32f2fd02018-04-16 18:23:438431 mock_quic_data.AddWrite(SYNCHRONOUS,
8432 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568433
8434 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338435 SYNCHRONOUS,
8436 client_maker->MakeRstPacket(
8437 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188438 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8439 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568440
8441 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8442 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8443 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048444 SYNCHRONOUS,
8445 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8446 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8447 ConvertRequestPriorityToQuicPriority(
8448 HttpProxyConnectJob::kH2QuicTunnelPriority),
8449 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
8450 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568451
8452 // Response to wrong password
8453 headers =
8454 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8455 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8456 headers["content-length"] = "10";
8457 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438458 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338459 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8460 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568461 mock_quic_data.AddRead(SYNCHRONOUS,
8462 ERR_IO_PENDING); // No more data to read
8463
Fan Yang32c5a112018-12-10 20:06:338464 mock_quic_data.AddWrite(
8465 SYNCHRONOUS,
8466 client_maker->MakeAckAndRstPacket(
8467 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8468 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568469
8470 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8471 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8472
8473 CreateSession();
8474
8475 request_.url = GURL("https://mail.example.org/");
8476 // Ensure that proxy authentication is attempted even
8477 // when the no authentication data flag is set.
8478 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8479 {
8480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8481 HeadersHandler headers_handler;
8482 trans.SetBeforeHeadersSentCallback(
8483 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8484 base::Unretained(&headers_handler)));
8485 RunTransaction(&trans);
8486
8487 const HttpResponseInfo* response = trans.GetResponseInfo();
8488 ASSERT_TRUE(response != nullptr);
8489 ASSERT_TRUE(response->headers.get() != nullptr);
8490 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8491 response->headers->GetStatusLine());
8492 EXPECT_TRUE(response->headers->IsKeepAlive());
8493 EXPECT_EQ(407, response->headers->response_code());
8494 EXPECT_EQ(10, response->headers->GetContentLength());
8495 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588496 base::Optional<AuthChallengeInfo> auth_challenge =
8497 response->auth_challenge;
8498 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568499 EXPECT_TRUE(auth_challenge->is_proxy);
8500 EXPECT_EQ("https://proxy.example.org:70",
8501 auth_challenge->challenger.Serialize());
8502 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8503 EXPECT_EQ("basic", auth_challenge->scheme);
8504
8505 TestCompletionCallback callback;
8506 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8507 callback.callback());
8508 EXPECT_EQ(ERR_IO_PENDING, rv);
8509 EXPECT_EQ(OK, callback.WaitForResult());
8510
8511 response = trans.GetResponseInfo();
8512 ASSERT_TRUE(response != nullptr);
8513 ASSERT_TRUE(response->headers.get() != nullptr);
8514 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8515 response->headers->GetStatusLine());
8516 EXPECT_TRUE(response->headers->IsKeepAlive());
8517 EXPECT_EQ(407, response->headers->response_code());
8518 EXPECT_EQ(10, response->headers->GetContentLength());
8519 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588520 auth_challenge = response->auth_challenge;
8521 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568522 EXPECT_TRUE(auth_challenge->is_proxy);
8523 EXPECT_EQ("https://proxy.example.org:70",
8524 auth_challenge->challenger.Serialize());
8525 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8526 EXPECT_EQ("basic", auth_challenge->scheme);
8527 }
8528 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8529 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8530 // reused because it's not connected).
8531 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8532 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8533 }
8534}
8535
Yixin Wang385652a2018-02-16 02:37:238536TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8537 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8538 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568539 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238540 !client_headers_include_h2_stream_dependency_) {
8541 return;
8542 }
8543
8544 session_params_.origins_to_force_quic_on.insert(
8545 HostPortPair::FromString("mail.example.org:443"));
8546
Fan Yang32c5a112018-12-10 20:06:338547 const quic::QuicStreamId client_stream_0 =
8548 GetNthClientInitiatedBidirectionalStreamId(0);
8549 const quic::QuicStreamId client_stream_1 =
8550 GetNthClientInitiatedBidirectionalStreamId(1);
8551 const quic::QuicStreamId client_stream_2 =
8552 GetNthClientInitiatedBidirectionalStreamId(2);
8553 const quic::QuicStreamId push_stream_0 =
8554 GetNthServerInitiatedUnidirectionalStreamId(0);
8555 const quic::QuicStreamId push_stream_1 =
8556 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238557
Ryan Hamiltonabad59e2019-06-06 04:02:598558 MockQuicData mock_quic_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528559 quic::QuicStreamOffset header_stream_offset = 0;
8560 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238561 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438562 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238563
8564 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438565 mock_quic_data.AddWrite(SYNCHRONOUS,
8566 ConstructClientRequestHeadersPacket(
8567 2, client_stream_0, true, true, HIGHEST,
8568 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8569 &header_stream_offset));
8570 mock_quic_data.AddWrite(SYNCHRONOUS,
8571 ConstructClientRequestHeadersPacket(
8572 3, client_stream_1, true, true, MEDIUM,
8573 GetRequestHeaders("GET", "https", "/1.jpg"),
8574 client_stream_0, &header_stream_offset));
8575 mock_quic_data.AddWrite(SYNCHRONOUS,
8576 ConstructClientRequestHeadersPacket(
8577 4, client_stream_2, true, true, MEDIUM,
8578 GetRequestHeaders("GET", "https", "/2.jpg"),
8579 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238580
8581 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438582 mock_quic_data.AddRead(
8583 ASYNC, ConstructServerResponseHeadersPacket(
8584 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8585 &server_header_offset));
8586 mock_quic_data.AddRead(
8587 ASYNC, ConstructServerResponseHeadersPacket(
8588 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8589 &server_header_offset));
8590 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8591 mock_quic_data.AddRead(
8592 ASYNC, ConstructServerResponseHeadersPacket(
8593 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8594 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238595
8596 // Server sends two push promises associated with |client_stream_0|; client
8597 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8598 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438599 mock_quic_data.AddRead(ASYNC,
8600 ConstructServerPushPromisePacket(
8601 4, client_stream_0, push_stream_0, false,
8602 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8603 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238604 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438605 SYNCHRONOUS,
8606 ConstructClientAckAndPriorityFramesPacket(
8607 6, false, 4, 3, 1,
8608 {{push_stream_0, client_stream_2,
8609 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8610 &header_stream_offset));
8611 mock_quic_data.AddRead(ASYNC,
8612 ConstructServerPushPromisePacket(
8613 5, client_stream_0, push_stream_1, false,
8614 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8615 &server_header_offset, &server_maker_));
8616 mock_quic_data.AddWrite(
8617 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238618 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8619 DEFAULT_PRIORITY, &header_stream_offset));
8620
8621 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438622 mock_quic_data.AddRead(
8623 ASYNC, ConstructServerResponseHeadersPacket(
8624 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8625 &server_header_offset));
8626 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8627 mock_quic_data.AddRead(
8628 ASYNC, ConstructServerResponseHeadersPacket(
8629 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8630 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238631
8632 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8633 // priority updates to match the request's priority. Client sends PRIORITY
8634 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438635 mock_quic_data.AddWrite(
8636 SYNCHRONOUS,
8637 ConstructClientAckAndPriorityFramesPacket(
8638 9, false, 7, 7, 1,
8639 {{push_stream_1, client_stream_2,
8640 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8641 {push_stream_0, client_stream_0,
8642 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8643 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238644
8645 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438646 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438647 mock_quic_data.AddRead(
8648 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418649 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438650 mock_quic_data.AddRead(
8651 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418652 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438653 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8654 mock_quic_data.AddRead(
8655 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418656 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438657 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438658 mock_quic_data.AddRead(
8659 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418660 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438661 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8662 mock_quic_data.AddRead(
8663 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418664 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238665
Yixin Wang385652a2018-02-16 02:37:238666 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8667 mock_quic_data.AddRead(ASYNC, 0); // EOF
8668 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8669
8670 // The non-alternate protocol job needs to hang in order to guarantee that
8671 // the alternate-protocol job will "win".
8672 AddHangingNonAlternateProtocolSocketData();
8673
8674 CreateSession();
8675
8676 request_.url = GURL("https://mail.example.org/0.jpg");
8677 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8678 TestCompletionCallback callback_0;
8679 EXPECT_EQ(ERR_IO_PENDING,
8680 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8681 base::RunLoop().RunUntilIdle();
8682
8683 request_.url = GURL("https://mail.example.org/1.jpg");
8684 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8685 TestCompletionCallback callback_1;
8686 EXPECT_EQ(ERR_IO_PENDING,
8687 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8688 base::RunLoop().RunUntilIdle();
8689
8690 request_.url = GURL("https://mail.example.org/2.jpg");
8691 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8692 TestCompletionCallback callback_2;
8693 EXPECT_EQ(ERR_IO_PENDING,
8694 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8695 base::RunLoop().RunUntilIdle();
8696
8697 // Client makes request that matches resource pushed in |pushed_stream_0|.
8698 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8699 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8700 TestCompletionCallback callback_3;
8701 EXPECT_EQ(ERR_IO_PENDING,
8702 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8703 base::RunLoop().RunUntilIdle();
8704
8705 EXPECT_TRUE(callback_0.have_result());
8706 EXPECT_EQ(OK, callback_0.WaitForResult());
8707 EXPECT_TRUE(callback_1.have_result());
8708 EXPECT_EQ(OK, callback_1.WaitForResult());
8709 EXPECT_TRUE(callback_2.have_result());
8710 EXPECT_EQ(OK, callback_2.WaitForResult());
8711
8712 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8713 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8714 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8715 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8716
8717 mock_quic_data.Resume();
8718 base::RunLoop().RunUntilIdle();
8719 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8720 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8721}
8722
Matt Menke26e41542019-06-05 01:09:518723// Test that NetworkIsolationKey is respected by QUIC connections, when
8724// kPartitionConnectionsByNetworkIsolationKey is enabled.
8725TEST_P(QuicNetworkTransactionTest, NetworkIsolation) {
8726 NetworkIsolationKey network_isolation_key1(
8727 url::Origin::Create(GURL("http://origin1/")));
8728 NetworkIsolationKey network_isolation_key2(
8729 url::Origin::Create(GURL("http://origin2/")));
8730
8731 session_params_.origins_to_force_quic_on.insert(
8732 HostPortPair::FromString("mail.example.org:443"));
8733
8734 // Whether to use an H2 proxy. When false, uses HTTPS H2 requests without a
8735 // proxy, when true, uses HTTP requests over an H2 proxy. It's unnecessary to
8736 // test tunneled HTTPS over an H2 proxy, since that path sets up H2 sessions
8737 // the same way as the HTTP over H2 proxy case.
8738 for (bool use_proxy : {false, true}) {
8739 SCOPED_TRACE(use_proxy);
8740
8741 if (use_proxy) {
8742 proxy_resolution_service_ =
8743 ProxyResolutionService::CreateFixedFromPacResult(
8744 "QUIC mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
8745 } else {
8746 proxy_resolution_service_ = ProxyResolutionService::CreateDirect();
8747 }
8748
8749 GURL url1;
8750 GURL url2;
8751 GURL url3;
8752 if (use_proxy) {
8753 url1 = GURL("http://mail.example.org/1");
8754 url2 = GURL("http://mail.example.org/2");
8755 url3 = GURL("http://mail.example.org/3");
8756 } else {
8757 url1 = GURL("https://mail.example.org/1");
8758 url2 = GURL("https://mail.example.org/2");
8759 url3 = GURL("https://mail.example.org/3");
8760 }
8761
8762 for (bool partition_connections : {false, true}) {
8763 SCOPED_TRACE(partition_connections);
8764
8765 base::test::ScopedFeatureList feature_list;
8766 if (partition_connections) {
8767 feature_list.InitAndEnableFeature(
8768 features::kPartitionConnectionsByNetworkIsolationKey);
8769 } else {
8770 feature_list.InitAndDisableFeature(
8771 features::kPartitionConnectionsByNetworkIsolationKey);
8772 }
8773
8774 // Reads and writes for the unpartitioned case, where only one socket is
8775 // used.
8776
8777 session_params_.origins_to_force_quic_on.insert(
8778 HostPortPair::FromString("mail.example.org:443"));
8779
Ryan Hamiltonabad59e2019-06-06 04:02:598780 MockQuicData unpartitioned_mock_quic_data(version_);
Matt Menke26e41542019-06-05 01:09:518781 quic::QuicStreamOffset request_header_offset = 0;
8782 quic::QuicStreamOffset response_header_offset = 0;
8783 QuicTestPacketMaker client_maker1(
8784 version_,
8785 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8786 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8787 client_headers_include_h2_stream_dependency_);
8788 QuicTestPacketMaker server_maker1(
8789 version_,
8790 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8791 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8792
8793 unpartitioned_mock_quic_data.AddWrite(
8794 SYNCHRONOUS,
8795 client_maker1.MakeInitialSettingsPacket(1, &request_header_offset));
8796
8797 unpartitioned_mock_quic_data.AddWrite(
8798 SYNCHRONOUS,
8799 client_maker1.MakeRequestHeadersPacketWithOffsetTracking(
8800 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
8801 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
8802 GetRequestHeaders("GET", url1.scheme(), "/1"), 0,
8803 &request_header_offset));
8804 unpartitioned_mock_quic_data.AddRead(
8805 ASYNC,
8806 server_maker1.MakeResponseHeadersPacketWithOffsetTracking(
8807 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8808 GetResponseHeaders("200 OK"), &response_header_offset));
8809 unpartitioned_mock_quic_data.AddRead(
8810 ASYNC, server_maker1.MakeDataPacket(
8811 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8812 true, 0, ConstructDataHeader(1) + "1"));
8813 unpartitioned_mock_quic_data.AddWrite(
8814 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
8815
8816 unpartitioned_mock_quic_data.AddWrite(
8817 SYNCHRONOUS,
8818 client_maker1.MakeRequestHeadersPacketWithOffsetTracking(
8819 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
8820 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
8821 GetRequestHeaders("GET", url2.scheme(), "/2"), 0,
8822 &request_header_offset));
8823 unpartitioned_mock_quic_data.AddRead(
8824 ASYNC,
8825 server_maker1.MakeResponseHeadersPacketWithOffsetTracking(
8826 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8827 GetResponseHeaders("200 OK"), &response_header_offset));
8828 unpartitioned_mock_quic_data.AddRead(
8829 ASYNC, server_maker1.MakeDataPacket(
8830 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8831 true, 0, ConstructDataHeader(1) + "2"));
8832 unpartitioned_mock_quic_data.AddWrite(
8833 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
8834
8835 unpartitioned_mock_quic_data.AddWrite(
8836 SYNCHRONOUS,
8837 client_maker1.MakeRequestHeadersPacketWithOffsetTracking(
8838 6, GetNthClientInitiatedBidirectionalStreamId(2), false, true,
8839 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
8840 GetRequestHeaders("GET", url3.scheme(), "/3"), 0,
8841 &request_header_offset));
8842 unpartitioned_mock_quic_data.AddRead(
8843 ASYNC,
8844 server_maker1.MakeResponseHeadersPacketWithOffsetTracking(
8845 5, GetNthClientInitiatedBidirectionalStreamId(2), false, false,
8846 GetResponseHeaders("200 OK"), &response_header_offset));
8847 unpartitioned_mock_quic_data.AddRead(
8848 ASYNC, server_maker1.MakeDataPacket(
8849 6, GetNthClientInitiatedBidirectionalStreamId(2), false,
8850 true, 0, ConstructDataHeader(1) + "3"));
8851 unpartitioned_mock_quic_data.AddWrite(
8852 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(7, 6, 5, 1));
8853
8854 unpartitioned_mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8855
8856 // Reads and writes for the partitioned case, where two sockets are used.
8857
Ryan Hamiltonabad59e2019-06-06 04:02:598858 MockQuicData partitioned_mock_quic_data1(version_);
Matt Menke26e41542019-06-05 01:09:518859 request_header_offset = 0;
8860 response_header_offset = 0;
8861 QuicTestPacketMaker client_maker2(
8862 version_,
8863 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8864 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8865 client_headers_include_h2_stream_dependency_);
8866 QuicTestPacketMaker server_maker2(
8867 version_,
8868 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8869 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8870
8871 partitioned_mock_quic_data1.AddWrite(
8872 SYNCHRONOUS,
8873 client_maker2.MakeInitialSettingsPacket(1, &request_header_offset));
8874
8875 partitioned_mock_quic_data1.AddWrite(
8876 SYNCHRONOUS,
8877 client_maker2.MakeRequestHeadersPacketWithOffsetTracking(
8878 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
8879 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
8880 GetRequestHeaders("GET", url1.scheme(), "/1"), 0,
8881 &request_header_offset));
8882 partitioned_mock_quic_data1.AddRead(
8883 ASYNC,
8884 server_maker2.MakeResponseHeadersPacketWithOffsetTracking(
8885 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8886 GetResponseHeaders("200 OK"), &response_header_offset));
8887 partitioned_mock_quic_data1.AddRead(
8888 ASYNC, server_maker2.MakeDataPacket(
8889 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8890 true, 0, ConstructDataHeader(1) + "1"));
8891 partitioned_mock_quic_data1.AddWrite(
8892 SYNCHRONOUS, client_maker2.MakeAckPacket(3, 2, 1, 1, true));
8893
8894 partitioned_mock_quic_data1.AddWrite(
8895 SYNCHRONOUS,
8896 client_maker2.MakeRequestHeadersPacketWithOffsetTracking(
8897 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
8898 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
8899 GetRequestHeaders("GET", url3.scheme(), "/3"), 0,
8900 &request_header_offset));
8901 partitioned_mock_quic_data1.AddRead(
8902 ASYNC,
8903 server_maker2.MakeResponseHeadersPacketWithOffsetTracking(
8904 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8905 GetResponseHeaders("200 OK"), &response_header_offset));
8906 partitioned_mock_quic_data1.AddRead(
8907 ASYNC, server_maker2.MakeDataPacket(
8908 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8909 true, 0, ConstructDataHeader(1) + "3"));
8910 partitioned_mock_quic_data1.AddWrite(
8911 SYNCHRONOUS, client_maker2.MakeAckPacket(5, 4, 3, 1, true));
8912
8913 partitioned_mock_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8914
Ryan Hamiltonabad59e2019-06-06 04:02:598915 MockQuicData partitioned_mock_quic_data2(version_);
Matt Menke26e41542019-06-05 01:09:518916 request_header_offset = 0;
8917 response_header_offset = 0;
8918 QuicTestPacketMaker client_maker3(
8919 version_,
8920 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8921 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8922 client_headers_include_h2_stream_dependency_);
8923 QuicTestPacketMaker server_maker3(
8924 version_,
8925 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8926 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
8927
8928 partitioned_mock_quic_data2.AddWrite(
8929 SYNCHRONOUS,
8930 client_maker3.MakeInitialSettingsPacket(1, &request_header_offset));
8931
8932 partitioned_mock_quic_data2.AddWrite(
8933 SYNCHRONOUS,
8934 client_maker3.MakeRequestHeadersPacketWithOffsetTracking(
8935 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
8936 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
8937 GetRequestHeaders("GET", url2.scheme(), "/2"), 0,
8938 &request_header_offset));
8939 partitioned_mock_quic_data2.AddRead(
8940 ASYNC,
8941 server_maker3.MakeResponseHeadersPacketWithOffsetTracking(
8942 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
8943 GetResponseHeaders("200 OK"), &response_header_offset));
8944 partitioned_mock_quic_data2.AddRead(
8945 ASYNC, server_maker3.MakeDataPacket(
8946 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8947 true, 0, ConstructDataHeader(1) + "2"));
8948 partitioned_mock_quic_data2.AddWrite(
8949 SYNCHRONOUS, client_maker3.MakeAckPacket(3, 2, 1, 1, true));
8950
8951 partitioned_mock_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8952
8953 if (partition_connections) {
8954 partitioned_mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
8955 partitioned_mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8956 } else {
8957 unpartitioned_mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8958 }
8959
8960 CreateSession();
8961
8962 TestCompletionCallback callback;
8963 HttpRequestInfo request1;
8964 request1.method = "GET";
8965 request1.url = GURL(url1);
8966 request1.traffic_annotation =
8967 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8968 request1.network_isolation_key = network_isolation_key1;
8969 HttpNetworkTransaction trans1(LOWEST, session_.get());
8970 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
8971 EXPECT_THAT(callback.GetResult(rv), IsOk());
8972 std::string response_data1;
8973 EXPECT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
8974 EXPECT_EQ("1", response_data1);
8975
8976 HttpRequestInfo request2;
8977 request2.method = "GET";
8978 request2.url = GURL(url2);
8979 request2.traffic_annotation =
8980 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8981 request2.network_isolation_key = network_isolation_key2;
8982 HttpNetworkTransaction trans2(LOWEST, session_.get());
8983 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
8984 EXPECT_THAT(callback.GetResult(rv), IsOk());
8985 std::string response_data2;
8986 EXPECT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
8987 EXPECT_EQ("2", response_data2);
8988
8989 HttpRequestInfo request3;
8990 request3.method = "GET";
8991 request3.url = GURL(url3);
8992 request3.traffic_annotation =
8993 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8994 request3.network_isolation_key = network_isolation_key1;
8995 HttpNetworkTransaction trans3(LOWEST, session_.get());
8996 rv = trans3.Start(&request3, callback.callback(), NetLogWithSource());
8997 EXPECT_THAT(callback.GetResult(rv), IsOk());
8998 std::string response_data3;
8999 EXPECT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
9000 EXPECT_EQ("3", response_data3);
9001
9002 if (partition_connections) {
9003 EXPECT_TRUE(partitioned_mock_quic_data1.AllReadDataConsumed());
9004 EXPECT_TRUE(partitioned_mock_quic_data1.AllWriteDataConsumed());
9005 EXPECT_TRUE(partitioned_mock_quic_data2.AllReadDataConsumed());
9006 EXPECT_TRUE(partitioned_mock_quic_data2.AllWriteDataConsumed());
9007 } else {
9008 EXPECT_TRUE(unpartitioned_mock_quic_data.AllReadDataConsumed());
9009 EXPECT_TRUE(unpartitioned_mock_quic_data.AllWriteDataConsumed());
9010 }
9011 }
9012 }
9013}
9014
9015// Test that two requests to the same origin over QUIC tunnels use different
9016// QUIC sessions if their NetworkIsolationKeys don't match, and
9017// kPartitionConnectionsByNetworkIsolationKey is enabled.
9018TEST_P(QuicNetworkTransactionTest, NetworkIsolationTunnel) {
9019 base::test::ScopedFeatureList feature_list;
9020 feature_list.InitAndEnableFeature(
9021 features::kPartitionConnectionsByNetworkIsolationKey);
9022
9023 session_params_.enable_quic = true;
9024 session_params_.enable_quic_proxies_for_https_urls = true;
9025 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
9026 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9027
9028 const char kGetRequest[] =
9029 "GET / HTTP/1.1\r\n"
9030 "Host: mail.example.org\r\n"
9031 "Connection: keep-alive\r\n\r\n";
9032 const char kGetResponse[] =
9033 "HTTP/1.1 200 OK\r\n"
9034 "Content-Length: 10\r\n\r\n";
9035
Ryan Hamiltonabad59e2019-06-06 04:02:599036 std::unique_ptr<MockQuicData> mock_quic_data[2] = {
9037 std::make_unique<MockQuicData>(version_),
9038 std::make_unique<MockQuicData>(version_)};
Matt Menke26e41542019-06-05 01:09:519039
9040 for (int index : {0, 1}) {
9041 QuicTestPacketMaker client_maker(
9042 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9043 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
9044 client_headers_include_h2_stream_dependency_);
9045 QuicTestPacketMaker server_maker(
9046 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
9047 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false);
9048
9049 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltonabad59e2019-06-06 04:02:599050 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519051 SYNCHRONOUS,
9052 client_maker.MakeInitialSettingsPacket(1, &header_stream_offset));
9053
Ryan Hamiltonabad59e2019-06-06 04:02:599054 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519055 SYNCHRONOUS,
9056 client_maker.MakeRequestHeadersPacketWithOffsetTracking(
9057 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
9058 ConvertRequestPriorityToQuicPriority(
9059 HttpProxyConnectJob::kH2QuicTunnelPriority),
9060 ConnectRequestHeaders("mail.example.org:443"), 0,
9061 &header_stream_offset));
Ryan Hamiltonabad59e2019-06-06 04:02:599062 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519063 ASYNC, server_maker.MakeResponseHeadersPacketWithOffsetTracking(
9064 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
9065 false, GetResponseHeaders("200 OK"), nullptr));
9066
9067 std::string header = ConstructDataHeader(strlen(kGetRequest));
9068 if (version_.transport_version != quic::QUIC_VERSION_99) {
Ryan Hamiltonabad59e2019-06-06 04:02:599069 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519070 SYNCHRONOUS,
9071 client_maker.MakeAckAndDataPacket(
9072 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
9073 false, 0, quic::QuicStringPiece(kGetRequest)));
9074 } else {
Ryan Hamiltonabad59e2019-06-06 04:02:599075 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519076 SYNCHRONOUS,
9077 client_maker.MakeAckAndMultipleDataFramesPacket(
9078 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
9079 false, 0, {header, std::string(kGetRequest)}));
9080 }
9081
9082 std::string header2 = ConstructDataHeader(strlen(kGetResponse));
Ryan Hamiltonabad59e2019-06-06 04:02:599083 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519084 ASYNC, server_maker.MakeDataPacket(
9085 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
9086 false, 0, header2 + std::string(kGetResponse)));
Ryan Hamiltonabad59e2019-06-06 04:02:599087 mock_quic_data[index]->AddRead(
Matt Menke26e41542019-06-05 01:09:519088 SYNCHRONOUS, server_maker.MakeDataPacket(
9089 3, GetNthClientInitiatedBidirectionalStreamId(0),
9090 false, false, strlen(kGetResponse) + header2.length(),
9091 ConstructDataHeader(10) + std::string("0123456789")));
Ryan Hamiltonabad59e2019-06-06 04:02:599092 mock_quic_data[index]->AddWrite(
Matt Menke26e41542019-06-05 01:09:519093 SYNCHRONOUS, client_maker.MakeAckPacket(4, 3, 2, 1, true));
Ryan Hamiltonabad59e2019-06-06 04:02:599094 mock_quic_data[index]->AddRead(SYNCHRONOUS,
9095 ERR_IO_PENDING); // No more data to read
Matt Menke26e41542019-06-05 01:09:519096
Ryan Hamiltonabad59e2019-06-06 04:02:599097 mock_quic_data[index]->AddSocketDataToFactory(&socket_factory_);
Matt Menke26e41542019-06-05 01:09:519098 }
9099
9100 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
9101 SSLSocketDataProvider ssl_data2(ASYNC, OK);
9102 socket_factory_.AddSSLSocketDataProvider(&ssl_data2);
9103
9104 CreateSession();
9105
9106 request_.url = GURL("https://mail.example.org/");
9107 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
9108 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
9109 RunTransaction(&trans);
9110 CheckResponseData(&trans, "0123456789");
9111
9112 HttpRequestInfo request2;
9113 request_.network_isolation_key =
9114 NetworkIsolationKey(url::Origin::Create(GURL("http://origin1/")));
9115 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session_.get());
9116 RunTransaction(&trans2);
9117 CheckResponseData(&trans2, "0123456789");
9118
Ryan Hamiltonabad59e2019-06-06 04:02:599119 EXPECT_TRUE(mock_quic_data[0]->AllReadDataConsumed());
9120 EXPECT_TRUE(mock_quic_data[0]->AllWriteDataConsumed());
9121 EXPECT_TRUE(mock_quic_data[1]->AllReadDataConsumed());
9122 EXPECT_TRUE(mock_quic_data[1]->AllWriteDataConsumed());
Matt Menke26e41542019-06-05 01:09:519123}
9124
[email protected]61a527782013-02-21 03:58:009125} // namespace test
9126} // namespace net