blob: 17f9ac870e23b58e5f2065febb6f9e56d208efbc [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"
rtenneti56977812016-01-15 19:26:5620#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5821#include "net/base/completion_once_callback.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3722#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0323#include "net/base/mock_network_change_notifier.h"
[email protected]61a527782013-02-21 03:58:0024#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0425#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2026#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1127#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1228#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5329#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0030#include "net/http/http_auth_handler_factory.h"
31#include "net/http/http_network_session.h"
32#include "net/http/http_network_transaction.h"
Matt Menke6e879bd2019-03-18 17:26:0433#include "net/http/http_proxy_connect_job.h"
[email protected]61a527782013-02-21 03:58:0034#include "net/http/http_server_properties_impl.h"
35#include "net/http/http_stream.h"
36#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1937#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1138#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0039#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5140#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4641#include "net/log/test_net_log_entry.h"
42#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4043#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0344#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4045#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0846#include "net/quic/crypto/proof_verifier_chromium.h"
47#include "net/quic/mock_crypto_client_stream_factory.h"
48#include "net/quic/mock_quic_data.h"
49#include "net/quic/quic_chromium_alarm_factory.h"
50#include "net/quic/quic_http_stream.h"
51#include "net/quic/quic_http_utils.h"
52#include "net/quic/quic_stream_factory_peer.h"
53#include "net/quic/quic_test_packet_maker.h"
54#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0055#include "net/socket/client_socket_factory.h"
56#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2157#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2858#include "net/socket/socket_performance_watcher.h"
59#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0060#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5861#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5762#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2963#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0164#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4365#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0166#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5167#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
68#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
69#include "net/third_party/quiche/src/quic/core/quic_framer.h"
70#include "net/third_party/quiche/src/quic/core/quic_utils.h"
71#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
72#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
73#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
74#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
75#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
76#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
77#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
78#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1479#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
80#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2981#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0082#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4883#include "net/url_request/url_request.h"
84#include "net/url_request/url_request_job_factory_impl.h"
85#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0186#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0087#include "testing/gtest/include/gtest/gtest.h"
88#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4689#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0090
Reilly Grant89a7e512018-01-20 01:57:1691using ::testing::ElementsAre;
92using ::testing::Key;
93
bnc508835902015-05-12 20:10:2994namespace net {
95namespace test {
[email protected]61a527782013-02-21 03:58:0096
97namespace {
98
bnc359ed2a2016-04-29 20:43:4599enum DestinationType {
100 // In pooling tests with two requests for different origins to the same
101 // destination, the destination should be
102 SAME_AS_FIRST, // the same as the first origin,
103 SAME_AS_SECOND, // the same as the second origin, or
104 DIFFERENT, // different from both.
105};
106
rchf114d982015-10-21 01:34:56107static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52108 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12109static const char kQuicAlternativeServiceWithProbabilityHeader[] =
110 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56111static const char kQuicAlternativeServiceDifferentPortHeader[] =
112 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20113
rch9ae5b3b2016-02-11 00:36:29114const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45115const char kDifferentHostname[] = "different.example.com";
116
117// Run QuicNetworkTransactionWithDestinationTest instances with all value
118// combinations of version and destination_type.
119struct PoolingTestParams {
120 friend std::ostream& operator<<(std::ostream& os,
121 const PoolingTestParams& p) {
122 os << "{ version: " << QuicVersionToString(p.version)
123 << ", destination_type: ";
124 switch (p.destination_type) {
125 case SAME_AS_FIRST:
126 os << "SAME_AS_FIRST";
127 break;
128 case SAME_AS_SECOND:
129 os << "SAME_AS_SECOND";
130 break;
131 case DIFFERENT:
132 os << "DIFFERENT";
133 break;
134 }
Yixin Wang079ad542018-01-11 04:06:05135 os << ", client_headers_include_h2_stream_dependency: "
136 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45137 os << " }";
138 return os;
139 }
140
Ryan Hamilton8d9ee76e2018-05-29 23:52:52141 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45142 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05143 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45144};
145
zhongyie537a002017-06-27 16:48:21146std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52147 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21148 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52149 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21150 if (!result.empty())
151 result.append(",");
Raul Tambre8c1981dd2019-02-08 02:22:26152 result.append(base::NumberToString(version));
zhongyie537a002017-06-27 16:48:21153 }
154 return result;
155}
156
bnc359ed2a2016-04-29 20:43:45157std::vector<PoolingTestParams> GetPoolingTestParams() {
158 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52159 quic::QuicTransportVersionVector all_supported_versions =
160 quic::AllSupportedTransportVersions();
161 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05162 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
163 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
164 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
165 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
166 params.push_back(PoolingTestParams{version, DIFFERENT, false});
167 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45168 }
169 return params;
170}
bncb07c05532015-05-14 19:07:20171
[email protected]61a527782013-02-21 03:58:00172} // namespace
173
ryansturm49a8cb12016-06-15 16:51:09174class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12175 public:
ryansturm49a8cb12016-06-15 16:51:09176 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12177
ryansturm49a8cb12016-06-15 16:51:09178 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12179
ryansturm49a8cb12016-06-15 16:51:09180 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
181 HttpRequestHeaders* request_headers) {
182 if (!proxy_info.is_http() && !proxy_info.is_https() &&
183 !proxy_info.is_quic()) {
184 return;
185 }
186 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12187 }
188
189 private:
ryansturm49a8cb12016-06-15 16:51:09190 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12191};
192
tbansal0f56a39a2016-04-07 22:03:38193class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40194 public:
tbansal180587c2017-02-16 15:13:23195 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
196 bool* rtt_notification_received)
197 : should_notify_updated_rtt_(should_notify_updated_rtt),
198 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38199 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40200
tbansal180587c2017-02-16 15:13:23201 bool ShouldNotifyUpdatedRTT() const override {
202 return *should_notify_updated_rtt_;
203 }
tbansalfdf5665b2015-09-21 22:46:40204
tbansal0f56a39a2016-04-07 22:03:38205 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
206 *rtt_notification_received_ = true;
207 }
208
209 void OnConnectionChanged() override {}
210
211 private:
tbansal180587c2017-02-16 15:13:23212 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38213 bool* rtt_notification_received_;
214
215 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
216};
217
218class TestSocketPerformanceWatcherFactory
219 : public SocketPerformanceWatcherFactory {
220 public:
221 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23222 : watcher_count_(0u),
223 should_notify_updated_rtt_(true),
224 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38225 ~TestSocketPerformanceWatcherFactory() override {}
226
227 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42228 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41229 const Protocol protocol,
230 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51231 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38232 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51233 }
234 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42235 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23236 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
237 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40238 }
239
tbansalc8a94ea2015-11-02 23:58:51240 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40241
tbansalc8a94ea2015-11-02 23:58:51242 bool rtt_notification_received() const { return rtt_notification_received_; }
243
tbansal180587c2017-02-16 15:13:23244 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
245 should_notify_updated_rtt_ = should_notify_updated_rtt;
246 }
247
tbansalc8a94ea2015-11-02 23:58:51248 private:
tbansal0f56a39a2016-04-07 22:03:38249 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23250 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51251 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38252
253 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51254};
255
Ryan Hamilton8d9ee76e2018-05-29 23:52:52256class QuicNetworkTransactionTest
257 : public PlatformTest,
258 public ::testing::WithParamInterface<
259 std::tuple<quic::QuicTransportVersion, bool>>,
260 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00261 protected:
[email protected]1c04f9522013-02-21 20:32:43262 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05263 : version_(std::get<0>(GetParam())),
264 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52265 supported_versions_(quic::test::SupportedTransportVersions(version_)),
David Schinazic8281052019-01-24 06:14:17266 random_generator_(0),
267 client_maker_(
268 version_,
269 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
270 &clock_,
271 kDefaultServerHostName,
272 quic::Perspective::IS_CLIENT,
273 client_headers_include_h2_stream_dependency_),
274 server_maker_(
275 version_,
276 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
277 &clock_,
278 kDefaultServerHostName,
279 quic::Perspective::IS_SERVER,
280 false),
rtenneti052774e2015-11-24 21:00:12281 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43282 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59283 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11284 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
rchf114d982015-10-21 01:34:56285 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19286 request_.method = "GET";
rchf114d982015-10-21 01:34:56287 std::string url("https://");
bncb07c05532015-05-14 19:07:20288 url.append(kDefaultServerHostName);
289 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19290 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10291 request_.traffic_annotation =
292 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52293 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56294
295 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29296 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56297 verify_details_.cert_verify_result.verified_cert = cert;
298 verify_details_.cert_verify_result.is_issued_by_known_root = true;
299 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43300 }
[email protected]61a527782013-02-21 03:58:00301
dcheng67be2b1f2014-10-27 21:47:29302 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00303 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55304 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00305 }
306
dcheng67be2b1f2014-10-27 21:47:29307 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00308 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
309 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55310 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00311 PlatformTest::TearDown();
312 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55313 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40314 session_.reset();
[email protected]61a527782013-02-21 03:58:00315 }
316
Ryan Hamilton8d9ee76e2018-05-29 23:52:52317 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23318 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03319 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52320 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30321 }
322
Ryan Hamilton8d9ee76e2018-05-29 23:52:52323 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23324 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03325 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52326 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58327 }
328
Ryan Hamilton8d9ee76e2018-05-29 23:52:52329 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23330 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20332 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58333 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20334 }
335
Ryan Hamilton8d9ee76e2018-05-29 23:52:52336 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23337 uint64_t packet_number,
338 uint64_t largest_received,
339 uint64_t smallest_received,
340 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37341 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49342 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37343 }
344
Ryan Hamilton8d9ee76e2018-05-29 23:52:52345 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23346 uint64_t packet_number,
347 uint64_t largest_received,
348 uint64_t smallest_received,
349 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52350 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23351 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49352 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23353 ack_delay_time);
354 }
355
Ryan Hamilton8d9ee76e2018-05-29 23:52:52356 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23357 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52358 quic::QuicStreamId stream_id,
359 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23360 uint64_t largest_received,
361 uint64_t smallest_received,
362 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58363 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49364 num, false, stream_id, error_code, largest_received, smallest_received,
365 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20366 }
367
Ryan Hamilton8d9ee76e2018-05-29 23:52:52368 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23369 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52370 quic::QuicStreamId stream_id,
371 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56372 size_t bytes_written) {
373 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18374 bytes_written,
375 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56376 }
377
Ryan Hamilton8d9ee76e2018-05-29 23:52:52378 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23379 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
380 uint64_t largest_received,
381 uint64_t smallest_received,
382 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58383 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49384 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20385 }
[email protected]61a527782013-02-21 03:58:00386
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58388 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23389 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52390 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23391 uint64_t largest_received,
392 uint64_t smallest_received,
393 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52394 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50395 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58396 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12397 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49398 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12399 }
400
Ryan Hamilton8d9ee76e2018-05-29 23:52:52401 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23402 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12403 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52404 quic::QuicStreamId stream_id,
405 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58406 return server_maker_.MakeRstPacket(num, include_version, stream_id,
407 error_code);
zhongyica364fbb2015-12-12 03:39:12408 }
409
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23411 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52412 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36413 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37414 }
415
Ryan Hamilton8d9ee76e2018-05-29 23:52:52416 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23417 uint64_t packet_number,
418 uint64_t largest_received,
419 uint64_t smallest_received,
420 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37421 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49422 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37423 }
424
Ryan Hamilton8d9ee76e2018-05-29 23:52:52425 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23426 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57427 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52428 quic::QuicStreamId id,
429 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57430 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52431 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57432 return client_maker_.MakePriorityPacket(
433 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23434 ConvertRequestPriorityToQuicPriority(request_priority), offset);
435 }
436
Ryan Hamilton8d9ee76e2018-05-29 23:52:52437 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25438 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23439 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23440 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23441 uint64_t largest_received,
442 uint64_t smallest_received,
443 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25444 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
445 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52446 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25447 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23448 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25449 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57450 }
451
zhongyi32569c62016-01-08 02:54:30452 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13453 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
454 const std::string& scheme,
455 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58456 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30457 }
458
459 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13460 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
461 const std::string& scheme,
462 const std::string& path,
463 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50464 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00465 }
466
Ryan Hamilton0239aac2018-05-19 00:03:13467 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56468 return client_maker_.ConnectRequestHeaders(host_port);
469 }
470
Ryan Hamilton0239aac2018-05-19 00:03:13471 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58472 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00473 }
474
zhongyi32569c62016-01-08 02:54:30475 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13476 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
477 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58478 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30479 }
480
Ryan Hamilton8d9ee76e2018-05-29 23:52:52481 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23482 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52483 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05484 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00485 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52486 quic::QuicStreamOffset offset,
487 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58488 return server_maker_.MakeDataPacket(
489 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00490 }
491
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23493 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52494 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36495 bool should_include_version,
496 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52497 quic::QuicStreamOffset offset,
498 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36499 return client_maker_.MakeDataPacket(
500 packet_number, stream_id, should_include_version, fin, offset, data);
501 }
502
Renjied172e812019-01-16 05:12:35503 std::unique_ptr<quic::QuicEncryptedPacket>
504 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23505 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35506 quic::QuicStreamId stream_id,
507 bool should_include_version,
508 bool fin,
509 quic::QuicStreamOffset offset,
510 const std::vector<std::string> data_writes) {
511 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
512 should_include_version,
513 fin, offset, data_writes);
514 }
515
Ryan Hamilton8d9ee76e2018-05-29 23:52:52516 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23517 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56518 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52519 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23520 uint64_t largest_received,
521 uint64_t smallest_received,
522 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56523 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52524 quic::QuicStreamOffset offset,
525 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56526 return client_maker_.MakeAckAndDataPacket(
527 packet_number, include_version, stream_id, largest_received,
528 smallest_received, least_unacked, fin, offset, data);
529 }
530
Renjied172e812019-01-16 05:12:35531 std::unique_ptr<quic::QuicEncryptedPacket>
532 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23533 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35534 bool include_version,
535 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23536 uint64_t largest_received,
537 uint64_t smallest_received,
538 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35539 bool fin,
540 quic::QuicStreamOffset offset,
541 const std::vector<std::string> data_writes) {
542 return client_maker_.MakeAckAndMultipleDataFramesPacket(
543 packet_number, include_version, stream_id, largest_received,
544 smallest_received, least_unacked, fin, offset, data_writes);
545 }
546
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23548 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52549 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36550 bool should_include_version,
551 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52552 quic::QuicStreamOffset* offset,
553 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36554 return client_maker_.MakeForceHolDataPacket(
555 packet_number, stream_id, should_include_version, fin, offset, data);
556 }
557
Ryan Hamilton8d9ee76e2018-05-29 23:52:52558 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23559 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 quic::QuicStreamId stream_id,
561 bool should_include_version,
562 bool fin,
563 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56564 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
565 should_include_version, fin,
566 std::move(headers), nullptr);
567 }
568
Ryan Hamilton8d9ee76e2018-05-29 23:52:52569 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23570 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52571 quic::QuicStreamId stream_id,
572 bool should_include_version,
573 bool fin,
574 spdy::SpdyHeaderBlock headers,
575 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48576 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
577 should_include_version, fin,
578 std::move(headers), 0, offset);
579 }
580
Ryan Hamilton8d9ee76e2018-05-29 23:52:52581 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23582 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52583 quic::QuicStreamId stream_id,
584 bool should_include_version,
585 bool fin,
586 spdy::SpdyHeaderBlock headers,
587 quic::QuicStreamId parent_stream_id,
588 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56589 return ConstructClientRequestHeadersPacket(
590 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48591 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30592 }
593
Ryan Hamilton8d9ee76e2018-05-29 23:52:52594 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23595 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 quic::QuicStreamId stream_id,
597 bool should_include_version,
598 bool fin,
599 RequestPriority request_priority,
600 spdy::SpdyHeaderBlock headers,
601 quic::QuicStreamId parent_stream_id,
602 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13603 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56604 ConvertRequestPriorityToQuicPriority(request_priority);
605 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
606 packet_number, stream_id, should_include_version, fin, priority,
607 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00608 }
609
Ryan Hamilton8d9ee76e2018-05-29 23:52:52610 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25611 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23612 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52613 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25614 bool should_include_version,
615 bool fin,
616 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13617 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52618 quic::QuicStreamId parent_stream_id,
619 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25620 size_t* spdy_headers_frame_length,
621 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13622 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25623 ConvertRequestPriorityToQuicPriority(request_priority);
624 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
625 packet_number, stream_id, should_include_version, fin, priority,
626 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
627 data_writes);
628 }
629
Ryan Hamilton8d9ee76e2018-05-29 23:52:52630 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23631 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52632 quic::QuicStreamId stream_id,
633 bool should_include_version,
634 bool fin,
635 const std::vector<std::string>& data,
636 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27637 return client_maker_.MakeMultipleDataFramesPacket(
638 packet_number, stream_id, should_include_version, fin, offset, data);
639 }
640
Ryan Hamilton8d9ee76e2018-05-29 23:52:52641 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23642 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52643 quic::QuicStreamId stream_id,
644 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13645 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13646 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52647 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13648 QuicTestPacketMaker* maker) {
649 return maker->MakePushPromisePacket(
650 packet_number, stream_id, promised_stream_id, should_include_version,
651 false, std::move(headers), nullptr, offset);
652 }
653
Ryan Hamilton8d9ee76e2018-05-29 23:52:52654 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23655 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52656 quic::QuicStreamId stream_id,
657 bool should_include_version,
658 bool fin,
659 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27660 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
661 should_include_version, fin,
662 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30663 }
664
Ryan Hamilton8d9ee76e2018-05-29 23:52:52665 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23666 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52667 quic::QuicStreamId stream_id,
668 bool should_include_version,
669 bool fin,
670 spdy::SpdyHeaderBlock headers,
671 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58672 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25673 packet_number, stream_id, should_include_version, fin,
674 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30675 }
676
Victor Vasiliev076657c2019-03-12 02:46:43677 std::string ConstructDataHeader(size_t body_len) {
Renjief49758b2019-01-11 23:32:41678 if (version_ != quic::QUIC_VERSION_99) {
679 return "";
680 }
681 quic::HttpEncoder encoder;
682 std::unique_ptr<char[]> buffer;
683 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43684 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41685 }
686
Ryan Hamilton8d9ee76e2018-05-29 23:52:52687 void CreateSession(
688 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41689 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21690 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05691 session_params_.quic_headers_include_h2_stream_dependency =
692 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00693
mmenke6ddfbea2017-05-31 21:48:41694 session_context_.quic_clock = &clock_;
695 session_context_.quic_random = &random_generator_;
696 session_context_.client_socket_factory = &socket_factory_;
697 session_context_.quic_crypto_client_stream_factory =
698 &crypto_client_stream_factory_;
699 session_context_.host_resolver = &host_resolver_;
700 session_context_.cert_verifier = &cert_verifier_;
701 session_context_.transport_security_state = &transport_security_state_;
702 session_context_.cert_transparency_verifier =
703 cert_transparency_verifier_.get();
704 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
705 session_context_.socket_performance_watcher_factory =
706 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59707 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41708 session_context_.ssl_config_service = ssl_config_service_.get();
709 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
710 session_context_.http_server_properties = &http_server_properties_;
711 session_context_.net_log = net_log_.bound().net_log();
712
713 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12714 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56715 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
716 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00717 }
718
zhongyi86838d52017-06-30 01:19:44719 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21720
bnc691fda62016-08-12 00:43:16721 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19722 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42723 ASSERT_TRUE(response != nullptr);
724 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19725 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
726 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52727 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44728 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19729 response->connection_info);
730 }
731
bnc691fda62016-08-12 00:43:16732 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41733 const HttpResponseInfo* response = trans->GetResponseInfo();
734 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37735 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41736 }
737
bnc691fda62016-08-12 00:43:16738 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19739 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42740 ASSERT_TRUE(response != nullptr);
741 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19742 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
743 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52744 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52745 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19746 response->connection_info);
747 }
748
Yixin Wang46a273ec302018-01-23 17:59:56749 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
750 const HttpResponseInfo* response = trans->GetResponseInfo();
751 ASSERT_TRUE(response != nullptr);
752 ASSERT_TRUE(response->headers.get() != nullptr);
753 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
754 EXPECT_TRUE(response->was_fetched_via_spdy);
755 EXPECT_TRUE(response->was_alpn_negotiated);
756 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
757 response->connection_info);
758 }
759
bnc691fda62016-08-12 00:43:16760 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19761 const std::string& expected) {
762 std::string response_data;
bnc691fda62016-08-12 00:43:16763 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19764 EXPECT_EQ(expected, response_data);
765 }
766
bnc691fda62016-08-12 00:43:16767 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19768 TestCompletionCallback callback;
769 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01770 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
771 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19772 }
773
774 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16775 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
776 RunTransaction(&trans);
777 CheckWasHttpResponse(&trans);
778 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19779 }
780
tbansalc3308d72016-08-27 10:25:04781 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
782 bool used_proxy,
783 uint16_t port) {
784 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
785 HeadersHandler headers_handler;
786 trans.SetBeforeHeadersSentCallback(
787 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
788 base::Unretained(&headers_handler)));
789 RunTransaction(&trans);
790 CheckWasHttpResponse(&trans);
791 CheckResponsePort(&trans, port);
792 CheckResponseData(&trans, expected);
793 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47794 if (used_proxy) {
795 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
796 } else {
797 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
798 }
tbansalc3308d72016-08-27 10:25:04799 }
800
[email protected]aa9b14d2013-05-10 23:45:19801 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56802 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12803 }
804
bnc62a44f022015-04-02 15:59:41805 void SendRequestAndExpectQuicResponseFromProxyOnPort(
806 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46807 uint16_t port) {
bnc62a44f022015-04-02 15:59:41808 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19809 }
810
811 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27812 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19813 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46814 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21815 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12816 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21817 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44818 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19819 }
820
rchbe69cb902016-02-11 01:10:48821 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27822 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48823 const HostPortPair& alternative) {
824 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46825 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21826 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48827 alternative.port());
828 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21829 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44830 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48831 }
832
[email protected]aa9b14d2013-05-10 23:45:19833 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46834 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34835 const AlternativeServiceInfoVector alternative_service_info_vector =
836 http_server_properties_.GetAlternativeServiceInfos(server);
837 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07838 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54839 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19840 }
841
[email protected]4d590c9c2014-05-02 05:14:33842 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46843 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34844 const AlternativeServiceInfoVector alternative_service_info_vector =
845 http_server_properties_.GetAlternativeServiceInfos(server);
846 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54847 EXPECT_EQ(
848 kProtoQUIC,
849 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23850 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54851 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33852 }
853
[email protected]aa9b14d2013-05-10 23:45:19854 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42855 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30856 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30857 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30858 hanging_data->set_connect_data(hanging_connect);
859 hanging_data_.push_back(std::move(hanging_data));
860 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56861 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19862 }
863
Zhongyi Shia6b68d112018-09-24 07:49:03864 void SetUpTestForRetryConnectionOnAlternateNetwork() {
865 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
866 session_params_.quic_migrate_sessions_early_v2 = true;
867 session_params_.quic_retry_on_alternate_network_before_handshake = true;
868 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
869 MockNetworkChangeNotifier* mock_ncn =
870 scoped_mock_change_notifier_->mock_network_change_notifier();
871 mock_ncn->ForceNetworkHandlesSupported();
872 mock_ncn->SetConnectedNetworksList(
873 {kDefaultNetworkForTests, kNewNetworkForTests});
874 }
875
tbansalc3308d72016-08-27 10:25:04876 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
877 // alternative proxy. Verifies that if the alternative proxy job returns
878 // |error_code|, the request is fetched successfully by the main job.
879 void TestAlternativeProxy(int error_code) {
880 // Use a non-cryptographic scheme for the request URL since this request
881 // will be fetched via proxy with QUIC as the alternative service.
882 request_.url = GURL("http://example.org/");
883 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27884 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04885 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27886 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04887 };
888
Ryan Sleevib8d7ea02018-05-07 20:01:01889 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04890 socket_factory_.AddSocketDataProvider(&quic_data);
891
892 // Main job succeeds and the alternative job fails.
893 // Add data for two requests that will be read by the main job.
894 MockRead http_reads_1[] = {
895 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
897 MockRead(ASYNC, OK)};
898
899 MockRead http_reads_2[] = {
900 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
901 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
902 MockRead(ASYNC, OK)};
903
Ryan Sleevib8d7ea02018-05-07 20:01:01904 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
905 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04906 socket_factory_.AddSocketDataProvider(&http_data_1);
907 socket_factory_.AddSocketDataProvider(&http_data_2);
908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
909 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
910
911 TestProxyDelegate test_proxy_delegate;
912 // Proxy URL is different from the request URL.
913 test_proxy_delegate.set_alternative_proxy_server(
914 ProxyServer::FromPacString("QUIC myproxy.org:443"));
915
Lily Houghton8c2f97d2018-01-22 05:06:59916 proxy_resolution_service_ =
917 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49918 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52919 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04920
921 CreateSession();
922 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
923
924 // The first request should be fetched via the HTTPS proxy.
925 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
926
Reilly Grant89a7e512018-01-20 01:57:16927 // Since the main job succeeded only the alternative proxy server should be
928 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59929 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16930 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04931
932 // Verify that the second request completes successfully, and the
933 // alternative proxy server job is not started.
934 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
935 }
936
Fan Yang32c5a112018-12-10 20:06:33937 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
938 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36939 }
940
Fan Yang32c5a112018-12-10 20:06:33941 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
942 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36943 }
944
Bence Béky230ac612017-08-30 19:17:08945 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49946 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08947 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49948 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08949 }
950
Ryan Hamilton8d9ee76e2018-05-29 23:52:52951 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05952 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52953 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01954 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52955 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17956 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58957 QuicTestPacketMaker client_maker_;
958 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42959 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00960 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56961 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05962 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43963 MockHostResolver host_resolver_;
964 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11965 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42966 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23967 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38968 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07969 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59970 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42971 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07972 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41973 HttpNetworkSession::Params session_params_;
974 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19975 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51976 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42977 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56978 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03979 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12980
981 private:
982 void SendRequestAndExpectQuicResponseMaybeFromProxy(
983 const std::string& expected,
bnc62a44f022015-04-02 15:59:41984 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46985 uint16_t port) {
bnc691fda62016-08-12 00:43:16986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09987 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16988 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09989 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
990 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16991 RunTransaction(&trans);
992 CheckWasQuicResponse(&trans);
993 CheckResponsePort(&trans, port);
994 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09995 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47996 if (used_proxy) {
997 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
998 } else {
999 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1000 }
tbansal7cec3812015-02-05 21:25:121001 }
[email protected]61a527782013-02-21 03:58:001002};
1003
Victor Costane635086f2019-01-27 05:20:301004INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231005 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051006 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521007 ::testing::Combine(
1008 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1009 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201010
Ryan Hamiltona64a5bcf2017-11-30 07:35:281011TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481012 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281013 base::HistogramTester histograms;
1014 session_params_.origins_to_force_quic_on.insert(
1015 HostPortPair::FromString("mail.example.org:443"));
1016 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271017 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281018
1019 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521020 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281021 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431022 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281023 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1024 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1025 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1026
1027 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1028
1029 CreateSession();
1030
1031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1032 TestCompletionCallback callback;
1033 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1034 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1035 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1036
1037 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1038 -ERR_INTERNET_DISCONNECTED, 1);
1039 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1040 -ERR_INTERNET_DISCONNECTED, 1);
1041}
1042
1043TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481044 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281045 base::HistogramTester histograms;
1046 session_params_.origins_to_force_quic_on.insert(
1047 HostPortPair::FromString("mail.example.org:443"));
1048 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271049 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281050
1051 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521052 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281053 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431054 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281055 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1056 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1057 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1058
1059 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1060
1061 CreateSession();
1062
1063 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1064 TestCompletionCallback callback;
1065 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1066 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1067 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1068
1069 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1070 -ERR_INTERNET_DISCONNECTED, 1);
1071 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1072 -ERR_INTERNET_DISCONNECTED, 1);
1073}
1074
tbansal180587c2017-02-16 15:13:231075TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411076 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231077 HostPortPair::FromString("mail.example.org:443"));
1078
1079 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521080 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361081 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431082 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1083 mock_quic_data.AddWrite(
1084 SYNCHRONOUS,
1085 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331086 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431087 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431088 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331089 ASYNC, ConstructServerResponseHeadersPacket(
1090 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1091 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431092 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331093 mock_quic_data.AddRead(
1094 ASYNC, ConstructServerDataPacket(
1095 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411096 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431097 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231098 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1099
1100 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1101
1102 CreateSession();
1103 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1104
1105 EXPECT_FALSE(
1106 test_socket_performance_watcher_factory_.rtt_notification_received());
1107 SendRequestAndExpectQuicResponse("hello!");
1108 EXPECT_TRUE(
1109 test_socket_performance_watcher_factory_.rtt_notification_received());
1110}
1111
1112TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411113 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231114 HostPortPair::FromString("mail.example.org:443"));
1115
1116 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521117 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361118 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431119 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1120 mock_quic_data.AddWrite(
1121 SYNCHRONOUS,
1122 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331123 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431124 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431125 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331126 ASYNC, ConstructServerResponseHeadersPacket(
1127 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1128 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431129 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331130 mock_quic_data.AddRead(
1131 ASYNC, ConstructServerDataPacket(
1132 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411133 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431134 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231135 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1136
1137 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1138
1139 CreateSession();
1140 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1141
1142 EXPECT_FALSE(
1143 test_socket_performance_watcher_factory_.rtt_notification_received());
1144 SendRequestAndExpectQuicResponse("hello!");
1145 EXPECT_FALSE(
1146 test_socket_performance_watcher_factory_.rtt_notification_received());
1147}
1148
[email protected]1e960032013-12-20 19:00:201149TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411150 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571151 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471152
[email protected]1e960032013-12-20 19:00:201153 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521154 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361155 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431156 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1157 mock_quic_data.AddWrite(
1158 SYNCHRONOUS,
1159 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331160 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431161 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431162 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331163 ASYNC, ConstructServerResponseHeadersPacket(
1164 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1165 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431166 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331167 mock_quic_data.AddRead(
1168 ASYNC, ConstructServerDataPacket(
1169 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411170 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431171 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591172 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471173
rcha5399e02015-04-21 19:32:041174 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471175
[email protected]4dca587c2013-03-07 16:54:471176 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471177
[email protected]aa9b14d2013-05-10 23:45:191178 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471179
[email protected]98b20ce2013-05-10 05:55:261180 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461181 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191182 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261183 EXPECT_LT(0u, entries.size());
1184
1185 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291186 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001187 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1188 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261189 EXPECT_LT(0, pos);
1190
rchfd527212015-08-25 00:41:261191 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291192 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261193 entries, 0,
mikecirone8b85c432016-09-08 19:11:001194 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1195 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261196 EXPECT_LT(0, pos);
1197
Eric Romanaefc98c2018-12-18 21:38:011198 int packet_number;
1199 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1200 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261201
rchfd527212015-08-25 00:41:261202 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1203 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001204 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1205 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261206 EXPECT_LT(0, pos);
1207
[email protected]98b20ce2013-05-10 05:55:261208 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291209 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001210 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1211 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261212 EXPECT_LT(0, pos);
1213
1214 int log_stream_id;
1215 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381216 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1217 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471218}
1219
rchbd089ab2017-05-26 23:05:041220TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411221 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041222 HostPortPair::FromString("mail.example.org:443"));
1223
1224 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521225 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041226 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431227 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1228 mock_quic_data.AddWrite(
1229 SYNCHRONOUS,
1230 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331231 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431232 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131233 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041234 response_headers["key1"] = std::string(30000, 'A');
1235 response_headers["key2"] = std::string(30000, 'A');
1236 response_headers["key3"] = std::string(30000, 'A');
1237 response_headers["key4"] = std::string(30000, 'A');
1238 response_headers["key5"] = std::string(30000, 'A');
1239 response_headers["key6"] = std::string(30000, 'A');
1240 response_headers["key7"] = std::string(30000, 'A');
1241 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331242 spdy::SpdyHeadersIR headers_frame(
1243 GetNthClientInitiatedBidirectionalStreamId(0),
1244 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131245 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1246 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041247 response_framer.SerializeFrame(headers_frame);
1248
Fan Yangac867502019-01-28 21:10:231249 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041250 size_t chunk_size = 1200;
1251 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1252 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431253 mock_quic_data.AddRead(
1254 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091255 packet_number++,
1256 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521257 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041258 }
1259
Victor Vasiliev076657c2019-03-12 02:46:431260 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041261 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331262 ASYNC, ConstructServerDataPacket(
1263 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411264 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041265 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431266 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1267 mock_quic_data.AddWrite(ASYNC,
1268 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041269
1270 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1271
1272 CreateSession();
1273
1274 SendRequestAndExpectQuicResponse("hello!");
1275}
1276
1277TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481278 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411279 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041280 HostPortPair::FromString("mail.example.org:443"));
1281
1282 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521283 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041284 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431285 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1286 mock_quic_data.AddWrite(
1287 SYNCHRONOUS,
1288 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331289 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431290 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131291 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041292 response_headers["key1"] = std::string(30000, 'A');
1293 response_headers["key2"] = std::string(30000, 'A');
1294 response_headers["key3"] = std::string(30000, 'A');
1295 response_headers["key4"] = std::string(30000, 'A');
1296 response_headers["key5"] = std::string(30000, 'A');
1297 response_headers["key6"] = std::string(30000, 'A');
1298 response_headers["key7"] = std::string(30000, 'A');
1299 response_headers["key8"] = std::string(30000, 'A');
1300 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331301 spdy::SpdyHeadersIR headers_frame(
1302 GetNthClientInitiatedBidirectionalStreamId(0),
1303 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131304 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1305 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041306 response_framer.SerializeFrame(headers_frame);
1307
Fan Yangac867502019-01-28 21:10:231308 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041309 size_t chunk_size = 1200;
1310 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1311 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431312 mock_quic_data.AddRead(
1313 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091314 packet_number++,
1315 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521316 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041317 }
1318
Victor Vasiliev076657c2019-03-12 02:46:431319 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411320
rchbd089ab2017-05-26 23:05:041321 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331322 ASYNC, ConstructServerDataPacket(
1323 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411324 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041325 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431326 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1327 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331328 ASYNC, ConstructClientAckAndRstPacket(
1329 4, GetNthClientInitiatedBidirectionalStreamId(0),
1330 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041331
1332 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1333
1334 CreateSession();
1335
1336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1337 TestCompletionCallback callback;
1338 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1339 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1340 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1341}
1342
rcha2bd44b2016-07-02 00:42:551343TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411344 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551345
Ryan Hamilton9835e662018-08-02 05:36:271346 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551347
1348 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521349 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361350 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431351 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1352 mock_quic_data.AddWrite(
1353 SYNCHRONOUS,
1354 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331355 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431356 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431357 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331358 ASYNC, ConstructServerResponseHeadersPacket(
1359 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1360 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431361 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331362 mock_quic_data.AddRead(
1363 ASYNC, ConstructServerDataPacket(
1364 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411365 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431366 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551367 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1368
1369 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1370
1371 CreateSession();
1372
1373 SendRequestAndExpectQuicResponse("hello!");
1374 EXPECT_TRUE(
1375 test_socket_performance_watcher_factory_.rtt_notification_received());
1376}
1377
[email protected]cf3e3cd62014-02-05 16:16:161378TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411379 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591380 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491381 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161382
[email protected]cf3e3cd62014-02-05 16:16:161383 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521384 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361385 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431386 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1387 mock_quic_data.AddWrite(
1388 SYNCHRONOUS,
1389 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331390 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431391 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431392 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331393 ASYNC, ConstructServerResponseHeadersPacket(
1394 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1395 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431396 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331397 mock_quic_data.AddRead(
1398 ASYNC, ConstructServerDataPacket(
1399 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411400 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431401 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501402 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591403 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161404
rcha5399e02015-04-21 19:32:041405 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161406
tbansal0f56a39a2016-04-07 22:03:381407 EXPECT_FALSE(
1408 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161409 // There is no need to set up an alternate protocol job, because
1410 // no attempt will be made to speak to the proxy over TCP.
1411
rch9ae5b3b2016-02-11 00:36:291412 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161413 CreateSession();
1414
bnc62a44f022015-04-02 15:59:411415 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381416 EXPECT_TRUE(
1417 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161418}
1419
bnc313ba9c2015-06-11 15:42:311420// Regression test for https://crbug.com/492458. Test that for an HTTP
1421// connection through a QUIC proxy, the certificate exhibited by the proxy is
1422// checked against the proxy hostname, not the origin hostname.
1423TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291424 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311425 const std::string proxy_host = "www.example.org";
1426
mmenke6ddfbea2017-05-31 21:48:411427 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591428 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491429 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311430
alyssar2adf3ac2016-05-03 17:12:581431 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311432 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521433 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361434 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431435 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1436 mock_quic_data.AddWrite(
1437 SYNCHRONOUS,
1438 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331439 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431440 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431441 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331442 ASYNC, ConstructServerResponseHeadersPacket(
1443 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1444 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431445 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331446 mock_quic_data.AddRead(
1447 ASYNC, ConstructServerDataPacket(
1448 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411449 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431450 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501451 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591452 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311453 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1454
1455 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291456 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311457 ASSERT_TRUE(cert.get());
1458 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241459 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1460 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311461 ProofVerifyDetailsChromium verify_details;
1462 verify_details.cert_verify_result.verified_cert = cert;
1463 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561464 ProofVerifyDetailsChromium verify_details2;
1465 verify_details2.cert_verify_result.verified_cert = cert;
1466 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311467
1468 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091469 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321470 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271471 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311472 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1473}
1474
rchbe69cb902016-02-11 01:10:481475TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341476 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481477 HostPortPair origin("www.example.org", 443);
1478 HostPortPair alternative("mail.example.org", 443);
1479
1480 base::FilePath certs_dir = GetTestCertsDirectory();
1481 scoped_refptr<X509Certificate> cert(
1482 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1483 ASSERT_TRUE(cert.get());
1484 // TODO(rch): the connection should be "to" the origin, so if the cert is
1485 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241486 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1487 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481488 ProofVerifyDetailsChromium verify_details;
1489 verify_details.cert_verify_result.verified_cert = cert;
1490 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1491
alyssar2adf3ac2016-05-03 17:12:581492 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481493 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521494 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361495 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431496 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1497 mock_quic_data.AddWrite(
1498 SYNCHRONOUS,
1499 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331500 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431501 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431502 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331503 ASYNC, ConstructServerResponseHeadersPacket(
1504 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1505 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431506 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331507 mock_quic_data.AddRead(
1508 ASYNC, ConstructServerDataPacket(
1509 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411510 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431511 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481512 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1513 mock_quic_data.AddRead(ASYNC, 0);
1514 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1515
1516 request_.url = GURL("https://" + origin.host());
1517 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271518 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091519 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321520 CreateSession();
rchbe69cb902016-02-11 01:10:481521
1522 SendRequestAndExpectQuicResponse("hello!");
1523}
1524
zhongyief3f4ce52017-07-05 23:53:281525TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521526 quic::QuicTransportVersion unsupported_version =
1527 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281528 // Add support for another QUIC version besides |version_|. Also find a
1529 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521530 for (const quic::QuicTransportVersion& version :
1531 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281532 if (version == version_)
1533 continue;
1534 if (supported_versions_.size() != 2) {
1535 supported_versions_.push_back(version);
1536 continue;
1537 }
1538 unsupported_version = version;
1539 break;
1540 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521541 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281542
1543 // Set up alternative service to use QUIC with a version that is not
1544 // supported.
1545 url::SchemeHostPort server(request_.url);
1546 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1547 443);
1548 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1549 http_server_properties_.SetQuicAlternativeService(
1550 server, alternative_service, expiration, {unsupported_version});
1551
1552 AlternativeServiceInfoVector alt_svc_info_vector =
1553 http_server_properties_.GetAlternativeServiceInfos(server);
1554 EXPECT_EQ(1u, alt_svc_info_vector.size());
1555 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1556 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1557 EXPECT_EQ(unsupported_version,
1558 alt_svc_info_vector[0].advertised_versions()[0]);
1559
1560 // First request should still be sent via TCP as the QUIC version advertised
1561 // in the stored AlternativeService is not supported by the client. However,
1562 // the response from the server will advertise new Alt-Svc with supported
1563 // versions.
1564 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521565 GenerateQuicVersionsListForAltSvcHeader(
1566 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281567 std::string altsvc_header =
1568 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1569 advertised_versions_list_str.c_str());
1570 MockRead http_reads[] = {
1571 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1572 MockRead("hello world"),
1573 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1574 MockRead(ASYNC, OK)};
1575
Ryan Sleevib8d7ea02018-05-07 20:01:011576 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281577 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081578 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281579 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1580
1581 // Second request should be sent via QUIC as a new list of verions supported
1582 // by the client has been advertised by the server.
1583 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521584 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281585 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431586 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1587 mock_quic_data.AddWrite(
1588 SYNCHRONOUS,
1589 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331590 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431591 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431592 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331593 ASYNC, ConstructServerResponseHeadersPacket(
1594 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1595 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431596 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331597 mock_quic_data.AddRead(
1598 ASYNC, ConstructServerDataPacket(
1599 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411600 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431601 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281602 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1603 mock_quic_data.AddRead(ASYNC, 0); // EOF
1604
1605 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1606
1607 AddHangingNonAlternateProtocolSocketData();
1608
1609 CreateSession(supported_versions_);
1610
1611 SendRequestAndExpectHttpResponse("hello world");
1612 SendRequestAndExpectQuicResponse("hello!");
1613
1614 // Check alternative service list is updated with new versions.
1615 alt_svc_info_vector =
1616 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1617 EXPECT_EQ(1u, alt_svc_info_vector.size());
1618 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1619 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1620 // Advertised versions will be lised in a sorted order.
1621 std::sort(supported_versions_.begin(), supported_versions_.end());
1622 EXPECT_EQ(supported_versions_[0],
1623 alt_svc_info_vector[0].advertised_versions()[0]);
1624 EXPECT_EQ(supported_versions_[1],
1625 alt_svc_info_vector[0].advertised_versions()[1]);
1626}
1627
bncaccd4962017-04-06 21:00:261628// Regression test for https://crbug.com/546991.
1629// The server might not be able to serve a request on an alternative connection,
1630// and might send a 421 Misdirected Request response status to indicate this.
1631// HttpNetworkTransaction should reset the request and retry without using
1632// alternative services.
1633TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1634 // Set up alternative service to use QUIC.
1635 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1636 // that overrides |enable_alternative_services|.
1637 url::SchemeHostPort server(request_.url);
1638 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1639 443);
1640 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211641 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441642 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261643
davidbena4449722017-05-05 23:30:531644 // First try: The alternative job uses QUIC and reports an HTTP 421
1645 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1646 // paused at Connect(), so it will never exit the socket pool. This ensures
1647 // that the alternate job always wins the race and keeps whether the
1648 // |http_data| exits the socket pool before the main job is aborted
1649 // deterministic. The first main job gets aborted without the socket pool ever
1650 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261651 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521652 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361653 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431654 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1655 mock_quic_data.AddWrite(
1656 SYNCHRONOUS,
1657 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331658 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431659 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331660 mock_quic_data.AddRead(
1661 ASYNC, ConstructServerResponseHeadersPacket(
1662 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1663 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261664 mock_quic_data.AddRead(ASYNC, OK);
1665 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1666
davidbena4449722017-05-05 23:30:531667 // Second try: The main job uses TCP, and there is no alternate job. Once the
1668 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1669 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261670 // Note that if there was an alternative QUIC Job created for the second try,
1671 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1672 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531673 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1674 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1675 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1676 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1677 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1678 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011679 reads, writes);
bncaccd4962017-04-06 21:00:261680 socket_factory_.AddSocketDataProvider(&http_data);
1681 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1682
bncaccd4962017-04-06 21:00:261683 CreateSession();
1684 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531685
1686 // Run until |mock_quic_data| has failed and |http_data| has paused.
1687 TestCompletionCallback callback;
1688 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1689 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1690 base::RunLoop().RunUntilIdle();
1691
1692 // |mock_quic_data| must have run to completion.
1693 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1694 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1695
1696 // Now that the QUIC data has been consumed, unblock |http_data|.
1697 http_data.socket()->OnConnectComplete(MockConnect());
1698
1699 // The retry logic must hide the 421 status. The transaction succeeds on
1700 // |http_data|.
1701 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261702 CheckWasHttpResponse(&trans);
1703 CheckResponsePort(&trans, 443);
1704 CheckResponseData(&trans, "hello!");
1705}
1706
[email protected]1e960032013-12-20 19:00:201707TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411708 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571709 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301710
tbansalfdf5665b2015-09-21 22:46:401711 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521712 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361713 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431714 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401715 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401716 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371717 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361718 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431719 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301720 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401721 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431722 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401723
1724 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1725 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301726
1727 CreateSession();
1728
tbansal0f56a39a2016-04-07 22:03:381729 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401730 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161731 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401732 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161733 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1735 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381736 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531737
1738 NetErrorDetails details;
1739 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521740 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401741 }
[email protected]cebe3282013-05-22 23:49:301742}
1743
tbansalc8a94ea2015-11-02 23:58:511744TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1745 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411746 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571747 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511748
1749 MockRead http_reads[] = {
1750 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1751 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1752 MockRead(ASYNC, OK)};
1753
Ryan Sleevib8d7ea02018-05-07 20:01:011754 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511755 socket_factory_.AddSocketDataProvider(&data);
1756 SSLSocketDataProvider ssl(ASYNC, OK);
1757 socket_factory_.AddSSLSocketDataProvider(&ssl);
1758
1759 CreateSession();
1760
1761 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381762 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511763}
1764
bncc958faa2015-07-31 18:14:521765TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521766 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561767 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1768 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521769 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1770 MockRead(ASYNC, OK)};
1771
Ryan Sleevib8d7ea02018-05-07 20:01:011772 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521773 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081774 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561775 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521776
1777 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521778 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361779 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431780 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1781 mock_quic_data.AddWrite(
1782 SYNCHRONOUS,
1783 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331784 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431785 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431786 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331787 ASYNC, ConstructServerResponseHeadersPacket(
1788 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1789 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431790 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331791 mock_quic_data.AddRead(
1792 ASYNC, ConstructServerDataPacket(
1793 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411794 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431795 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521796 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591797 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521798
1799 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1800
rtennetib8e80fb2016-05-16 00:12:091801 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321802 CreateSession();
bncc958faa2015-07-31 18:14:521803
1804 SendRequestAndExpectHttpResponse("hello world");
1805 SendRequestAndExpectQuicResponse("hello!");
1806}
1807
zhongyia00ca012017-07-06 23:36:391808TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1809 // Both server advertises and client supports two QUIC versions.
1810 // Only |version_| is advertised and supported.
1811 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1812 // PacketMakers are using |version_|.
1813
1814 // Add support for another QUIC version besides |version_| on the client side.
1815 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521816 quic::QuicTransportVersion advertised_version_2 =
1817 quic::QUIC_VERSION_UNSUPPORTED;
1818 for (const quic::QuicTransportVersion& version :
1819 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391820 if (version == version_)
1821 continue;
1822 if (supported_versions_.size() != 2) {
1823 supported_versions_.push_back(version);
1824 continue;
1825 }
1826 advertised_version_2 = version;
1827 break;
1828 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521829 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391830
1831 std::string QuicAltSvcWithVersionHeader =
1832 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1833 advertised_version_2, version_);
1834
1835 MockRead http_reads[] = {
1836 MockRead("HTTP/1.1 200 OK\r\n"),
1837 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1838 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1839 MockRead(ASYNC, OK)};
1840
Ryan Sleevib8d7ea02018-05-07 20:01:011841 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391842 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081843 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391844 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1845
1846 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521847 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391848 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431849 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1850 mock_quic_data.AddWrite(
1851 SYNCHRONOUS,
1852 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331853 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431854 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431855 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331856 ASYNC, ConstructServerResponseHeadersPacket(
1857 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1858 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431859 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331860 mock_quic_data.AddRead(
1861 ASYNC, ConstructServerDataPacket(
1862 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411863 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431864 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391865 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1866 mock_quic_data.AddRead(ASYNC, 0); // EOF
1867
1868 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1869
1870 AddHangingNonAlternateProtocolSocketData();
1871 CreateSession(supported_versions_);
1872
1873 SendRequestAndExpectHttpResponse("hello world");
1874 SendRequestAndExpectQuicResponse("hello!");
1875}
1876
1877TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1878 // Client and server mutually support more than one QUIC_VERSION.
1879 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1880 // which is verified as the PacketMakers are using |version_|.
1881
Ryan Hamilton8d9ee76e2018-05-29 23:52:521882 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1883 for (const quic::QuicTransportVersion& version :
1884 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391885 if (version == version_)
1886 continue;
1887 common_version_2 = version;
1888 break;
1889 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521890 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391891
1892 supported_versions_.push_back(
1893 common_version_2); // Supported but unpreferred.
1894
1895 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1896 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1897
1898 MockRead http_reads[] = {
1899 MockRead("HTTP/1.1 200 OK\r\n"),
1900 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1901 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1902 MockRead(ASYNC, OK)};
1903
Ryan Sleevib8d7ea02018-05-07 20:01:011904 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391905 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081906 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391907 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1908
1909 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521910 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391911 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431912 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1913 mock_quic_data.AddWrite(
1914 SYNCHRONOUS,
1915 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331916 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431917 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431918 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331919 ASYNC, ConstructServerResponseHeadersPacket(
1920 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1921 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431922 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331923 mock_quic_data.AddRead(
1924 ASYNC, ConstructServerDataPacket(
1925 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411926 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431927 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391928 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1929 mock_quic_data.AddRead(ASYNC, 0); // EOF
1930
1931 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1932
1933 AddHangingNonAlternateProtocolSocketData();
1934 CreateSession(supported_versions_);
1935
1936 SendRequestAndExpectHttpResponse("hello world");
1937 SendRequestAndExpectQuicResponse("hello!");
1938}
1939
rchf47265dc2016-03-21 21:33:121940TEST_P(QuicNetworkTransactionTest,
1941 UseAlternativeServiceWithProbabilityForQuic) {
1942 MockRead http_reads[] = {
1943 MockRead("HTTP/1.1 200 OK\r\n"),
1944 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1945 MockRead("hello world"),
1946 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1947 MockRead(ASYNC, OK)};
1948
Ryan Sleevib8d7ea02018-05-07 20:01:011949 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121950 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081951 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121952 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1953
1954 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521955 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361956 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431957 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1958 mock_quic_data.AddWrite(
1959 SYNCHRONOUS,
1960 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331961 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431962 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431963 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331964 ASYNC, ConstructServerResponseHeadersPacket(
1965 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1966 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431967 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331968 mock_quic_data.AddRead(
1969 ASYNC, ConstructServerDataPacket(
1970 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411971 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431972 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121973 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1974 mock_quic_data.AddRead(ASYNC, 0); // EOF
1975
1976 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1977
rtennetib8e80fb2016-05-16 00:12:091978 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121979 CreateSession();
1980
1981 SendRequestAndExpectHttpResponse("hello world");
1982 SendRequestAndExpectQuicResponse("hello!");
1983}
1984
zhongyi3d4a55e72016-04-22 20:36:461985TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1986 MockRead http_reads[] = {
1987 MockRead("HTTP/1.1 200 OK\r\n"),
1988 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1989 MockRead("hello world"),
1990 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1991 MockRead(ASYNC, OK)};
1992
Ryan Sleevib8d7ea02018-05-07 20:01:011993 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461994 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081995 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461996 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1997
1998 CreateSession();
bncb26024382016-06-29 02:39:451999 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462000 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452001 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462002 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402003 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462004 session_->http_server_properties();
2005 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2006 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2007 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462008 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342009 2u,
2010 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452011 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342012 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462013}
2014
2015TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2016 MockRead http_reads[] = {
2017 MockRead("HTTP/1.1 200 OK\r\n"),
2018 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2019 MockRead("hello world"),
2020 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2021 MockRead(ASYNC, OK)};
2022
Ryan Sleevib8d7ea02018-05-07 20:01:012023 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082024 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462025
2026 socket_factory_.AddSocketDataProvider(&http_data);
2027 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2028 socket_factory_.AddSocketDataProvider(&http_data);
2029 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2030
2031 CreateSession();
2032
2033 // Send https request and set alternative services if response header
2034 // advertises alternative service for mail.example.org.
2035 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402036 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462037 session_->http_server_properties();
2038
2039 const url::SchemeHostPort https_server(request_.url);
2040 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342041 EXPECT_EQ(
2042 2u,
2043 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462044
2045 // Send http request to the same origin but with diffrent scheme, should not
2046 // use QUIC.
2047 request_.url = GURL("http://mail.example.org:443");
2048 SendRequestAndExpectHttpResponse("hello world");
2049}
2050
zhongyie537a002017-06-27 16:48:212051TEST_P(QuicNetworkTransactionTest,
2052 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442053 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522054 for (const quic::QuicTransportVersion& version :
2055 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442056 if (version == version_)
2057 continue;
2058 supported_versions_.push_back(version);
2059 break;
2060 }
2061
zhongyie537a002017-06-27 16:48:212062 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522063 GenerateQuicVersionsListForAltSvcHeader(
2064 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212065 std::string altsvc_header =
2066 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2067 advertised_versions_list_str.c_str());
2068 MockRead http_reads[] = {
2069 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2070 MockRead("hello world"),
2071 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2072 MockRead(ASYNC, OK)};
2073
Ryan Sleevib8d7ea02018-05-07 20:01:012074 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212075 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082076 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212077 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2078
2079 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522080 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212081 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432082 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2083 mock_quic_data.AddWrite(
2084 SYNCHRONOUS,
2085 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332086 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432087 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432088 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332089 ASYNC, ConstructServerResponseHeadersPacket(
2090 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2091 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432092 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332093 mock_quic_data.AddRead(
2094 ASYNC, ConstructServerDataPacket(
2095 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412096 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432097 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212098 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2099 mock_quic_data.AddRead(ASYNC, 0); // EOF
2100
2101 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2102
2103 AddHangingNonAlternateProtocolSocketData();
2104
zhongyi86838d52017-06-30 01:19:442105 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212106
2107 SendRequestAndExpectHttpResponse("hello world");
2108 SendRequestAndExpectQuicResponse("hello!");
2109
2110 // Check alternative service is set with only mutually supported versions.
2111 const url::SchemeHostPort https_server(request_.url);
2112 const AlternativeServiceInfoVector alt_svc_info_vector =
2113 session_->http_server_properties()->GetAlternativeServiceInfos(
2114 https_server);
2115 EXPECT_EQ(1u, alt_svc_info_vector.size());
2116 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2117 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2118 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442119 std::sort(supported_versions_.begin(), supported_versions_.end());
2120 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212121 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442122 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212123 alt_svc_info_vector[0].advertised_versions()[1]);
2124}
2125
danzh3134c2562016-08-12 14:07:522126TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442127 std::string altsvc_header =
2128 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072129 MockRead http_reads[] = {
2130 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2131 MockRead("hello world"),
2132 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2133 MockRead(ASYNC, OK)};
2134
Ryan Sleevib8d7ea02018-05-07 20:01:012135 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072136 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082137 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072138 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2139
2140 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522141 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362142 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432143 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2144 mock_quic_data.AddWrite(
2145 SYNCHRONOUS,
2146 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332147 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432148 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432149 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332150 ASYNC, ConstructServerResponseHeadersPacket(
2151 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2152 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432153 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332154 mock_quic_data.AddRead(
2155 ASYNC, ConstructServerDataPacket(
2156 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412157 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432158 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072159 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592160 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072161
2162 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2163
rtennetib8e80fb2016-05-16 00:12:092164 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322165 CreateSession();
bnc8be55ebb2015-10-30 14:12:072166
2167 SendRequestAndExpectHttpResponse("hello world");
2168 SendRequestAndExpectQuicResponse("hello!");
2169}
2170
zhongyi6b5a3892016-03-12 04:46:202171TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092172 if (version_ == quic::QUIC_VERSION_99) {
2173 // Not available under version 99
2174 return;
2175 }
zhongyi6b5a3892016-03-12 04:46:202176 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522177 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362178 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432179 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2180 mock_quic_data.AddWrite(
2181 SYNCHRONOUS,
2182 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332183 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432184 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332185 mock_quic_data.AddRead(
2186 ASYNC, ConstructServerResponseHeadersPacket(
2187 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2188 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202189 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522190 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432191 mock_quic_data.AddRead(SYNCHRONOUS,
2192 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522193 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432194 "connection migration with port change only"));
2195 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432196 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332197 mock_quic_data.AddRead(
2198 SYNCHRONOUS, ConstructServerDataPacket(
2199 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412200 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332201 mock_quic_data.AddWrite(SYNCHRONOUS,
2202 ConstructClientAckAndRstPacket(
2203 4, GetNthClientInitiatedBidirectionalStreamId(0),
2204 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202205 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2206 mock_quic_data.AddRead(ASYNC, 0); // EOF
2207
2208 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2209
2210 // The non-alternate protocol job needs to hang in order to guarantee that
2211 // the alternate-protocol job will "win".
2212 AddHangingNonAlternateProtocolSocketData();
2213
2214 // In order for a new QUIC session to be established via alternate-protocol
2215 // without racing an HTTP connection, we need the host resolution to happen
2216 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2217 // connection to the the server, in this test we require confirmation
2218 // before encrypting so the HTTP job will still start.
2219 host_resolver_.set_synchronous_mode(true);
2220 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2221 "");
zhongyi6b5a3892016-03-12 04:46:202222
2223 CreateSession();
2224 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272225 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202226
bnc691fda62016-08-12 00:43:162227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202228 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362229 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202231
2232 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522233 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012234 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202235
2236 // Check whether this transaction is correctly marked as received a go-away
2237 // because of migrating port.
2238 NetErrorDetails details;
2239 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162240 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202241 EXPECT_TRUE(details.quic_port_migration_detected);
2242}
2243
Zhongyi Shia6b68d112018-09-24 07:49:032244// This test verifies that a new QUIC connection will be attempted on the
2245// alternate network if the original QUIC connection fails with idle timeout
2246// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2247// alternate network as well, QUIC is marked as broken and the brokenness will
2248// not expire when default network changes.
2249TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Michael Warres167db3e2019-03-01 21:38:032250 if (version_ >= quic::QUIC_VERSION_47) {
2251 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2252 return;
2253 }
Zhongyi Shia6b68d112018-09-24 07:49:032254 SetUpTestForRetryConnectionOnAlternateNetwork();
2255
2256 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032257 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032258
2259 // The request will initially go out over QUIC.
2260 MockQuicData quic_data;
2261 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2262 int packet_num = 1;
2263 quic_data.AddWrite(SYNCHRONOUS,
2264 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2265 // Retranmit the handshake messages.
2266 quic_data.AddWrite(SYNCHRONOUS,
2267 client_maker_.MakeDummyCHLOPacket(packet_num++));
2268 quic_data.AddWrite(SYNCHRONOUS,
2269 client_maker_.MakeDummyCHLOPacket(packet_num++));
2270 quic_data.AddWrite(SYNCHRONOUS,
2271 client_maker_.MakeDummyCHLOPacket(packet_num++));
2272 quic_data.AddWrite(SYNCHRONOUS,
2273 client_maker_.MakeDummyCHLOPacket(packet_num++));
2274 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2275 if (version_ <= quic::QUIC_VERSION_39) {
2276 quic_data.AddWrite(SYNCHRONOUS,
2277 client_maker_.MakeDummyCHLOPacket(packet_num++));
2278 }
2279 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2280 quic_data.AddWrite(SYNCHRONOUS,
2281 client_maker_.MakeConnectionClosePacket(
2282 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2283 "No recent network activity."));
2284 quic_data.AddSocketDataToFactory(&socket_factory_);
2285
2286 // Add successful TCP data so that TCP job will succeed.
2287 MockWrite http_writes[] = {
2288 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2289 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2290 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2291
2292 MockRead http_reads[] = {
2293 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2294 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2295 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2296 SequencedSocketData http_data(http_reads, http_writes);
2297 socket_factory_.AddSocketDataProvider(&http_data);
2298 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2299
2300 // Add data for the second QUIC connection to fail.
2301 MockQuicData quic_data2;
2302 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2303 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2304 quic_data2.AddSocketDataToFactory(&socket_factory_);
2305
2306 // Resolve the host resolution synchronously.
2307 host_resolver_.set_synchronous_mode(true);
2308 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2309 "");
Zhongyi Shia6b68d112018-09-24 07:49:032310
2311 CreateSession();
2312 session_->quic_stream_factory()->set_require_confirmation(true);
2313 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2314 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2315 QuicStreamFactoryPeer::SetAlarmFactory(
2316 session_->quic_stream_factory(),
2317 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2318 &clock_));
2319 // Add alternate protocol mapping to race QUIC and TCP.
2320 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2321 // peer.
2322 AddQuicAlternateProtocolMapping(
2323 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2324
2325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2326 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362327 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2329
2330 // Pump the message loop to get the request started.
2331 // Request will be served with TCP job.
2332 base::RunLoop().RunUntilIdle();
2333 EXPECT_THAT(callback.WaitForResult(), IsOk());
2334 CheckResponseData(&trans, "TCP succeeds");
2335
2336 // Fire the retransmission alarm, from this point, connection will idle
2337 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062338 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182339 quic_fix_time_of_first_packet_sent_after_receiving)) {
2340 quic_task_runner_->RunNextTask();
2341 }
Zhongyi Shia6b68d112018-09-24 07:49:032342 // Fast forward to idle timeout the original connection. A new connection will
2343 // be kicked off on the alternate network.
2344 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2345 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2346 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2347
2348 // Run the message loop to execute posted tasks, which will report job status.
2349 base::RunLoop().RunUntilIdle();
2350
2351 // Verify that QUIC is marked as broken.
2352 ExpectBrokenAlternateProtocolMapping();
2353
2354 // Deliver a message to notify the new network becomes default, the brokenness
2355 // will not expire as QUIC is broken on both networks.
2356 scoped_mock_change_notifier_->mock_network_change_notifier()
2357 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2358 ExpectBrokenAlternateProtocolMapping();
2359
2360 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2361 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2362}
2363
2364// This test verifies that a new QUIC connection will be attempted on the
2365// alternate network if the original QUIC connection fails with idle timeout
2366// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2367// alternate network, QUIC is marked as broken. The brokenness will expire when
2368// the default network changes.
2369TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Michael Warres167db3e2019-03-01 21:38:032370 if (version_ >= quic::QUIC_VERSION_47) {
2371 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2372 return;
2373 }
Zhongyi Shia6b68d112018-09-24 07:49:032374 SetUpTestForRetryConnectionOnAlternateNetwork();
2375
2376 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032377 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032378
2379 // The request will initially go out over QUIC.
2380 MockQuicData quic_data;
2381 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2382 int packet_num = 1;
2383 quic_data.AddWrite(SYNCHRONOUS,
2384 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2385 // Retranmit the handshake messages.
2386 quic_data.AddWrite(SYNCHRONOUS,
2387 client_maker_.MakeDummyCHLOPacket(packet_num++));
2388 quic_data.AddWrite(SYNCHRONOUS,
2389 client_maker_.MakeDummyCHLOPacket(packet_num++));
2390 quic_data.AddWrite(SYNCHRONOUS,
2391 client_maker_.MakeDummyCHLOPacket(packet_num++));
2392 quic_data.AddWrite(SYNCHRONOUS,
2393 client_maker_.MakeDummyCHLOPacket(packet_num++));
2394 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2395 if (version_ <= quic::QUIC_VERSION_39) {
2396 quic_data.AddWrite(SYNCHRONOUS,
2397 client_maker_.MakeDummyCHLOPacket(packet_num++));
2398 }
2399 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2400 quic_data.AddWrite(SYNCHRONOUS,
2401 client_maker_.MakeConnectionClosePacket(
2402 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2403 "No recent network activity."));
2404 quic_data.AddSocketDataToFactory(&socket_factory_);
2405
2406 // Add successful TCP data so that TCP job will succeed.
2407 MockWrite http_writes[] = {
2408 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2409 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2410 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2411
2412 MockRead http_reads[] = {
2413 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2414 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2415 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2416 SequencedSocketData http_data(http_reads, http_writes);
2417 socket_factory_.AddSocketDataProvider(&http_data);
2418 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2419
2420 // Quic connection will be retried on the alternate network after the initial
2421 // one fails on the default network.
2422 MockQuicData quic_data2;
2423 quic::QuicStreamOffset header_stream_offset = 0;
2424 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2425 quic_data2.AddWrite(SYNCHRONOUS,
2426 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2427
2428 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2429 quic_data2.AddWrite(SYNCHRONOUS,
2430 ConstructInitialSettingsPacket(2, &header_stream_offset));
2431 quic_data2.AddSocketDataToFactory(&socket_factory_);
2432
2433 // Resolve the host resolution synchronously.
2434 host_resolver_.set_synchronous_mode(true);
2435 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2436 "");
Zhongyi Shia6b68d112018-09-24 07:49:032437
2438 CreateSession();
2439 session_->quic_stream_factory()->set_require_confirmation(true);
2440 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2441 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2442 QuicStreamFactoryPeer::SetAlarmFactory(
2443 session_->quic_stream_factory(),
2444 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2445 &clock_));
2446 // Add alternate protocol mapping to race QUIC and TCP.
2447 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2448 // peer.
2449 AddQuicAlternateProtocolMapping(
2450 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2451
2452 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2453 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362454 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2456
2457 // Pump the message loop to get the request started.
2458 // Request will be served with TCP job.
2459 base::RunLoop().RunUntilIdle();
2460 EXPECT_THAT(callback.WaitForResult(), IsOk());
2461 CheckResponseData(&trans, "TCP succeeds");
2462
2463 // Fire the retransmission alarm, after which connection will idle
2464 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062465 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182466 quic_fix_time_of_first_packet_sent_after_receiving)) {
2467 quic_task_runner_->RunNextTask();
2468 }
Zhongyi Shia6b68d112018-09-24 07:49:032469 // Fast forward to idle timeout the original connection. A new connection will
2470 // be kicked off on the alternate network.
2471 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2472 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2473 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2474
2475 // The second connection hasn't finish handshake, verify that QUIC is not
2476 // marked as broken.
2477 ExpectQuicAlternateProtocolMapping();
2478 // Explicitly confirm the handshake on the second connection.
2479 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2480 quic::QuicSession::HANDSHAKE_CONFIRMED);
2481 // Run message loop to execute posted tasks, which will notify JoController
2482 // about the orphaned job status.
2483 base::RunLoop().RunUntilIdle();
2484
2485 // Verify that QUIC is marked as broken.
2486 ExpectBrokenAlternateProtocolMapping();
2487
2488 // Deliver a message to notify the new network becomes default, the previous
2489 // brokenness will be clear as the brokenness is bond with old default
2490 // network.
2491 scoped_mock_change_notifier_->mock_network_change_notifier()
2492 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2493 ExpectQuicAlternateProtocolMapping();
2494
2495 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2496 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2497}
2498
2499// This test verifies that a new QUIC connection will be attempted on the
2500// alternate network if the original QUIC connection fails with idle timeout
2501// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2502// alternative network succeeds, QUIC is not marked as broken.
2503TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Michael Warres167db3e2019-03-01 21:38:032504 if (version_ >= quic::QUIC_VERSION_47) {
2505 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2506 return;
2507 }
Zhongyi Shia6b68d112018-09-24 07:49:032508 SetUpTestForRetryConnectionOnAlternateNetwork();
2509
2510 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032511 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032512
2513 // The request will initially go out over QUIC.
2514 MockQuicData quic_data;
2515 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2516 int packet_num = 1;
2517 quic_data.AddWrite(SYNCHRONOUS,
2518 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2519 // Retranmit the handshake messages.
2520 quic_data.AddWrite(SYNCHRONOUS,
2521 client_maker_.MakeDummyCHLOPacket(packet_num++));
2522 quic_data.AddWrite(SYNCHRONOUS,
2523 client_maker_.MakeDummyCHLOPacket(packet_num++));
2524 quic_data.AddWrite(SYNCHRONOUS,
2525 client_maker_.MakeDummyCHLOPacket(packet_num++));
2526 quic_data.AddWrite(SYNCHRONOUS,
2527 client_maker_.MakeDummyCHLOPacket(packet_num++));
2528 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2529 // quic_fix_has_pending_crypto_data is introduced and enabled.
2530 if (version_ <= quic::QUIC_VERSION_39) {
2531 quic_data.AddWrite(SYNCHRONOUS,
2532 client_maker_.MakeDummyCHLOPacket(packet_num++));
2533 }
2534 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2535 quic_data.AddWrite(SYNCHRONOUS,
2536 client_maker_.MakeConnectionClosePacket(
2537 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2538 "No recent network activity."));
2539 quic_data.AddSocketDataToFactory(&socket_factory_);
2540
2541 // Add hanging TCP data so that TCP job will never succeeded.
2542 AddHangingNonAlternateProtocolSocketData();
2543
2544 // Quic connection will then be retried on the alternate network.
2545 MockQuicData quic_data2;
2546 quic::QuicStreamOffset header_stream_offset = 0;
2547 quic_data2.AddWrite(SYNCHRONOUS,
2548 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2549
Victor Vasiliev076657c2019-03-12 02:46:432550 const std::string body = "hello!";
2551 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412552
Zhongyi Shia6b68d112018-09-24 07:49:032553 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2554 quic_data2.AddWrite(SYNCHRONOUS,
2555 ConstructInitialSettingsPacket(2, &header_stream_offset));
2556 quic_data2.AddWrite(
2557 SYNCHRONOUS,
2558 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332559 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032560 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032561 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332562 ASYNC, ConstructServerResponseHeadersPacket(
2563 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2564 GetResponseHeaders("200 OK")));
2565 quic_data2.AddRead(
2566 ASYNC, ConstructServerDataPacket(
2567 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412568 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032569 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2570 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2571 quic_data2.AddSocketDataToFactory(&socket_factory_);
2572
2573 // Resolve the host resolution synchronously.
2574 host_resolver_.set_synchronous_mode(true);
2575 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2576 "");
Zhongyi Shia6b68d112018-09-24 07:49:032577
2578 CreateSession();
2579 session_->quic_stream_factory()->set_require_confirmation(true);
2580 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2581 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2582 QuicStreamFactoryPeer::SetAlarmFactory(
2583 session_->quic_stream_factory(),
2584 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2585 &clock_));
2586 // Add alternate protocol mapping to race QUIC and TCP.
2587 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2588 // peer.
2589 AddQuicAlternateProtocolMapping(
2590 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2591
2592 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2593 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362594 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032595 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2596
2597 // Pump the message loop to get the request started.
2598 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062599 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182600 quic_fix_time_of_first_packet_sent_after_receiving)) {
2601 quic_task_runner_->RunNextTask();
2602 }
Zhongyi Shia6b68d112018-09-24 07:49:032603
2604 // Fast forward to idle timeout the original connection. A new connection will
2605 // be kicked off on the alternate network.
2606 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2607 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2608 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2609
2610 // Verify that QUIC is not marked as broken.
2611 ExpectQuicAlternateProtocolMapping();
2612 // Explicitly confirm the handshake on the second connection.
2613 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2614 quic::QuicSession::HANDSHAKE_CONFIRMED);
2615
2616 // Read the response.
2617 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412618 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032619 // Verify that QUIC is not marked as broken.
2620 ExpectQuicAlternateProtocolMapping();
2621
2622 // Deliver a message to notify the new network becomes default.
2623 scoped_mock_change_notifier_->mock_network_change_notifier()
2624 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2625 ExpectQuicAlternateProtocolMapping();
2626 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2627 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2628}
2629
rch9ecde09b2017-04-08 00:18:232630// Verify that if a QUIC connection times out, the QuicHttpStream will
2631// return QUIC_PROTOCOL_ERROR.
2632TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482633 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412634 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232635
2636 // The request will initially go out over QUIC.
2637 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522638 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132639 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232640 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2641
2642 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032643 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432644 quic_data.AddWrite(SYNCHRONOUS,
2645 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332646 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2647 true, priority, GetRequestHeaders("GET", "https", "/"),
2648 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232649
2650 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522651 quic::QuicStreamOffset settings_offset = header_stream_offset;
2652 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432653 quic_data.AddWrite(SYNCHRONOUS,
2654 client_maker_.MakeInitialSettingsPacketAndSaveData(
2655 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232656 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092657 quic_data.AddWrite(SYNCHRONOUS,
2658 client_maker_.MakeDataPacket(
2659 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2660 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232661 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092662 quic_data.AddWrite(SYNCHRONOUS,
2663 client_maker_.MakeDataPacket(
2664 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2665 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232666 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092667 quic_data.AddWrite(SYNCHRONOUS,
2668 client_maker_.MakeDataPacket(
2669 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2670 false, 0, request_data));
2671 quic_data.AddWrite(SYNCHRONOUS,
2672 client_maker_.MakeDataPacket(
2673 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2674 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232675 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092676 quic_data.AddWrite(SYNCHRONOUS,
2677 client_maker_.MakeDataPacket(
2678 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2679 false, 0, request_data));
2680 quic_data.AddWrite(SYNCHRONOUS,
2681 client_maker_.MakeDataPacket(
2682 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2683 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232684 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092685 quic_data.AddWrite(SYNCHRONOUS,
2686 client_maker_.MakeDataPacket(
2687 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2688 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522689 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092690 SYNCHRONOUS, client_maker_.MakeDataPacket(
2691 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2692 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232693
Zhongyi Shi32f2fd02018-04-16 18:23:432694 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522695 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432696 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222697
rch9ecde09b2017-04-08 00:18:232698 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2699 quic_data.AddRead(ASYNC, OK);
2700 quic_data.AddSocketDataToFactory(&socket_factory_);
2701
2702 // In order for a new QUIC session to be established via alternate-protocol
2703 // without racing an HTTP connection, we need the host resolution to happen
2704 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2705 // connection to the the server, in this test we require confirmation
2706 // before encrypting so the HTTP job will still start.
2707 host_resolver_.set_synchronous_mode(true);
2708 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2709 "");
rch9ecde09b2017-04-08 00:18:232710
2711 CreateSession();
2712 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552713 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232714 QuicStreamFactoryPeer::SetAlarmFactory(
2715 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192716 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552717 &clock_));
rch9ecde09b2017-04-08 00:18:232718
Ryan Hamilton9835e662018-08-02 05:36:272719 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232720
2721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2722 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362723 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2725
2726 // Pump the message loop to get the request started.
2727 base::RunLoop().RunUntilIdle();
2728 // Explicitly confirm the handshake.
2729 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522730 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232731
2732 // Run the QUIC session to completion.
2733 quic_task_runner_->RunUntilIdle();
2734
2735 ExpectQuicAlternateProtocolMapping();
2736 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2737 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2738}
2739
2740// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2741// return QUIC_PROTOCOL_ERROR.
2742TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482743 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522744 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232745
2746 // The request will initially go out over QUIC.
2747 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522748 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132749 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232750 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2751
2752 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032753 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432754 quic_data.AddWrite(SYNCHRONOUS,
2755 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332756 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2757 true, priority, GetRequestHeaders("GET", "https", "/"),
2758 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232759
2760 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522761 quic::QuicStreamOffset settings_offset = header_stream_offset;
2762 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432763 quic_data.AddWrite(SYNCHRONOUS,
2764 client_maker_.MakeInitialSettingsPacketAndSaveData(
2765 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232766 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092767 quic_data.AddWrite(SYNCHRONOUS,
2768 client_maker_.MakeDataPacket(
2769 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2770 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232771 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092772 quic_data.AddWrite(SYNCHRONOUS,
2773 client_maker_.MakeDataPacket(
2774 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2775 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232776 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092777 quic_data.AddWrite(SYNCHRONOUS,
2778 client_maker_.MakeDataPacket(
2779 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2780 false, 0, request_data));
2781 quic_data.AddWrite(SYNCHRONOUS,
2782 client_maker_.MakeDataPacket(
2783 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2784 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232785 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092786 quic_data.AddWrite(SYNCHRONOUS,
2787 client_maker_.MakeDataPacket(
2788 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2789 false, 0, request_data));
2790 quic_data.AddWrite(SYNCHRONOUS,
2791 client_maker_.MakeDataPacket(
2792 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2793 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232794 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092795 quic_data.AddWrite(SYNCHRONOUS,
2796 client_maker_.MakeDataPacket(
2797 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2798 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522799 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092800 SYNCHRONOUS, client_maker_.MakeDataPacket(
2801 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2802 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232803 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522804 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092805 SYNCHRONOUS, client_maker_.MakeDataPacket(
2806 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2807 false, 0, request_data));
2808 quic_data.AddWrite(
2809 SYNCHRONOUS, client_maker_.MakeDataPacket(
2810 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2811 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232812 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432813 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522814 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432815 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232816
2817 quic_data.AddRead(ASYNC, OK);
2818 quic_data.AddSocketDataToFactory(&socket_factory_);
2819
2820 // In order for a new QUIC session to be established via alternate-protocol
2821 // without racing an HTTP connection, we need the host resolution to happen
2822 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2823 // connection to the the server, in this test we require confirmation
2824 // before encrypting so the HTTP job will still start.
2825 host_resolver_.set_synchronous_mode(true);
2826 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2827 "");
rch9ecde09b2017-04-08 00:18:232828
2829 CreateSession();
2830 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552831 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232832 QuicStreamFactoryPeer::SetAlarmFactory(
2833 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192834 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552835 &clock_));
rch9ecde09b2017-04-08 00:18:232836
Ryan Hamilton9835e662018-08-02 05:36:272837 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232838
2839 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2840 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362841 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232842 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2843
2844 // Pump the message loop to get the request started.
2845 base::RunLoop().RunUntilIdle();
2846 // Explicitly confirm the handshake.
2847 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522848 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232849
2850 // Run the QUIC session to completion.
2851 quic_task_runner_->RunUntilIdle();
2852
2853 ExpectQuicAlternateProtocolMapping();
2854 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2855 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2856}
2857
2858// Verify that if a QUIC connection RTOs, while there are no active streams
2859// QUIC will not be marked as broken.
2860TEST_P(QuicNetworkTransactionTest,
2861 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522862 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232863
2864 // The request will initially go out over QUIC.
2865 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522866 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132867 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232868 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2869
2870 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032871 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432872 quic_data.AddWrite(SYNCHRONOUS,
2873 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332874 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2875 true, priority, GetRequestHeaders("GET", "https", "/"),
2876 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232877
2878 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522879 quic::QuicStreamOffset settings_offset = header_stream_offset;
2880 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432881 quic_data.AddWrite(SYNCHRONOUS,
2882 client_maker_.MakeInitialSettingsPacketAndSaveData(
2883 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232884
Fan Yang32c5a112018-12-10 20:06:332885 quic_data.AddWrite(SYNCHRONOUS,
2886 client_maker_.MakeRstPacket(
2887 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2888 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232889 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092890 quic_data.AddWrite(SYNCHRONOUS,
2891 client_maker_.MakeDataPacket(
2892 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2893 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232894 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092895 quic_data.AddWrite(SYNCHRONOUS,
2896 client_maker_.MakeDataPacket(
2897 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2898 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232899 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332900 quic_data.AddWrite(SYNCHRONOUS,
2901 client_maker_.MakeRstPacket(
2902 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2903 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092904 quic_data.AddWrite(SYNCHRONOUS,
2905 client_maker_.MakeDataPacket(
2906 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2907 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232908 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092909 quic_data.AddWrite(SYNCHRONOUS,
2910 client_maker_.MakeDataPacket(
2911 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2912 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332913 quic_data.AddWrite(SYNCHRONOUS,
2914 client_maker_.MakeRstPacket(
2915 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2916 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232917 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522918 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092919 SYNCHRONOUS, client_maker_.MakeDataPacket(
2920 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2921 false, 0, request_data));
2922 quic_data.AddWrite(
2923 SYNCHRONOUS, client_maker_.MakeDataPacket(
2924 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2925 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232926 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432927 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332928 SYNCHRONOUS, client_maker_.MakeRstPacket(
2929 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2930 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522931 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092932 SYNCHRONOUS, client_maker_.MakeDataPacket(
2933 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2934 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232935 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432936 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522937 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432938 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232939
2940 quic_data.AddRead(ASYNC, OK);
2941 quic_data.AddSocketDataToFactory(&socket_factory_);
2942
2943 // In order for a new QUIC session to be established via alternate-protocol
2944 // without racing an HTTP connection, we need the host resolution to happen
2945 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2946 // connection to the the server, in this test we require confirmation
2947 // before encrypting so the HTTP job will still start.
2948 host_resolver_.set_synchronous_mode(true);
2949 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2950 "");
rch9ecde09b2017-04-08 00:18:232951
2952 CreateSession();
2953 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552954 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232955 QuicStreamFactoryPeer::SetAlarmFactory(
2956 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192957 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552958 &clock_));
rch9ecde09b2017-04-08 00:18:232959
Ryan Hamilton9835e662018-08-02 05:36:272960 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232961
Jeremy Roman0579ed62017-08-29 15:56:192962 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232963 session_.get());
2964 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362965 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232966 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2967
2968 // Pump the message loop to get the request started.
2969 base::RunLoop().RunUntilIdle();
2970 // Explicitly confirm the handshake.
2971 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522972 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232973
2974 // Now cancel the request.
2975 trans.reset();
2976
2977 // Run the QUIC session to completion.
2978 quic_task_runner_->RunUntilIdle();
2979
2980 ExpectQuicAlternateProtocolMapping();
2981
2982 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2983}
2984
rch2f2991c2017-04-13 19:28:172985// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2986// the request fails with QUIC_PROTOCOL_ERROR.
2987TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482988 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172989 // The request will initially go out over QUIC.
2990 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522991 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:032992 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432993 quic_data.AddWrite(
2994 SYNCHRONOUS,
2995 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332996 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432997 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522998 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432999 quic_data.AddWrite(SYNCHRONOUS,
3000 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173001 // Peer sending data from an non-existing stream causes this end to raise
3002 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333003 quic_data.AddRead(
3004 ASYNC, ConstructServerRstPacket(
3005 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3006 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173007 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433008 quic_data.AddWrite(SYNCHRONOUS,
3009 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523010 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3011 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173012 quic_data.AddSocketDataToFactory(&socket_factory_);
3013
3014 // In order for a new QUIC session to be established via alternate-protocol
3015 // without racing an HTTP connection, we need the host resolution to happen
3016 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3017 // connection to the the server, in this test we require confirmation
3018 // before encrypting so the HTTP job will still start.
3019 host_resolver_.set_synchronous_mode(true);
3020 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3021 "");
rch2f2991c2017-04-13 19:28:173022
3023 CreateSession();
3024
Ryan Hamilton9835e662018-08-02 05:36:273025 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173026
3027 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3028 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363029 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3031
3032 // Pump the message loop to get the request started.
3033 base::RunLoop().RunUntilIdle();
3034 // Explicitly confirm the handshake.
3035 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523036 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173037
3038 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3039
3040 // Run the QUIC session to completion.
3041 base::RunLoop().RunUntilIdle();
3042 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3043 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3044
3045 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3046 ExpectQuicAlternateProtocolMapping();
3047 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3048}
3049
rch9ecde09b2017-04-08 00:18:233050// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3051// connection times out, then QUIC will be marked as broken and the request
3052// retried over TCP.
3053TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413054 session_params_.mark_quic_broken_when_network_blackholes = true;
3055 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233056
3057 // The request will initially go out over QUIC.
3058 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523059 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133060 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233061 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3062
3063 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033064 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433065 quic_data.AddWrite(SYNCHRONOUS,
3066 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333067 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3068 true, priority, GetRequestHeaders("GET", "https", "/"),
3069 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233070
3071 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523072 quic::QuicStreamOffset settings_offset = header_stream_offset;
3073 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433074 quic_data.AddWrite(SYNCHRONOUS,
3075 client_maker_.MakeInitialSettingsPacketAndSaveData(
3076 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233077 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093078 quic_data.AddWrite(SYNCHRONOUS,
3079 client_maker_.MakeDataPacket(
3080 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3081 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233082 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093083 quic_data.AddWrite(SYNCHRONOUS,
3084 client_maker_.MakeDataPacket(
3085 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3086 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233087 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093088 quic_data.AddWrite(SYNCHRONOUS,
3089 client_maker_.MakeDataPacket(
3090 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3091 false, 0, request_data));
3092 quic_data.AddWrite(SYNCHRONOUS,
3093 client_maker_.MakeDataPacket(
3094 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3095 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233096 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093097 quic_data.AddWrite(SYNCHRONOUS,
3098 client_maker_.MakeDataPacket(
3099 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3100 false, 0, request_data));
3101 quic_data.AddWrite(SYNCHRONOUS,
3102 client_maker_.MakeDataPacket(
3103 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3104 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233105 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093106 quic_data.AddWrite(SYNCHRONOUS,
3107 client_maker_.MakeDataPacket(
3108 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3109 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523110 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093111 SYNCHRONOUS, client_maker_.MakeDataPacket(
3112 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3113 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233114
Zhongyi Shi32f2fd02018-04-16 18:23:433115 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523116 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433117 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223118
rch9ecde09b2017-04-08 00:18:233119 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3120 quic_data.AddRead(ASYNC, OK);
3121 quic_data.AddSocketDataToFactory(&socket_factory_);
3122
3123 // After that fails, it will be resent via TCP.
3124 MockWrite http_writes[] = {
3125 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3126 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3127 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3128
3129 MockRead http_reads[] = {
3130 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3131 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3132 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013133 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233134 socket_factory_.AddSocketDataProvider(&http_data);
3135 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3136
3137 // In order for a new QUIC session to be established via alternate-protocol
3138 // without racing an HTTP connection, we need the host resolution to happen
3139 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3140 // connection to the the server, in this test we require confirmation
3141 // before encrypting so the HTTP job will still start.
3142 host_resolver_.set_synchronous_mode(true);
3143 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3144 "");
rch9ecde09b2017-04-08 00:18:233145
3146 CreateSession();
3147 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553148 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233149 QuicStreamFactoryPeer::SetAlarmFactory(
3150 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193151 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553152 &clock_));
rch9ecde09b2017-04-08 00:18:233153
Ryan Hamilton9835e662018-08-02 05:36:273154 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233155
3156 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3157 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363158 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233159 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3160
3161 // Pump the message loop to get the request started.
3162 base::RunLoop().RunUntilIdle();
3163 // Explicitly confirm the handshake.
3164 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523165 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233166
3167 // Run the QUIC session to completion.
3168 quic_task_runner_->RunUntilIdle();
3169 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3170
3171 // Let the transaction proceed which will result in QUIC being marked
3172 // as broken and the request falling back to TCP.
3173 EXPECT_THAT(callback.WaitForResult(), IsOk());
3174
3175 ExpectBrokenAlternateProtocolMapping();
3176 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3177 ASSERT_FALSE(http_data.AllReadDataConsumed());
3178
3179 // Read the response body over TCP.
3180 CheckResponseData(&trans, "hello world");
3181 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3182 ASSERT_TRUE(http_data.AllReadDataConsumed());
3183}
3184
rch2f2991c2017-04-13 19:28:173185// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3186// connection times out, then QUIC will be marked as broken and the request
3187// retried over TCP.
3188TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413189 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173190
3191 // The request will initially go out over QUIC.
3192 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523193 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133194 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173195 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3196
3197 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033198 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433199 quic_data.AddWrite(SYNCHRONOUS,
3200 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333201 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3202 true, priority, GetRequestHeaders("GET", "https", "/"),
3203 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173204
3205 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523206 quic::QuicStreamOffset settings_offset = header_stream_offset;
3207 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433208 quic_data.AddWrite(SYNCHRONOUS,
3209 client_maker_.MakeInitialSettingsPacketAndSaveData(
3210 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173211 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093212 quic_data.AddWrite(SYNCHRONOUS,
3213 client_maker_.MakeDataPacket(
3214 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3215 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173216 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093217 quic_data.AddWrite(SYNCHRONOUS,
3218 client_maker_.MakeDataPacket(
3219 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3220 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173221 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093222 quic_data.AddWrite(SYNCHRONOUS,
3223 client_maker_.MakeDataPacket(
3224 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3225 false, 0, request_data));
3226 quic_data.AddWrite(SYNCHRONOUS,
3227 client_maker_.MakeDataPacket(
3228 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3229 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173230 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093231 quic_data.AddWrite(SYNCHRONOUS,
3232 client_maker_.MakeDataPacket(
3233 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3234 false, 0, request_data));
3235 quic_data.AddWrite(SYNCHRONOUS,
3236 client_maker_.MakeDataPacket(
3237 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3238 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173239 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093240 quic_data.AddWrite(SYNCHRONOUS,
3241 client_maker_.MakeDataPacket(
3242 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3243 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523244 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093245 SYNCHRONOUS, client_maker_.MakeDataPacket(
3246 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3247 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173248
Zhongyi Shi32f2fd02018-04-16 18:23:433249 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523250 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433251 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223252
rch2f2991c2017-04-13 19:28:173253 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3254 quic_data.AddRead(ASYNC, OK);
3255 quic_data.AddSocketDataToFactory(&socket_factory_);
3256
3257 // After that fails, it will be resent via TCP.
3258 MockWrite http_writes[] = {
3259 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3260 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3261 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3262
3263 MockRead http_reads[] = {
3264 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3265 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3266 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013267 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173268 socket_factory_.AddSocketDataProvider(&http_data);
3269 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3270
3271 // In order for a new QUIC session to be established via alternate-protocol
3272 // without racing an HTTP connection, we need the host resolution to happen
3273 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3274 // connection to the the server, in this test we require confirmation
3275 // before encrypting so the HTTP job will still start.
3276 host_resolver_.set_synchronous_mode(true);
3277 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3278 "");
rch2f2991c2017-04-13 19:28:173279
3280 CreateSession();
3281 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553282 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173283 QuicStreamFactoryPeer::SetAlarmFactory(
3284 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193285 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553286 &clock_));
rch2f2991c2017-04-13 19:28:173287
Ryan Hamilton9835e662018-08-02 05:36:273288 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173289
3290 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3291 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363292 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173293 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3294
3295 // Pump the message loop to get the request started.
3296 base::RunLoop().RunUntilIdle();
3297 // Explicitly confirm the handshake.
3298 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523299 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173300
3301 // Run the QUIC session to completion.
3302 quic_task_runner_->RunUntilIdle();
3303 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3304
3305 ExpectQuicAlternateProtocolMapping();
3306
3307 // Let the transaction proceed which will result in QUIC being marked
3308 // as broken and the request falling back to TCP.
3309 EXPECT_THAT(callback.WaitForResult(), IsOk());
3310
3311 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3312 ASSERT_FALSE(http_data.AllReadDataConsumed());
3313
3314 // Read the response body over TCP.
3315 CheckResponseData(&trans, "hello world");
3316 ExpectBrokenAlternateProtocolMapping();
3317 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3318 ASSERT_TRUE(http_data.AllReadDataConsumed());
3319}
3320
rch9ecde09b2017-04-08 00:18:233321// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3322// connection times out, then QUIC will be marked as broken but the request
3323// will not be retried over TCP.
3324TEST_P(QuicNetworkTransactionTest,
3325 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413326 session_params_.mark_quic_broken_when_network_blackholes = true;
3327 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233328
3329 // The request will initially go out over QUIC.
3330 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523331 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133332 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233333 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3334
3335 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033336 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433337 quic_data.AddWrite(SYNCHRONOUS,
3338 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333339 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3340 true, priority, GetRequestHeaders("GET", "https", "/"),
3341 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233342
3343 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523344 quic::QuicStreamOffset settings_offset = header_stream_offset;
3345 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433346 quic_data.AddWrite(SYNCHRONOUS,
3347 client_maker_.MakeInitialSettingsPacketAndSaveData(
3348 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233349
Zhongyi Shi32f2fd02018-04-16 18:23:433350 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333351 1, GetNthClientInitiatedBidirectionalStreamId(0),
3352 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433353 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523354 quic_data.AddWrite(
3355 SYNCHRONOUS,
3356 ConstructClientAckPacket(3, 1, 1, 1,
3357 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233358
3359 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523360 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093361 SYNCHRONOUS, client_maker_.MakeDataPacket(
3362 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3363 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233364 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093365 quic_data.AddWrite(
3366 SYNCHRONOUS, client_maker_.MakeDataPacket(
3367 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3368 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233369 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523370 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093371 SYNCHRONOUS, client_maker_.MakeDataPacket(
3372 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3373 false, 0, request_data));
3374 quic_data.AddWrite(
3375 SYNCHRONOUS, client_maker_.MakeDataPacket(
3376 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3377 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233378 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523379 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093380 SYNCHRONOUS, client_maker_.MakeDataPacket(
3381 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3382 false, 0, request_data));
3383 quic_data.AddWrite(
3384 SYNCHRONOUS, client_maker_.MakeDataPacket(
3385 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3386 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233387 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523388 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093389 SYNCHRONOUS, client_maker_.MakeDataPacket(
3390 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3391 false, 0, request_data));
3392 quic_data.AddWrite(
3393 SYNCHRONOUS, client_maker_.MakeDataPacket(
3394 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3395 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233396
Michael Warres112212822018-12-26 17:51:063397 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183398 quic_fix_time_of_first_packet_sent_after_receiving)) {
3399 quic_data.AddWrite(
3400 SYNCHRONOUS,
3401 client_maker_.MakeAckAndConnectionClosePacket(
3402 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3403 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3404
3405 } else {
3406 quic_data.AddWrite(
3407 SYNCHRONOUS,
3408 client_maker_.MakeAckAndConnectionClosePacket(
3409 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3410 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3411 }
Fan Yang928f1632017-12-14 18:55:223412
rch9ecde09b2017-04-08 00:18:233413 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3414 quic_data.AddRead(ASYNC, OK);
3415 quic_data.AddSocketDataToFactory(&socket_factory_);
3416
3417 // In order for a new QUIC session to be established via alternate-protocol
3418 // without racing an HTTP connection, we need the host resolution to happen
3419 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3420 // connection to the the server, in this test we require confirmation
3421 // before encrypting so the HTTP job will still start.
3422 host_resolver_.set_synchronous_mode(true);
3423 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3424 "");
rch9ecde09b2017-04-08 00:18:233425
3426 CreateSession();
3427 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553428 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233429 QuicStreamFactoryPeer::SetAlarmFactory(
3430 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193431 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553432 &clock_));
rch9ecde09b2017-04-08 00:18:233433
Ryan Hamilton9835e662018-08-02 05:36:273434 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233435
3436 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3437 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363438 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233439 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3440
3441 // Pump the message loop to get the request started.
3442 base::RunLoop().RunUntilIdle();
3443 // Explicitly confirm the handshake.
3444 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523445 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233446
3447 // Pump the message loop to get the request started.
3448 base::RunLoop().RunUntilIdle();
3449
3450 // Run the QUIC session to completion.
3451 quic_task_runner_->RunUntilIdle();
3452 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3453
3454 // Let the transaction proceed which will result in QUIC being marked
3455 // as broken and the request falling back to TCP.
3456 EXPECT_THAT(callback.WaitForResult(), IsOk());
3457
3458 ExpectBrokenAlternateProtocolMapping();
3459 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3460
3461 std::string response_data;
3462 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3463 IsError(ERR_QUIC_PROTOCOL_ERROR));
3464}
3465
3466// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3467// connection RTOs, then QUIC will be marked as broken and the request retried
3468// over TCP.
3469TEST_P(QuicNetworkTransactionTest,
3470 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413471 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523472 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233473
3474 // The request will initially go out over QUIC.
3475 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523476 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133477 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233478 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3479
3480 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033481 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433482 quic_data.AddWrite(SYNCHRONOUS,
3483 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333484 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3485 true, priority, GetRequestHeaders("GET", "https", "/"),
3486 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233487
3488 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523489 quic::QuicStreamOffset settings_offset = header_stream_offset;
3490 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433491 quic_data.AddWrite(SYNCHRONOUS,
3492 client_maker_.MakeInitialSettingsPacketAndSaveData(
3493 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233494 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093495 quic_data.AddWrite(SYNCHRONOUS,
3496 client_maker_.MakeDataPacket(
3497 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3498 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233499 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093500 quic_data.AddWrite(SYNCHRONOUS,
3501 client_maker_.MakeDataPacket(
3502 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3503 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233504 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093505 quic_data.AddWrite(SYNCHRONOUS,
3506 client_maker_.MakeDataPacket(
3507 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3508 false, 0, request_data));
3509 quic_data.AddWrite(SYNCHRONOUS,
3510 client_maker_.MakeDataPacket(
3511 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3512 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233513 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093514 quic_data.AddWrite(SYNCHRONOUS,
3515 client_maker_.MakeDataPacket(
3516 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3517 false, 0, request_data));
3518 quic_data.AddWrite(SYNCHRONOUS,
3519 client_maker_.MakeDataPacket(
3520 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3521 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233522 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093523 quic_data.AddWrite(SYNCHRONOUS,
3524 client_maker_.MakeDataPacket(
3525 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3526 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523527 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093528 SYNCHRONOUS, client_maker_.MakeDataPacket(
3529 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3530 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233531 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523532 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093533 SYNCHRONOUS, client_maker_.MakeDataPacket(
3534 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3535 false, 0, request_data));
3536 quic_data.AddWrite(
3537 SYNCHRONOUS, client_maker_.MakeDataPacket(
3538 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3539 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233540
Zhongyi Shi32f2fd02018-04-16 18:23:433541 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523542 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433543 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233544
3545 quic_data.AddRead(ASYNC, OK);
3546 quic_data.AddSocketDataToFactory(&socket_factory_);
3547
3548 // After that fails, it will be resent via TCP.
3549 MockWrite http_writes[] = {
3550 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3551 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3552 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3553
3554 MockRead http_reads[] = {
3555 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3556 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3557 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013558 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233559 socket_factory_.AddSocketDataProvider(&http_data);
3560 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3561
3562 // In order for a new QUIC session to be established via alternate-protocol
3563 // without racing an HTTP connection, we need the host resolution to happen
3564 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3565 // connection to the the server, in this test we require confirmation
3566 // before encrypting so the HTTP job will still start.
3567 host_resolver_.set_synchronous_mode(true);
3568 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3569 "");
rch9ecde09b2017-04-08 00:18:233570
3571 CreateSession();
3572 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553573 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233574 QuicStreamFactoryPeer::SetAlarmFactory(
3575 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193576 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553577 &clock_));
rch9ecde09b2017-04-08 00:18:233578
Ryan Hamilton9835e662018-08-02 05:36:273579 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233580
3581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3582 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363583 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3585
3586 // Pump the message loop to get the request started.
3587 base::RunLoop().RunUntilIdle();
3588 // Explicitly confirm the handshake.
3589 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523590 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233591
3592 // Run the QUIC session to completion.
3593 quic_task_runner_->RunUntilIdle();
3594 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3595
3596 // Let the transaction proceed which will result in QUIC being marked
3597 // as broken and the request falling back to TCP.
3598 EXPECT_THAT(callback.WaitForResult(), IsOk());
3599
3600 ExpectBrokenAlternateProtocolMapping();
3601 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3602 ASSERT_FALSE(http_data.AllReadDataConsumed());
3603
3604 // Read the response body over TCP.
3605 CheckResponseData(&trans, "hello world");
3606 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3607 ASSERT_TRUE(http_data.AllReadDataConsumed());
3608}
3609
3610// Verify that if a QUIC connection RTOs, while there are no active streams
3611// QUIC will be marked as broken.
3612TEST_P(QuicNetworkTransactionTest,
3613 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413614 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523615 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233616
3617 // The request will initially go out over QUIC.
3618 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523619 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133620 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233621 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3622
3623 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033624 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433625 quic_data.AddWrite(SYNCHRONOUS,
3626 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333627 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3628 true, priority, GetRequestHeaders("GET", "https", "/"),
3629 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233630
3631 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523632 quic::QuicStreamOffset settings_offset = header_stream_offset;
3633 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433634 quic_data.AddWrite(SYNCHRONOUS,
3635 client_maker_.MakeInitialSettingsPacketAndSaveData(
3636 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233637
Fan Yang32c5a112018-12-10 20:06:333638 quic_data.AddWrite(SYNCHRONOUS,
3639 client_maker_.MakeRstPacket(
3640 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3641 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233642 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093643 quic_data.AddWrite(SYNCHRONOUS,
3644 client_maker_.MakeDataPacket(
3645 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3646 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233647 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093648 quic_data.AddWrite(SYNCHRONOUS,
3649 client_maker_.MakeDataPacket(
3650 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3651 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233652 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333653 quic_data.AddWrite(SYNCHRONOUS,
3654 client_maker_.MakeRstPacket(
3655 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3656 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093657 quic_data.AddWrite(SYNCHRONOUS,
3658 client_maker_.MakeDataPacket(
3659 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3660 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233661 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093662 quic_data.AddWrite(SYNCHRONOUS,
3663 client_maker_.MakeDataPacket(
3664 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3665 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333666 quic_data.AddWrite(SYNCHRONOUS,
3667 client_maker_.MakeRstPacket(
3668 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3669 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233670 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523671 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093672 SYNCHRONOUS, client_maker_.MakeDataPacket(
3673 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3674 false, 0, request_data));
3675 quic_data.AddWrite(
3676 SYNCHRONOUS, client_maker_.MakeDataPacket(
3677 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3678 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233679 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433680 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333681 SYNCHRONOUS, client_maker_.MakeRstPacket(
3682 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3683 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523684 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093685 SYNCHRONOUS, client_maker_.MakeDataPacket(
3686 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3687 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233688 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433689 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523690 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433691 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233692
3693 quic_data.AddRead(ASYNC, OK);
3694 quic_data.AddSocketDataToFactory(&socket_factory_);
3695
3696 // In order for a new QUIC session to be established via alternate-protocol
3697 // without racing an HTTP connection, we need the host resolution to happen
3698 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3699 // connection to the the server, in this test we require confirmation
3700 // before encrypting so the HTTP job will still start.
3701 host_resolver_.set_synchronous_mode(true);
3702 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3703 "");
rch9ecde09b2017-04-08 00:18:233704
3705 CreateSession();
3706 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553707 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233708 QuicStreamFactoryPeer::SetAlarmFactory(
3709 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193710 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553711 &clock_));
rch9ecde09b2017-04-08 00:18:233712
Ryan Hamilton9835e662018-08-02 05:36:273713 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233714
Jeremy Roman0579ed62017-08-29 15:56:193715 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233716 session_.get());
3717 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363718 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3720
3721 // Pump the message loop to get the request started.
3722 base::RunLoop().RunUntilIdle();
3723 // Explicitly confirm the handshake.
3724 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523725 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233726
3727 // Now cancel the request.
3728 trans.reset();
3729
3730 // Run the QUIC session to completion.
3731 quic_task_runner_->RunUntilIdle();
3732
3733 ExpectBrokenAlternateProtocolMapping();
3734
3735 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3736}
3737
rch2f2991c2017-04-13 19:28:173738// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3739// protocol error occurs after the handshake is confirmed, the request
3740// retried over TCP and the QUIC will be marked as broken.
3741TEST_P(QuicNetworkTransactionTest,
3742 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413743 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173744
3745 // The request will initially go out over QUIC.
3746 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523747 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033748 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433749 quic_data.AddWrite(
3750 SYNCHRONOUS,
3751 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333752 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433753 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523754 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433755 quic_data.AddWrite(SYNCHRONOUS,
3756 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173757 // Peer sending data from an non-existing stream causes this end to raise
3758 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333759 quic_data.AddRead(
3760 ASYNC, ConstructServerRstPacket(
3761 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3762 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173763 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433764 quic_data.AddWrite(SYNCHRONOUS,
3765 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523766 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3767 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173768 quic_data.AddSocketDataToFactory(&socket_factory_);
3769
3770 // After that fails, it will be resent via TCP.
3771 MockWrite http_writes[] = {
3772 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3773 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3774 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3775
3776 MockRead http_reads[] = {
3777 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3778 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3779 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013780 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173781 socket_factory_.AddSocketDataProvider(&http_data);
3782 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3783
3784 // In order for a new QUIC session to be established via alternate-protocol
3785 // without racing an HTTP connection, we need the host resolution to happen
3786 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3787 // connection to the the server, in this test we require confirmation
3788 // before encrypting so the HTTP job will still start.
3789 host_resolver_.set_synchronous_mode(true);
3790 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3791 "");
rch2f2991c2017-04-13 19:28:173792
3793 CreateSession();
3794
Ryan Hamilton9835e662018-08-02 05:36:273795 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173796
3797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3798 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363799 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3801
3802 // Pump the message loop to get the request started.
3803 base::RunLoop().RunUntilIdle();
3804 // Explicitly confirm the handshake.
3805 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523806 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173807
3808 // Run the QUIC session to completion.
3809 base::RunLoop().RunUntilIdle();
3810 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3811
3812 ExpectQuicAlternateProtocolMapping();
3813
3814 // Let the transaction proceed which will result in QUIC being marked
3815 // as broken and the request falling back to TCP.
3816 EXPECT_THAT(callback.WaitForResult(), IsOk());
3817
3818 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3819 ASSERT_FALSE(http_data.AllReadDataConsumed());
3820
3821 // Read the response body over TCP.
3822 CheckResponseData(&trans, "hello world");
3823 ExpectBrokenAlternateProtocolMapping();
3824 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3825 ASSERT_TRUE(http_data.AllReadDataConsumed());
3826}
3827
rch30943ee2017-06-12 21:28:443828// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3829// request is reset from, then QUIC will be marked as broken and the request
3830// retried over TCP.
3831TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443832 // The request will initially go out over QUIC.
3833 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523834 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133835 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443836 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3837
3838 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033839 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433840 quic_data.AddWrite(SYNCHRONOUS,
3841 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333842 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3843 true, priority, GetRequestHeaders("GET", "https", "/"),
3844 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443845
3846 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523847 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3848 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433849 quic_data.AddWrite(SYNCHRONOUS,
3850 client_maker_.MakeInitialSettingsPacketAndSaveData(
3851 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443852
Fan Yang32c5a112018-12-10 20:06:333853 quic_data.AddRead(ASYNC,
3854 ConstructServerRstPacket(
3855 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3856 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443857
3858 quic_data.AddRead(ASYNC, OK);
3859 quic_data.AddSocketDataToFactory(&socket_factory_);
3860
3861 // After that fails, it will be resent via TCP.
3862 MockWrite http_writes[] = {
3863 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3864 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3865 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3866
3867 MockRead http_reads[] = {
3868 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3869 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3870 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013871 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443872 socket_factory_.AddSocketDataProvider(&http_data);
3873 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3874
3875 // In order for a new QUIC session to be established via alternate-protocol
3876 // without racing an HTTP connection, we need the host resolution to happen
3877 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3878 // connection to the the server, in this test we require confirmation
3879 // before encrypting so the HTTP job will still start.
3880 host_resolver_.set_synchronous_mode(true);
3881 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3882 "");
rch30943ee2017-06-12 21:28:443883
3884 CreateSession();
3885
Ryan Hamilton9835e662018-08-02 05:36:273886 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443887
3888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3889 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363890 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3892
3893 // Pump the message loop to get the request started.
3894 base::RunLoop().RunUntilIdle();
3895 // Explicitly confirm the handshake.
3896 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523897 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443898
3899 // Run the QUIC session to completion.
3900 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3901
3902 ExpectQuicAlternateProtocolMapping();
3903
3904 // Let the transaction proceed which will result in QUIC being marked
3905 // as broken and the request falling back to TCP.
3906 EXPECT_THAT(callback.WaitForResult(), IsOk());
3907
3908 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3909 ASSERT_FALSE(http_data.AllReadDataConsumed());
3910
3911 // Read the response body over TCP.
3912 CheckResponseData(&trans, "hello world");
3913 ExpectBrokenAlternateProtocolMapping();
3914 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3915 ASSERT_TRUE(http_data.AllReadDataConsumed());
3916}
3917
Ryan Hamilton6c2a2a82017-12-15 02:06:283918// Verify that when an origin has two alt-svc advertisements, one local and one
3919// remote, that when the local is broken the request will go over QUIC via
3920// the remote Alt-Svc.
3921// This is a regression test for crbug/825646.
3922TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3923 session_params_.quic_allow_remote_alt_svc = true;
3924
3925 GURL origin1 = request_.url; // mail.example.org
3926 GURL origin2("https://www.example.org/");
3927 ASSERT_NE(origin1.host(), origin2.host());
3928
3929 scoped_refptr<X509Certificate> cert(
3930 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243931 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3932 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283933
3934 ProofVerifyDetailsChromium verify_details;
3935 verify_details.cert_verify_result.verified_cert = cert;
3936 verify_details.cert_verify_result.is_issued_by_known_root = true;
3937 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3938
3939 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523940 quic::QuicStreamOffset request_header_offset(0);
3941 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283942 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433943 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3944 mock_quic_data.AddWrite(
3945 SYNCHRONOUS,
3946 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333947 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433948 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3949 mock_quic_data.AddRead(
3950 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333951 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433952 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:433953 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433954 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333955 ASYNC, ConstructServerDataPacket(
3956 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:413957 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433958 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283959 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3960 mock_quic_data.AddRead(ASYNC, 0); // EOF
3961
3962 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3963 MockQuicData mock_quic_data2;
3964 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3965 AddHangingNonAlternateProtocolSocketData();
3966
3967 CreateSession();
3968
3969 // Set up alternative service for |origin1|.
3970 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3971 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3972 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3973 AlternativeServiceInfoVector alternative_services;
3974 alternative_services.push_back(
3975 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3976 local_alternative, expiration,
3977 session_->params().quic_supported_versions));
3978 alternative_services.push_back(
3979 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3980 remote_alternative, expiration,
3981 session_->params().quic_supported_versions));
3982 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3983 alternative_services);
3984
3985 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3986
3987 SendRequestAndExpectQuicResponse("hello!");
3988}
3989
rch30943ee2017-06-12 21:28:443990// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3991// request is reset from, then QUIC will be marked as broken and the request
3992// retried over TCP. Then, subsequent requests will go over a new QUIC
3993// connection instead of going back to the broken QUIC connection.
3994// This is a regression tests for crbug/731303.
3995TEST_P(QuicNetworkTransactionTest,
3996 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:343997 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443998
3999 GURL origin1 = request_.url;
4000 GURL origin2("https://www.example.org/");
4001 ASSERT_NE(origin1.host(), origin2.host());
4002
4003 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524004 quic::QuicStreamOffset request_header_offset(0);
4005 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444006
4007 scoped_refptr<X509Certificate> cert(
4008 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244009 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4010 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444011
4012 ProofVerifyDetailsChromium verify_details;
4013 verify_details.cert_verify_result.verified_cert = cert;
4014 verify_details.cert_verify_result.is_issued_by_known_root = true;
4015 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4016
4017 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434018 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444019 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434020 mock_quic_data.AddWrite(
4021 SYNCHRONOUS,
4022 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334023 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434024 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4025 mock_quic_data.AddRead(
4026 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334027 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434028 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434029 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434030 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334031 ASYNC, ConstructServerDataPacket(
4032 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414033 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434034 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444035
4036 // Second request will go over the pooled QUIC connection, but will be
4037 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054038 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174039 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4040 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054041 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174042 QuicTestPacketMaker server_maker2(
4043 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4044 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434045 mock_quic_data.AddWrite(
4046 SYNCHRONOUS,
4047 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334048 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434049 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334050 GetNthClientInitiatedBidirectionalStreamId(0),
4051 &request_header_offset));
4052 mock_quic_data.AddRead(
4053 ASYNC, ConstructServerRstPacket(
4054 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4055 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444056 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4057 mock_quic_data.AddRead(ASYNC, 0); // EOF
4058
4059 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4060
4061 // After that fails, it will be resent via TCP.
4062 MockWrite http_writes[] = {
4063 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4064 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4065 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4066
4067 MockRead http_reads[] = {
4068 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4069 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4070 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014071 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444072 socket_factory_.AddSocketDataProvider(&http_data);
4073 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4074
Ryan Hamilton6c2a2a82017-12-15 02:06:284075 // Then the next request to the second origin will be sent over TCP.
4076 socket_factory_.AddSocketDataProvider(&http_data);
4077 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444078
4079 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564080 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4081 QuicStreamFactoryPeer::SetAlarmFactory(
4082 session_->quic_stream_factory(),
4083 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4084 &clock_));
rch30943ee2017-06-12 21:28:444085
4086 // Set up alternative service for |origin1|.
4087 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244088 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214089 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244090 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444091 supported_versions_);
rch30943ee2017-06-12 21:28:444092
4093 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244094 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214095 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244096 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444097 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344098
rch30943ee2017-06-12 21:28:444099 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524100 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444101 SendRequestAndExpectQuicResponse("hello!");
4102
4103 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524104 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444105 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4106 request_.url = origin2;
4107 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284108 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244109 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284110 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244111 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444112
4113 // The third request should use a new QUIC connection, not the broken
4114 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284115 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444116}
4117
bnc8be55ebb2015-10-30 14:12:074118TEST_P(QuicNetworkTransactionTest,
4119 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4120 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444121 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074122 MockRead http_reads[] = {
4123 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4124 MockRead("hello world"),
4125 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4126 MockRead(ASYNC, OK)};
4127
Ryan Sleevib8d7ea02018-05-07 20:01:014128 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074129 socket_factory_.AddSocketDataProvider(&http_data);
4130 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4131 socket_factory_.AddSocketDataProvider(&http_data);
4132 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4133
rch3f4b8452016-02-23 16:59:324134 CreateSession();
bnc8be55ebb2015-10-30 14:12:074135
4136 SendRequestAndExpectHttpResponse("hello world");
4137 SendRequestAndExpectHttpResponse("hello world");
4138}
4139
Xida Chen9bfe0b62018-04-24 19:52:214140// When multiple alternative services are advertised, HttpStreamFactory should
4141// select the alternative service which uses existing QUIC session if available.
4142// If no existing QUIC session can be used, use the first alternative service
4143// from the list.
zhongyi32569c62016-01-08 02:54:304144TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344145 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524146 MockRead http_reads[] = {
4147 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294148 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524149 MockRead("hello world"),
4150 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4151 MockRead(ASYNC, OK)};
4152
Ryan Sleevib8d7ea02018-05-07 20:01:014153 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524154 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084155 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564156 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524157
Ryan Hamilton8d9ee76e2018-05-29 23:52:524158 quic::QuicStreamOffset request_header_offset = 0;
4159 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304160 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294161 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304162 // alternative service list.
bncc958faa2015-07-31 18:14:524163 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364164 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434165 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4166 mock_quic_data.AddWrite(
4167 SYNCHRONOUS,
4168 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334169 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434170 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304171
4172 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294173 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4174 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434175 mock_quic_data.AddRead(
4176 ASYNC,
4177 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334178 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434179 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434180 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434181 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334182 ASYNC, ConstructServerDataPacket(
4183 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414184 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434185 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304186
4187 // Second QUIC request data.
4188 // Connection pooling, using existing session, no need to include version
4189 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584190 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334191 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4192 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4193 true, GetRequestHeaders("GET", "https", "/"),
4194 GetNthClientInitiatedBidirectionalStreamId(0),
4195 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434196 mock_quic_data.AddRead(
4197 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334198 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434199 GetResponseHeaders("200 OK"), &response_header_offset));
4200 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334201 ASYNC, ConstructServerDataPacket(
4202 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414203 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434204 mock_quic_data.AddWrite(
4205 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524206 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594207 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524208
4209 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4210
rtennetib8e80fb2016-05-16 00:12:094211 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324212 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564213 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4214 QuicStreamFactoryPeer::SetAlarmFactory(
4215 session_->quic_stream_factory(),
4216 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4217 &clock_));
bncc958faa2015-07-31 18:14:524218
4219 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304220
bnc359ed2a2016-04-29 20:43:454221 SendRequestAndExpectQuicResponse("hello!");
4222 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304223}
4224
tbansal6490783c2016-09-20 17:55:274225// Check that an existing QUIC connection to an alternative proxy server is
4226// used.
4227TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4228 base::HistogramTester histogram_tester;
4229
Ryan Hamilton8d9ee76e2018-05-29 23:52:524230 quic::QuicStreamOffset request_header_offset = 0;
4231 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274232 // First QUIC request data.
4233 // Open a session to foo.example.org:443 using the first entry of the
4234 // alternative service list.
4235 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364236 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434237 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4238 mock_quic_data.AddWrite(
4239 SYNCHRONOUS,
4240 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334241 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434242 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274243
4244 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434245 mock_quic_data.AddRead(
4246 ASYNC,
4247 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334248 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434249 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434250 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434251 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334252 ASYNC, ConstructServerDataPacket(
4253 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414254 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434255 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274256
4257 // Second QUIC request data.
4258 // Connection pooling, using existing session, no need to include version
4259 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274260 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334261 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4262 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4263 true, GetRequestHeaders("GET", "http", "/"),
4264 GetNthClientInitiatedBidirectionalStreamId(0),
4265 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434266 mock_quic_data.AddRead(
4267 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334268 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434269 GetResponseHeaders("200 OK"), &response_header_offset));
4270 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334271 ASYNC, ConstructServerDataPacket(
4272 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414273 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434274 mock_quic_data.AddWrite(
4275 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274276 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4277 mock_quic_data.AddRead(ASYNC, 0); // EOF
4278
4279 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4280
4281 AddHangingNonAlternateProtocolSocketData();
4282
4283 TestProxyDelegate test_proxy_delegate;
4284
Lily Houghton8c2f97d2018-01-22 05:06:594285 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494286 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274287
4288 test_proxy_delegate.set_alternative_proxy_server(
4289 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524290 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274291
4292 request_.url = GURL("http://mail.example.org/");
4293
4294 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564295 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4296 QuicStreamFactoryPeer::SetAlarmFactory(
4297 session_->quic_stream_factory(),
4298 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4299 &clock_));
tbansal6490783c2016-09-20 17:55:274300
4301 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4302 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4303 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4304 1);
4305
4306 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4307 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4308 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4309 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4310 1);
4311}
4312
Ryan Hamilton8d9ee76e2018-05-29 23:52:524313// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454314// even if alternative service destination is different.
4315TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344316 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304317 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524318 quic::QuicStreamOffset request_header_offset(0);
4319 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454320
rch5cb522462017-04-25 20:18:364321 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434322 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454323 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434324 mock_quic_data.AddWrite(
4325 SYNCHRONOUS,
4326 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334327 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434328 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4329 mock_quic_data.AddRead(
4330 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334331 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434332 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434333 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434334 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334335 ASYNC, ConstructServerDataPacket(
4336 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414337 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434338 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304339
bnc359ed2a2016-04-29 20:43:454340 // Second request.
alyssar2adf3ac2016-05-03 17:12:584341 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334342 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4343 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4344 true, GetRequestHeaders("GET", "https", "/"),
4345 GetNthClientInitiatedBidirectionalStreamId(0),
4346 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434347 mock_quic_data.AddRead(
4348 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334349 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434350 GetResponseHeaders("200 OK"), &response_header_offset));
4351 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334352 ASYNC, ConstructServerDataPacket(
4353 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414354 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434355 mock_quic_data.AddWrite(
4356 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304357 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4358 mock_quic_data.AddRead(ASYNC, 0); // EOF
4359
4360 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454361
4362 AddHangingNonAlternateProtocolSocketData();
4363 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304364
rch3f4b8452016-02-23 16:59:324365 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564366 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4367 QuicStreamFactoryPeer::SetAlarmFactory(
4368 session_->quic_stream_factory(),
4369 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4370 &clock_));
zhongyi32569c62016-01-08 02:54:304371
bnc359ed2a2016-04-29 20:43:454372 const char destination1[] = "first.example.com";
4373 const char destination2[] = "second.example.com";
4374
4375 // Set up alternative service entry to destination1.
4376 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214377 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454378 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214379 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444380 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454381 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524382 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454383 SendRequestAndExpectQuicResponse("hello!");
4384
4385 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214386 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214387 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444388 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524389 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454390 // even though alternative service destination is different.
4391 SendRequestAndExpectQuicResponse("hello!");
4392}
4393
4394// Pool to existing session with matching destination and matching certificate
4395// even if origin is different, and even if the alternative service with
4396// matching destination is not the first one on the list.
4397TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344398 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454399 GURL origin1 = request_.url;
4400 GURL origin2("https://www.example.org/");
4401 ASSERT_NE(origin1.host(), origin2.host());
4402
4403 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524404 quic::QuicStreamOffset request_header_offset(0);
4405 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454406
rch5cb522462017-04-25 20:18:364407 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434408 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454409 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434410 mock_quic_data.AddWrite(
4411 SYNCHRONOUS,
4412 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334413 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434414 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4415 mock_quic_data.AddRead(
4416 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334417 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434418 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434419 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434420 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334421 ASYNC, ConstructServerDataPacket(
4422 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414423 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434424 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454425
4426 // Second request.
Yixin Wang079ad542018-01-11 04:06:054427 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174428 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4429 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054430 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174431 QuicTestPacketMaker server_maker2(
4432 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4433 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584434 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434435 SYNCHRONOUS,
4436 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334437 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434438 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334439 GetNthClientInitiatedBidirectionalStreamId(0),
4440 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434441 mock_quic_data.AddRead(
4442 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334443 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434444 GetResponseHeaders("200 OK"), &response_header_offset));
4445 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334446 ASYNC, ConstructServerDataPacket(
4447 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414448 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434449 mock_quic_data.AddWrite(
4450 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454451 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4452 mock_quic_data.AddRead(ASYNC, 0); // EOF
4453
4454 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4455
4456 AddHangingNonAlternateProtocolSocketData();
4457 AddHangingNonAlternateProtocolSocketData();
4458
4459 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564460 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4461 QuicStreamFactoryPeer::SetAlarmFactory(
4462 session_->quic_stream_factory(),
4463 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4464 &clock_));
bnc359ed2a2016-04-29 20:43:454465
4466 const char destination1[] = "first.example.com";
4467 const char destination2[] = "second.example.com";
4468
4469 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214470 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454471 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214472 http_server_properties_.SetQuicAlternativeService(
4473 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444474 supported_versions_);
bnc359ed2a2016-04-29 20:43:454475
4476 // Set up multiple alternative service entries for |origin2|,
4477 // the first one with a different destination as for |origin1|,
4478 // the second one with the same. The second one should be used,
4479 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214480 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454481 AlternativeServiceInfoVector alternative_services;
4482 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214483 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4484 alternative_service2, expiration,
4485 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454486 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214487 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4488 alternative_service1, expiration,
4489 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454490 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4491 alternative_services);
bnc359ed2a2016-04-29 20:43:454492 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524493 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454494 SendRequestAndExpectQuicResponse("hello!");
4495
4496 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524497 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454498 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584499
bnc359ed2a2016-04-29 20:43:454500 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304501}
4502
4503// Multiple origins have listed the same alternative services. When there's a
4504// existing QUIC session opened by a request to other origin,
4505// if the cert is valid, should select this QUIC session to make the request
4506// if this is also the first existing QUIC session.
4507TEST_P(QuicNetworkTransactionTest,
4508 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344509 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294510 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304511
rch9ae5b3b2016-02-11 00:36:294512 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304513 MockRead http_reads[] = {
4514 MockRead("HTTP/1.1 200 OK\r\n"),
4515 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294516 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304517 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4518 MockRead(ASYNC, OK)};
4519
Ryan Sleevib8d7ea02018-05-07 20:01:014520 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304521 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084522 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304523 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4524
4525 // HTTP data for request to mail.example.org.
4526 MockRead http_reads2[] = {
4527 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294528 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304529 MockRead("hello world from mail.example.org"),
4530 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4531 MockRead(ASYNC, OK)};
4532
Ryan Sleevib8d7ea02018-05-07 20:01:014533 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304534 socket_factory_.AddSocketDataProvider(&http_data2);
4535 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4536
Ryan Hamilton8d9ee76e2018-05-29 23:52:524537 quic::QuicStreamOffset request_header_offset = 0;
4538 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304539
Yixin Wang079ad542018-01-11 04:06:054540 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174541 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4542 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054543 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584544 server_maker_.set_hostname("www.example.org");
4545 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304546 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364547 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434548 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304549 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584550 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434551 SYNCHRONOUS,
4552 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334553 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434554 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4555
4556 mock_quic_data.AddRead(
4557 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334558 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434559 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434560 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334561 mock_quic_data.AddRead(
4562 ASYNC, ConstructServerDataPacket(
4563 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414564 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434565 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4566 // Second QUIC request data.
4567 mock_quic_data.AddWrite(
4568 SYNCHRONOUS,
4569 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334570 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434571 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334572 GetNthClientInitiatedBidirectionalStreamId(0),
4573 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434574 mock_quic_data.AddRead(
4575 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334576 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434577 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334578 mock_quic_data.AddRead(
4579 ASYNC, ConstructServerDataPacket(
4580 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414581 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434582 mock_quic_data.AddWrite(
4583 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304584 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4585 mock_quic_data.AddRead(ASYNC, 0); // EOF
4586
4587 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304588
rtennetib8e80fb2016-05-16 00:12:094589 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324590 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564591 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4592 QuicStreamFactoryPeer::SetAlarmFactory(
4593 session_->quic_stream_factory(),
4594 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4595 &clock_));
zhongyi32569c62016-01-08 02:54:304596
4597 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294598 request_.url = GURL("https://www.example.org/");
4599 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304600 request_.url = GURL("https://mail.example.org/");
4601 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4602
rch9ae5b3b2016-02-11 00:36:294603 // Open a QUIC session to mail.example.org:443 when making request
4604 // to mail.example.org.
4605 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454606 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304607
rch9ae5b3b2016-02-11 00:36:294608 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304609 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454610 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524611}
4612
4613TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524614 MockRead http_reads[] = {
4615 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564616 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524617 MockRead("hello world"),
4618 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4619 MockRead(ASYNC, OK)};
4620
Ryan Sleevib8d7ea02018-05-07 20:01:014621 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524622 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084623 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564624 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524625
rtennetib8e80fb2016-05-16 00:12:094626 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324627 CreateSession();
bncc958faa2015-07-31 18:14:524628
4629 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454630
4631 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344632 AlternativeServiceInfoVector alternative_service_info_vector =
4633 http_server_properties_.GetAlternativeServiceInfos(http_server);
4634 ASSERT_EQ(1u, alternative_service_info_vector.size());
4635 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544636 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344637 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4638 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4639 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524640}
4641
4642TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524643 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564644 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4645 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524646 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4647 MockRead(ASYNC, OK)};
4648
Ryan Sleevib8d7ea02018-05-07 20:01:014649 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524650 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084651 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564652 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524653
4654 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524655 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364656 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434657 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4658 mock_quic_data.AddWrite(
4659 SYNCHRONOUS,
4660 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334661 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434662 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434663 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334664 ASYNC, ConstructServerResponseHeadersPacket(
4665 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4666 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434667 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334668 mock_quic_data.AddRead(
4669 ASYNC, ConstructServerDataPacket(
4670 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414671 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434672 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524673 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4674 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524675
4676 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4677
rtennetib8e80fb2016-05-16 00:12:094678 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324679 CreateSession();
bncc958faa2015-07-31 18:14:524680
bnc3472afd2016-11-17 15:27:214681 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524682 HostPortPair::FromURL(request_.url));
4683 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4684 alternative_service);
4685 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4686 alternative_service));
4687
4688 SendRequestAndExpectHttpResponse("hello world");
4689 SendRequestAndExpectQuicResponse("hello!");
4690
mmenkee24011922015-12-17 22:12:594691 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524692
4693 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4694 alternative_service));
rchac7f35e2017-03-15 20:42:304695 EXPECT_NE(nullptr,
4696 http_server_properties_.GetServerNetworkStats(
4697 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524698}
4699
bncc958faa2015-07-31 18:14:524700TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524701 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564702 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4703 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524704 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4705 MockRead(ASYNC, OK)};
4706
Ryan Sleevib8d7ea02018-05-07 20:01:014707 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524708 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564709 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524710
4711 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524712 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364713 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434714 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4715 mock_quic_data.AddWrite(
4716 SYNCHRONOUS,
4717 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334718 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434719 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434720 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334721 ASYNC, ConstructServerResponseHeadersPacket(
4722 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4723 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434724 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334725 mock_quic_data.AddRead(
4726 ASYNC, ConstructServerDataPacket(
4727 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414728 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434729 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524730 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4731
4732 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4733
4734 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324735 CreateSession();
bncc958faa2015-07-31 18:14:524736
4737 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4738 SendRequestAndExpectHttpResponse("hello world");
4739}
4740
tbansalc3308d72016-08-27 10:25:044741// Tests that the connection to an HTTPS proxy is raced with an available
4742// alternative proxy server.
4743TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274744 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594745 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494746 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044747
4748 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524749 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364750 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434751 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4752 mock_quic_data.AddWrite(
4753 SYNCHRONOUS,
4754 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334755 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434756 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434757 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334758 ASYNC, ConstructServerResponseHeadersPacket(
4759 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4760 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434761 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334762 mock_quic_data.AddRead(
4763 ASYNC, ConstructServerDataPacket(
4764 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414765 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434766 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044767 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4768 mock_quic_data.AddRead(ASYNC, 0); // EOF
4769
4770 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4771
4772 // There is no need to set up main job, because no attempt will be made to
4773 // speak to the proxy over TCP.
4774 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044775 TestProxyDelegate test_proxy_delegate;
4776 const HostPortPair host_port_pair("mail.example.org", 443);
4777
4778 test_proxy_delegate.set_alternative_proxy_server(
4779 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524780 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044781 CreateSession();
4782 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4783
4784 // The main job needs to hang in order to guarantee that the alternative
4785 // proxy server job will "win".
4786 AddHangingNonAlternateProtocolSocketData();
4787
4788 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4789
4790 // Verify that the alternative proxy server is not marked as broken.
4791 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4792
4793 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594794 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274795
4796 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4797 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4798 1);
tbansalc3308d72016-08-27 10:25:044799}
4800
bnc1c196c6e2016-05-28 13:51:484801TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304802 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274803 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304804
4805 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564806 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294807 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564808 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304809
4810 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564811 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484812 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564813 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304814
Ryan Sleevib8d7ea02018-05-07 20:01:014815 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504816 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084817 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504818 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304819
4820 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454821 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304822 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454823 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304824 };
Ryan Sleevib8d7ea02018-05-07 20:01:014825 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504826 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304827
4828 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014829 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504830 socket_factory_.AddSocketDataProvider(&http_data2);
4831 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304832
bnc912a04b2016-04-20 14:19:504833 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304834
4835 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304836 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174837 ASSERT_TRUE(http_data.AllReadDataConsumed());
4838 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304839
4840 // Now run the second request in which the QUIC socket hangs,
4841 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304842 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454843 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304844
rch37de576c2015-05-17 20:28:174845 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4846 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454847 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304848}
4849
[email protected]1e960032013-12-20 19:00:204850TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204851 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524852 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:034853 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434854 mock_quic_data.AddWrite(
4855 SYNCHRONOUS,
4856 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334857 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434858 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434859 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334860 ASYNC, ConstructServerResponseHeadersPacket(
4861 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4862 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434863 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334864 mock_quic_data.AddRead(
4865 ASYNC, ConstructServerDataPacket(
4866 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414867 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434868 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504869 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594870 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484871
rcha5399e02015-04-21 19:32:044872 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484873
rtennetib8e80fb2016-05-16 00:12:094874 // The non-alternate protocol job needs to hang in order to guarantee that
4875 // the alternate-protocol job will "win".
4876 AddHangingNonAlternateProtocolSocketData();
4877
rch3f4b8452016-02-23 16:59:324878 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274879 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194880 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304881
4882 EXPECT_EQ(nullptr,
4883 http_server_properties_.GetServerNetworkStats(
4884 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484885}
4886
[email protected]1e960032013-12-20 19:00:204887TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204888 MockQuicData mock_quic_data;
Michael Warres167db3e2019-03-01 21:38:034889 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334890 mock_quic_data.AddWrite(
4891 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4892 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4893 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434894 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334895 ASYNC, ConstructServerResponseHeadersPacket(
4896 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4897 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434898 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334899 mock_quic_data.AddRead(
4900 ASYNC, ConstructServerDataPacket(
4901 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414902 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434903 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504904 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594905 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044906 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274907
4908 // In order for a new QUIC session to be established via alternate-protocol
4909 // without racing an HTTP connection, we need the host resolution to happen
4910 // synchronously.
4911 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294912 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564913 "");
[email protected]3a120a6b2013-06-25 01:08:274914
rtennetib8e80fb2016-05-16 00:12:094915 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324916 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274917 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274918 SendRequestAndExpectQuicResponse("hello!");
4919}
4920
[email protected]0fc924b2014-03-31 04:34:154921TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494922 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4923 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154924
4925 // Since we are using a proxy, the QUIC job will not succeed.
4926 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294927 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4928 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564929 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154930
4931 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564932 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484933 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564934 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154935
Ryan Sleevib8d7ea02018-05-07 20:01:014936 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154937 socket_factory_.AddSocketDataProvider(&http_data);
4938
4939 // In order for a new QUIC session to be established via alternate-protocol
4940 // without racing an HTTP connection, we need the host resolution to happen
4941 // synchronously.
4942 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294943 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564944 "");
[email protected]0fc924b2014-03-31 04:34:154945
rch9ae5b3b2016-02-11 00:36:294946 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324947 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274948 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154949 SendRequestAndExpectHttpResponse("hello world");
4950}
4951
[email protected]1e960032013-12-20 19:00:204952TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204953 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524954 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364955 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434956 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4957 mock_quic_data.AddWrite(
4958 SYNCHRONOUS,
4959 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334960 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434961 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434962 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334963 ASYNC, ConstructServerResponseHeadersPacket(
4964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4965 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434966 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334967 mock_quic_data.AddRead(
4968 ASYNC, ConstructServerDataPacket(
4969 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414970 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434971 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594972 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044973 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124974
rtennetib8e80fb2016-05-16 00:12:094975 // The non-alternate protocol job needs to hang in order to guarantee that
4976 // the alternate-protocol job will "win".
4977 AddHangingNonAlternateProtocolSocketData();
4978
[email protected]11c05872013-08-20 02:04:124979 // In order for a new QUIC session to be established via alternate-protocol
4980 // without racing an HTTP connection, we need the host resolution to happen
4981 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4982 // connection to the the server, in this test we require confirmation
4983 // before encrypting so the HTTP job will still start.
4984 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294985 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564986 "");
[email protected]11c05872013-08-20 02:04:124987
rch3f4b8452016-02-23 16:59:324988 CreateSession();
[email protected]11c05872013-08-20 02:04:124989 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274990 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124991
bnc691fda62016-08-12 00:43:164992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124993 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364994 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124996
4997 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524998 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014999 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505000
bnc691fda62016-08-12 00:43:165001 CheckWasQuicResponse(&trans);
5002 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125003}
5004
Steven Valdez58097ec32018-07-16 18:29:045005TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5006 MockQuicData mock_quic_data;
5007 quic::QuicStreamOffset client_header_stream_offset = 0;
5008 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035009 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045010 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335011 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5012 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5013 true, GetRequestHeaders("GET", "https", "/"),
5014 &client_header_stream_offset));
5015 mock_quic_data.AddRead(
5016 ASYNC,
5017 ConstructServerResponseHeadersPacket(
5018 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5019 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5020 mock_quic_data.AddWrite(SYNCHRONOUS,
5021 ConstructClientAckAndRstPacket(
5022 2, GetNthClientInitiatedBidirectionalStreamId(0),
5023 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045024
5025 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5026
5027 spdy::SpdySettingsIR settings_frame;
5028 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5029 quic::kDefaultMaxUncompressedHeaderSize);
5030 spdy::SpdySerializedFrame spdy_frame(
5031 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5032 mock_quic_data.AddWrite(
5033 SYNCHRONOUS,
5034 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385035 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5036 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045037 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5038 client_header_stream_offset += spdy_frame.size();
5039
5040 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335041 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5042 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5043 true, GetRequestHeaders("GET", "https", "/"),
5044 GetNthClientInitiatedBidirectionalStreamId(0),
5045 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045046 mock_quic_data.AddRead(
5047 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335048 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045049 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:435050 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045051 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335052 ASYNC, ConstructServerDataPacket(
5053 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415054 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045055 mock_quic_data.AddWrite(
5056 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5057 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5058 mock_quic_data.AddRead(ASYNC, 0); // EOF
5059
5060 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5061
5062 // In order for a new QUIC session to be established via alternate-protocol
5063 // without racing an HTTP connection, we need the host resolution to happen
5064 // synchronously.
5065 host_resolver_.set_synchronous_mode(true);
5066 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5067 "");
Steven Valdez58097ec32018-07-16 18:29:045068
5069 AddHangingNonAlternateProtocolSocketData();
5070 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275071 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565072 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5073 QuicStreamFactoryPeer::SetAlarmFactory(
5074 session_->quic_stream_factory(),
5075 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5076 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045077
5078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5079 TestCompletionCallback callback;
5080 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5081 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5082
5083 // Confirm the handshake after the 425 Too Early.
5084 base::RunLoop().RunUntilIdle();
5085
5086 // The handshake hasn't been confirmed yet, so the retry should not have
5087 // succeeded.
5088 EXPECT_FALSE(callback.have_result());
5089
5090 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5091 quic::QuicSession::HANDSHAKE_CONFIRMED);
5092
5093 EXPECT_THAT(callback.WaitForResult(), IsOk());
5094 CheckWasQuicResponse(&trans);
5095 CheckResponseData(&trans, "hello!");
5096}
5097
5098TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5099 MockQuicData mock_quic_data;
5100 quic::QuicStreamOffset client_header_stream_offset = 0;
5101 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035102 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045103 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335104 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5105 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5106 true, GetRequestHeaders("GET", "https", "/"),
5107 &client_header_stream_offset));
5108 mock_quic_data.AddRead(
5109 ASYNC,
5110 ConstructServerResponseHeadersPacket(
5111 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5112 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5113 mock_quic_data.AddWrite(SYNCHRONOUS,
5114 ConstructClientAckAndRstPacket(
5115 2, GetNthClientInitiatedBidirectionalStreamId(0),
5116 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045117
5118 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5119
5120 spdy::SpdySettingsIR settings_frame;
5121 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5122 quic::kDefaultMaxUncompressedHeaderSize);
5123 spdy::SpdySerializedFrame spdy_frame(
5124 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5125 mock_quic_data.AddWrite(
5126 SYNCHRONOUS,
5127 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385128 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5129 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045130 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5131 client_header_stream_offset += spdy_frame.size();
5132
5133 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335134 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5135 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5136 true, GetRequestHeaders("GET", "https", "/"),
5137 GetNthClientInitiatedBidirectionalStreamId(0),
5138 &client_header_stream_offset));
5139 mock_quic_data.AddRead(
5140 ASYNC,
5141 ConstructServerResponseHeadersPacket(
5142 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5143 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5144 mock_quic_data.AddWrite(SYNCHRONOUS,
5145 ConstructClientAckAndRstPacket(
5146 5, GetNthClientInitiatedBidirectionalStreamId(1),
5147 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045148 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5149 mock_quic_data.AddRead(ASYNC, 0); // EOF
5150
5151 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5152
5153 // In order for a new QUIC session to be established via alternate-protocol
5154 // without racing an HTTP connection, we need the host resolution to happen
5155 // synchronously.
5156 host_resolver_.set_synchronous_mode(true);
5157 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5158 "");
Steven Valdez58097ec32018-07-16 18:29:045159
5160 AddHangingNonAlternateProtocolSocketData();
5161 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275162 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565163 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5164 QuicStreamFactoryPeer::SetAlarmFactory(
5165 session_->quic_stream_factory(),
5166 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5167 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045168
5169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5170 TestCompletionCallback callback;
5171 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5173
5174 // Confirm the handshake after the 425 Too Early.
5175 base::RunLoop().RunUntilIdle();
5176
5177 // The handshake hasn't been confirmed yet, so the retry should not have
5178 // succeeded.
5179 EXPECT_FALSE(callback.have_result());
5180
5181 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5182 quic::QuicSession::HANDSHAKE_CONFIRMED);
5183
5184 EXPECT_THAT(callback.WaitForResult(), IsOk());
5185 const HttpResponseInfo* response = trans.GetResponseInfo();
5186 ASSERT_TRUE(response != nullptr);
5187 ASSERT_TRUE(response->headers.get() != nullptr);
5188 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5189 EXPECT_TRUE(response->was_fetched_via_spdy);
5190 EXPECT_TRUE(response->was_alpn_negotiated);
5191 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5192 response->connection_info);
5193}
5194
zhongyica364fbb2015-12-12 03:39:125195TEST_P(QuicNetworkTransactionTest,
5196 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485197 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125198 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525199 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365200 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435201 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5202 mock_quic_data.AddWrite(
5203 SYNCHRONOUS,
5204 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335205 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435206 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125207 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525208 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435209 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125210 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5211
5212 // The non-alternate protocol job needs to hang in order to guarantee that
5213 // the alternate-protocol job will "win".
5214 AddHangingNonAlternateProtocolSocketData();
5215
5216 // In order for a new QUIC session to be established via alternate-protocol
5217 // without racing an HTTP connection, we need the host resolution to happen
5218 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5219 // connection to the the server, in this test we require confirmation
5220 // before encrypting so the HTTP job will still start.
5221 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295222 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125223 "");
zhongyica364fbb2015-12-12 03:39:125224
rch3f4b8452016-02-23 16:59:325225 CreateSession();
zhongyica364fbb2015-12-12 03:39:125226 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275227 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125228
bnc691fda62016-08-12 00:43:165229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125230 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365231 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125233
5234 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525235 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015236 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125237
5238 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525239 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125240
bnc691fda62016-08-12 00:43:165241 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125242 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525243 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5244 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125245}
5246
5247TEST_P(QuicNetworkTransactionTest,
5248 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485249 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125250 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525251 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365252 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435253 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5254 mock_quic_data.AddWrite(
5255 SYNCHRONOUS,
5256 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335257 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435258 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215259 // Peer sending data from an non-existing stream causes this end to raise
5260 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335261 mock_quic_data.AddRead(
5262 ASYNC, ConstructServerRstPacket(
5263 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5264 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215265 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525266 mock_quic_data.AddWrite(
5267 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5268 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5269 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125270 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5271
5272 // The non-alternate protocol job needs to hang in order to guarantee that
5273 // the alternate-protocol job will "win".
5274 AddHangingNonAlternateProtocolSocketData();
5275
5276 // In order for a new QUIC session to be established via alternate-protocol
5277 // without racing an HTTP connection, we need the host resolution to happen
5278 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5279 // connection to the the server, in this test we require confirmation
5280 // before encrypting so the HTTP job will still start.
5281 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295282 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125283 "");
zhongyica364fbb2015-12-12 03:39:125284
rch3f4b8452016-02-23 16:59:325285 CreateSession();
zhongyica364fbb2015-12-12 03:39:125286 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275287 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125288
bnc691fda62016-08-12 00:43:165289 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125290 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365291 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125293
5294 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525295 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015296 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125297 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525298 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125299
bnc691fda62016-08-12 00:43:165300 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525301 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125302}
5303
rchcd5f1c62016-06-23 02:43:485304TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5305 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525306 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365307 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435308 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5309 mock_quic_data.AddWrite(
5310 SYNCHRONOUS,
5311 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335312 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435313 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485314 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335315 mock_quic_data.AddRead(
5316 ASYNC, ConstructServerResponseHeadersPacket(
5317 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5318 GetResponseHeaders("200 OK")));
5319 mock_quic_data.AddRead(
5320 ASYNC, ConstructServerRstPacket(
5321 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5322 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435323 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485324 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5325 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5326
5327 // The non-alternate protocol job needs to hang in order to guarantee that
5328 // the alternate-protocol job will "win".
5329 AddHangingNonAlternateProtocolSocketData();
5330
5331 // In order for a new QUIC session to be established via alternate-protocol
5332 // without racing an HTTP connection, we need the host resolution to happen
5333 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5334 // connection to the the server, in this test we require confirmation
5335 // before encrypting so the HTTP job will still start.
5336 host_resolver_.set_synchronous_mode(true);
5337 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5338 "");
rchcd5f1c62016-06-23 02:43:485339
5340 CreateSession();
5341 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275342 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485343
bnc691fda62016-08-12 00:43:165344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485345 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365346 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485348
5349 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525350 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485351 // Read the headers.
robpercival214763f2016-07-01 23:27:015352 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485353
bnc691fda62016-08-12 00:43:165354 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485355 ASSERT_TRUE(response != nullptr);
5356 ASSERT_TRUE(response->headers.get() != nullptr);
5357 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5358 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525359 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445360 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5361 response->connection_info);
rchcd5f1c62016-06-23 02:43:485362
5363 std::string response_data;
bnc691fda62016-08-12 00:43:165364 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485365}
5366
5367TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485368 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485369 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525370 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365371 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435372 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5373 mock_quic_data.AddWrite(
5374 SYNCHRONOUS,
5375 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335376 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435377 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335378 mock_quic_data.AddRead(
5379 ASYNC, ConstructServerRstPacket(
5380 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5381 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485382 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5383 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5384
5385 // The non-alternate protocol job needs to hang in order to guarantee that
5386 // the alternate-protocol job will "win".
5387 AddHangingNonAlternateProtocolSocketData();
5388
5389 // In order for a new QUIC session to be established via alternate-protocol
5390 // without racing an HTTP connection, we need the host resolution to happen
5391 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5392 // connection to the the server, in this test we require confirmation
5393 // before encrypting so the HTTP job will still start.
5394 host_resolver_.set_synchronous_mode(true);
5395 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5396 "");
rchcd5f1c62016-06-23 02:43:485397
5398 CreateSession();
5399 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275400 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485401
bnc691fda62016-08-12 00:43:165402 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485403 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365404 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015405 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485406
5407 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525408 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485409 // Read the headers.
robpercival214763f2016-07-01 23:27:015410 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485411}
5412
[email protected]1e960032013-12-20 19:00:205413TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305414 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525415 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585416 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305417 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505418 MockRead(ASYNC, close->data(), close->length()),
5419 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5420 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305421 };
Ryan Sleevib8d7ea02018-05-07 20:01:015422 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305423 socket_factory_.AddSocketDataProvider(&quic_data);
5424
5425 // Main job which will succeed even though the alternate job fails.
5426 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025427 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5428 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5429 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305430
Ryan Sleevib8d7ea02018-05-07 20:01:015431 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305432 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565433 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305434
rch3f4b8452016-02-23 16:59:325435 CreateSession();
David Schinazic8281052019-01-24 06:14:175436 AddQuicAlternateProtocolMapping(
5437 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195438 SendRequestAndExpectHttpResponse("hello from http");
5439 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305440}
5441
[email protected]1e960032013-12-20 19:00:205442TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595443 // Alternate-protocol job
5444 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025445 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595446 };
Ryan Sleevib8d7ea02018-05-07 20:01:015447 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595448 socket_factory_.AddSocketDataProvider(&quic_data);
5449
5450 // Main job which will succeed even though the alternate job fails.
5451 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025452 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5453 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5454 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595455
Ryan Sleevib8d7ea02018-05-07 20:01:015456 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595457 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565458 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595459
rch3f4b8452016-02-23 16:59:325460 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595461
Ryan Hamilton9835e662018-08-02 05:36:275462 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195463 SendRequestAndExpectHttpResponse("hello from http");
5464 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595465}
5466
[email protected]00c159f2014-05-21 22:38:165467TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535468 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165469 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025470 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165471 };
Ryan Sleevib8d7ea02018-05-07 20:01:015472 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165473 socket_factory_.AddSocketDataProvider(&quic_data);
5474
[email protected]eb71ab62014-05-23 07:57:535475 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165476 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025477 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165478 };
5479
Ryan Sleevib8d7ea02018-05-07 20:01:015480 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165481 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5482 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565483 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165484
rtennetib8e80fb2016-05-16 00:12:095485 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325486 CreateSession();
[email protected]00c159f2014-05-21 22:38:165487
Ryan Hamilton9835e662018-08-02 05:36:275488 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165489 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165490 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165491 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015492 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5493 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165494 ExpectQuicAlternateProtocolMapping();
5495}
5496
Zhongyi Shia0cef1082017-08-25 01:49:505497TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5498 // Tests that TCP job is delayed and QUIC job does not require confirmation
5499 // if QUIC was recently supported on the same IP on start.
5500
5501 // Set QUIC support on the last IP address, which is same with the local IP
5502 // address. Require confirmation mode will be turned off immediately when
5503 // local IP address is sorted out after we configure the UDP socket.
5504 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5505
5506 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525507 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035508 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435509 mock_quic_data.AddWrite(
5510 SYNCHRONOUS,
5511 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335512 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435513 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435514 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335515 ASYNC, ConstructServerResponseHeadersPacket(
5516 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5517 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435518 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335519 mock_quic_data.AddRead(
5520 ASYNC, ConstructServerDataPacket(
5521 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415522 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435523 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505524 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5525 mock_quic_data.AddRead(ASYNC, 0); // EOF
5526
5527 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5528 // No HTTP data is mocked as TCP job never starts in this case.
5529
5530 CreateSession();
5531 // QuicStreamFactory by default requires confirmation on construction.
5532 session_->quic_stream_factory()->set_require_confirmation(true);
5533
Ryan Hamilton9835e662018-08-02 05:36:275534 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505535
5536 // Stall host resolution so that QUIC job will not succeed synchronously.
5537 // Socket will not be configured immediately and QUIC support is not sorted
5538 // out, TCP job will still be delayed as server properties indicates QUIC
5539 // support on last IP address.
5540 host_resolver_.set_synchronous_mode(false);
5541
5542 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5543 TestCompletionCallback callback;
5544 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5545 IsError(ERR_IO_PENDING));
5546 // Complete host resolution in next message loop so that QUIC job could
5547 // proceed.
5548 base::RunLoop().RunUntilIdle();
5549 EXPECT_THAT(callback.WaitForResult(), IsOk());
5550
5551 CheckWasQuicResponse(&trans);
5552 CheckResponseData(&trans, "hello!");
5553}
5554
5555TEST_P(QuicNetworkTransactionTest,
5556 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5557 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5558 // was recently supported on a different IP address on start.
5559
5560 // Set QUIC support on the last IP address, which is different with the local
5561 // IP address. Require confirmation mode will remain when local IP address is
5562 // sorted out after we configure the UDP socket.
5563 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5564
5565 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525566 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505567 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435568 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5569 mock_quic_data.AddWrite(
5570 SYNCHRONOUS,
5571 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335572 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435573 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435574 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335575 ASYNC, ConstructServerResponseHeadersPacket(
5576 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5577 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435578 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335579 mock_quic_data.AddRead(
5580 ASYNC, ConstructServerDataPacket(
5581 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415582 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435583 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505584 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5585 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5586 // No HTTP data is mocked as TCP job will be delayed and never starts.
5587
5588 CreateSession();
5589 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275590 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505591
5592 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5593 // Socket will not be configured immediately and QUIC support is not sorted
5594 // out, TCP job will still be delayed as server properties indicates QUIC
5595 // support on last IP address.
5596 host_resolver_.set_synchronous_mode(false);
5597
5598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5599 TestCompletionCallback callback;
5600 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5601 IsError(ERR_IO_PENDING));
5602
5603 // Complete host resolution in next message loop so that QUIC job could
5604 // proceed.
5605 base::RunLoop().RunUntilIdle();
5606 // Explicitly confirm the handshake so that QUIC job could succeed.
5607 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525608 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505609 EXPECT_THAT(callback.WaitForResult(), IsOk());
5610
5611 CheckWasQuicResponse(&trans);
5612 CheckResponseData(&trans, "hello!");
5613}
5614
Ryan Hamilton75f197262017-08-17 14:00:075615TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5616 // Test that NetErrorDetails is correctly populated, even if the
5617 // handshake has not yet been confirmed and no stream has been created.
5618
5619 // QUIC job will pause. When resumed, it will fail.
5620 MockQuicData mock_quic_data;
5621 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5622 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5623 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5624
5625 // Main job will also fail.
5626 MockRead http_reads[] = {
5627 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5628 };
5629
Ryan Sleevib8d7ea02018-05-07 20:01:015630 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075631 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5632 socket_factory_.AddSocketDataProvider(&http_data);
5633 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5634
5635 AddHangingNonAlternateProtocolSocketData();
5636 CreateSession();
5637 // Require handshake confirmation to ensure that no QUIC streams are
5638 // created, and to ensure that the TCP job does not wait for the QUIC
5639 // job to fail before it starts.
5640 session_->quic_stream_factory()->set_require_confirmation(true);
5641
Ryan Hamilton9835e662018-08-02 05:36:275642 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5644 TestCompletionCallback callback;
5645 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5647 // Allow the TCP job to fail.
5648 base::RunLoop().RunUntilIdle();
5649 // Now let the QUIC job fail.
5650 mock_quic_data.Resume();
5651 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5652 ExpectQuicAlternateProtocolMapping();
5653 NetErrorDetails details;
5654 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525655 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075656}
5657
[email protected]1e960032013-12-20 19:00:205658TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455659 // Alternate-protocol job
5660 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025661 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455662 };
Ryan Sleevib8d7ea02018-05-07 20:01:015663 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455664 socket_factory_.AddSocketDataProvider(&quic_data);
5665
[email protected]c92c1b52014-05-31 04:16:065666 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015667 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065668 socket_factory_.AddSocketDataProvider(&quic_data2);
5669
[email protected]4d283b32013-10-17 12:57:275670 // Final job that will proceed when the QUIC job fails.
5671 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025672 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5673 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5674 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275675
Ryan Sleevib8d7ea02018-05-07 20:01:015676 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275677 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565678 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275679
rtennetiafccbc062016-05-16 18:21:145680 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325681 CreateSession();
[email protected]77c6c162013-08-17 02:57:455682
Ryan Hamilton9835e662018-08-02 05:36:275683 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455684
[email protected]4d283b32013-10-17 12:57:275685 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455686
5687 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275688
rch37de576c2015-05-17 20:28:175689 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5690 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455691}
5692
[email protected]93b31772014-06-19 08:03:355693TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035694 // Alternate-protocol job
5695 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595696 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035697 };
Ryan Sleevib8d7ea02018-05-07 20:01:015698 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035699 socket_factory_.AddSocketDataProvider(&quic_data);
5700
5701 // Main job that will proceed when the QUIC job fails.
5702 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025703 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5704 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5705 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035706
Ryan Sleevib8d7ea02018-05-07 20:01:015707 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035708 socket_factory_.AddSocketDataProvider(&http_data);
5709
rtennetib8e80fb2016-05-16 00:12:095710 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325711 CreateSession();
[email protected]65768442014-06-06 23:37:035712
Ryan Hamilton9835e662018-08-02 05:36:275713 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035714
5715 SendRequestAndExpectHttpResponse("hello from http");
5716}
5717
[email protected]eb71ab62014-05-23 07:57:535718TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335719 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015720 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495721 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335722 socket_factory_.AddSocketDataProvider(&quic_data);
5723
5724 // Main job which will succeed even though the alternate job fails.
5725 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025726 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5727 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5728 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335729
Ryan Sleevib8d7ea02018-05-07 20:01:015730 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335731 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565732 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335733
rch3f4b8452016-02-23 16:59:325734 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275735 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335736 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535737
5738 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335739}
5740
[email protected]4fee9672014-01-08 14:47:155741TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Michael Warres167db3e2019-03-01 21:38:035742 if (version_ >= quic::QUIC_VERSION_47) {
5743 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
5744 return;
5745 }
[email protected]4fee9672014-01-08 14:47:155746 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175747 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5748 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045749 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155750
5751 // When the QUIC connection fails, we will try the request again over HTTP.
5752 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485753 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565754 MockRead("hello world"),
5755 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5756 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155757
Ryan Sleevib8d7ea02018-05-07 20:01:015758 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155759 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565760 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155761
5762 // In order for a new QUIC session to be established via alternate-protocol
5763 // without racing an HTTP connection, we need the host resolution to happen
5764 // synchronously.
5765 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295766 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565767 "");
[email protected]4fee9672014-01-08 14:47:155768
rch3f4b8452016-02-23 16:59:325769 CreateSession();
David Schinazic8281052019-01-24 06:14:175770 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5771 AddQuicAlternateProtocolMapping(
5772 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155773 SendRequestAndExpectHttpResponse("hello world");
5774}
5775
tbansalc3308d72016-08-27 10:25:045776// For an alternative proxy that supports QUIC, test that the request is
5777// successfully fetched by the main job when the alternate proxy job encounters
5778// an error.
5779TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5780 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5781}
5782TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5783 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5784}
5785TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5786 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5787}
5788TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5789 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5790}
5791TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5792 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5793}
5794TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5795 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5796}
5797TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5798 TestAlternativeProxy(ERR_IO_PENDING);
5799}
5800TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5801 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5802}
5803
5804TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5805 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175806 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5807 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335808 mock_quic_data.AddWrite(
5809 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5810 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5811 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435812 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045813 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5814
5815 // When the QUIC connection fails, we will try the request again over HTTP.
5816 MockRead http_reads[] = {
5817 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5818 MockRead("hello world"),
5819 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5820 MockRead(ASYNC, OK)};
5821
Ryan Sleevib8d7ea02018-05-07 20:01:015822 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045823 socket_factory_.AddSocketDataProvider(&http_data);
5824 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5825
5826 TestProxyDelegate test_proxy_delegate;
5827 const HostPortPair host_port_pair("myproxy.org", 443);
5828 test_proxy_delegate.set_alternative_proxy_server(
5829 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5830 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5831
Ramin Halavatica8d5252018-03-12 05:33:495832 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5833 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525834 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045835 request_.url = GURL("http://mail.example.org/");
5836
5837 // In order for a new QUIC session to be established via alternate-protocol
5838 // without racing an HTTP connection, we need the host resolution to happen
5839 // synchronously.
5840 host_resolver_.set_synchronous_mode(true);
5841 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045842
5843 CreateSession();
David Schinazic8281052019-01-24 06:14:175844 crypto_client_stream_factory_.set_handshake_mode(
5845 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045846 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595847 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165848 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045849}
5850
bnc508835902015-05-12 20:10:295851TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585852 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385853 EXPECT_FALSE(
5854 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295855 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525856 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365857 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435858 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5859 mock_quic_data.AddWrite(
5860 SYNCHRONOUS,
5861 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335862 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435863 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435864 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335865 ASYNC, ConstructServerResponseHeadersPacket(
5866 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5867 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435868 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335869 mock_quic_data.AddRead(
5870 ASYNC, ConstructServerDataPacket(
5871 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415872 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435873 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505874 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295875 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5876
bncb07c05532015-05-14 19:07:205877 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095878 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325879 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275880 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295881 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385882 EXPECT_TRUE(
5883 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295884}
5885
zhongyi363c91c2017-03-23 23:16:085886// TODO(zhongyi): disabled this broken test as it was not testing the correct
5887// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5888TEST_P(QuicNetworkTransactionTest,
5889 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275890 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595891 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495892 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045893
5894 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045895
5896 test_proxy_delegate.set_alternative_proxy_server(
5897 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525898 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045899
5900 request_.url = GURL("http://mail.example.org/");
5901
5902 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5903 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015904 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045905 socket_factory_.AddSocketDataProvider(&socket_data);
5906
5907 // The non-alternate protocol job needs to hang in order to guarantee that
5908 // the alternate-protocol job will "win".
5909 AddHangingNonAlternateProtocolSocketData();
5910
5911 CreateSession();
5912 request_.method = "POST";
5913 ChunkedUploadDataStream upload_data(0);
5914 upload_data.AppendData("1", 1, true);
5915
5916 request_.upload_data_stream = &upload_data;
5917
5918 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5919 TestCompletionCallback callback;
5920 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5921 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5922 EXPECT_NE(OK, callback.WaitForResult());
5923
5924 // Verify that the alternative proxy server is not marked as broken.
5925 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5926
5927 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595928 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275929
5930 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5931 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5932 1);
tbansalc3308d72016-08-27 10:25:045933}
5934
rtenneti56977812016-01-15 19:26:565935TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415936 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575937 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565938
5939 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5940 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015941 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565942 socket_factory_.AddSocketDataProvider(&socket_data);
5943
rtennetib8e80fb2016-05-16 00:12:095944 // The non-alternate protocol job needs to hang in order to guarantee that
5945 // the alternate-protocol job will "win".
5946 AddHangingNonAlternateProtocolSocketData();
5947
rtenneti56977812016-01-15 19:26:565948 CreateSession();
5949 request_.method = "POST";
5950 ChunkedUploadDataStream upload_data(0);
5951 upload_data.AppendData("1", 1, true);
5952
5953 request_.upload_data_stream = &upload_data;
5954
bnc691fda62016-08-12 00:43:165955 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565956 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165957 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565959 EXPECT_NE(OK, callback.WaitForResult());
5960}
5961
rche11300ef2016-09-02 01:44:285962TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485963 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285964 ScopedMockNetworkChangeNotifier network_change_notifier;
5965 MockNetworkChangeNotifier* mock_ncn =
5966 network_change_notifier.mock_network_change_notifier();
5967 mock_ncn->ForceNetworkHandlesSupported();
5968 mock_ncn->SetConnectedNetworksList(
5969 {kDefaultNetworkForTests, kNewNetworkForTests});
5970
mmenke6ddfbea2017-05-31 21:48:415971 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285972 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315973 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285974
5975 MockQuicData socket_data;
5976 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525977 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435978 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:335979 socket_data.AddWrite(
5980 SYNCHRONOUS,
5981 ConstructClientRequestHeadersPacket(
5982 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
5983 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:285984 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5985 socket_data.AddSocketDataToFactory(&socket_factory_);
5986
5987 MockQuicData socket_data2;
5988 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5989 socket_data2.AddSocketDataToFactory(&socket_factory_);
5990
5991 // The non-alternate protocol job needs to hang in order to guarantee that
5992 // the alternate-protocol job will "win".
5993 AddHangingNonAlternateProtocolSocketData();
5994
5995 CreateSession();
5996 request_.method = "POST";
5997 ChunkedUploadDataStream upload_data(0);
5998
5999 request_.upload_data_stream = &upload_data;
6000
rdsmith1d343be52016-10-21 20:37:506001 std::unique_ptr<HttpNetworkTransaction> trans(
6002 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286003 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506004 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6006
6007 base::RunLoop().RunUntilIdle();
6008 upload_data.AppendData("1", 1, true);
6009 base::RunLoop().RunUntilIdle();
6010
6011 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506012 trans.reset();
rche11300ef2016-09-02 01:44:286013 session_.reset();
6014}
6015
Ryan Hamilton4b3574532017-10-30 20:17:256016TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6017 session_params_.origins_to_force_quic_on.insert(
6018 HostPortPair::FromString("mail.example.org:443"));
6019
6020 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526021 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436022 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256023 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336024 socket_data.AddWrite(
6025 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6026 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6027 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436028 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336029 ASYNC, ConstructServerResponseHeadersPacket(
6030 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6031 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436032 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336033 socket_data.AddRead(
6034 ASYNC, ConstructServerDataPacket(
6035 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416036 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436037 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256038 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166039 socket_data.AddWrite(
6040 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6041 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6042 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256043
6044 socket_data.AddSocketDataToFactory(&socket_factory_);
6045
6046 CreateSession();
6047
6048 SendRequestAndExpectQuicResponse("hello!");
6049 session_.reset();
6050}
6051
6052TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6053 session_params_.origins_to_force_quic_on.insert(
6054 HostPortPair::FromString("mail.example.org:443"));
6055
6056 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526057 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436058 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256059 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336060 socket_data.AddWrite(
6061 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6062 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6063 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436064 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336065 ASYNC, ConstructServerResponseHeadersPacket(
6066 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6067 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436068 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336069 socket_data.AddRead(
6070 ASYNC, ConstructServerDataPacket(
6071 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416072 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436073 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256074 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166075 socket_data.AddWrite(
6076 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6077 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6078 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256079
6080 socket_data.AddSocketDataToFactory(&socket_factory_);
6081
6082 CreateSession();
6083
6084 SendRequestAndExpectQuicResponse("hello!");
6085 session_.reset();
6086}
6087
Ryan Hamilton9edcf1a2017-11-22 05:55:176088TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486089 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256090 session_params_.origins_to_force_quic_on.insert(
6091 HostPortPair::FromString("mail.example.org:443"));
6092
6093 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526094 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256095 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436096 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176097 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256098 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6099 }
6100 socket_data.AddSocketDataToFactory(&socket_factory_);
6101
6102 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176103 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6104 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6105 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6106 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256107
Ryan Hamilton8d9ee76e2018-05-29 23:52:526108 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256109 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6110 TestCompletionCallback callback;
6111 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6112 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176113 while (!callback.have_result()) {
6114 base::RunLoop().RunUntilIdle();
6115 quic_task_runner_->RunUntilIdle();
6116 }
6117 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256118 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176119 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6120 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6121 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526122 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6123 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256124}
6125
Ryan Hamilton9edcf1a2017-11-22 05:55:176126TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486127 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256128 session_params_.origins_to_force_quic_on.insert(
6129 HostPortPair::FromString("mail.example.org:443"));
6130
6131 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526132 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256133 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436134 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176135 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256136 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6137 }
6138 socket_data.AddSocketDataToFactory(&socket_factory_);
6139
6140 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176141 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6142 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6143 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6144 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256145
Ryan Hamilton8d9ee76e2018-05-29 23:52:526146 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6148 TestCompletionCallback callback;
6149 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6150 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176151 while (!callback.have_result()) {
6152 base::RunLoop().RunUntilIdle();
6153 quic_task_runner_->RunUntilIdle();
6154 }
6155 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256156 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176157 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6158 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6159 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526160 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6161 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256162}
6163
Cherie Shi7596de632018-02-22 07:28:186164TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486165 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186166 session_params_.origins_to_force_quic_on.insert(
6167 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436168 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526169 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6170 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186171
6172 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526173 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186174 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436175 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186176 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6177 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526178 socket_data.AddWrite(
6179 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6180 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186181 socket_data.AddSocketDataToFactory(&socket_factory_);
6182
6183 CreateSession();
6184
6185 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6186 TestCompletionCallback callback;
6187 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6188 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6189 base::RunLoop().RunUntilIdle();
6190 ASSERT_TRUE(callback.have_result());
6191 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6192 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6193 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6194}
6195
ckrasic769733c2016-06-30 00:42:136196// Adds coverage to catch regression such as https://crbug.com/622043
6197TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416198 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136199 HostPortPair::FromString("mail.example.org:443"));
6200
6201 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526202 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236203 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436204 mock_quic_data.AddWrite(
6205 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6206 &header_stream_offset));
6207 mock_quic_data.AddWrite(
6208 SYNCHRONOUS,
6209 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336210 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6211 true, true, GetRequestHeaders("GET", "https", "/"),
6212 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526213 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436214 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336215 ASYNC, ConstructServerPushPromisePacket(
6216 1, GetNthClientInitiatedBidirectionalStreamId(0),
6217 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6218 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6219 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576220 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266221 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336222 mock_quic_data.AddWrite(SYNCHRONOUS,
6223 ConstructClientPriorityPacket(
6224 client_packet_number++, false,
6225 GetNthServerInitiatedUnidirectionalStreamId(0),
6226 GetNthClientInitiatedBidirectionalStreamId(0),
6227 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576228 }
Zhongyi Shi32f2fd02018-04-16 18:23:436229 mock_quic_data.AddRead(
6230 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336231 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436232 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576233 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436234 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6235 mock_quic_data.AddRead(
6236 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336237 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6238 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436239 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436240 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336241 ASYNC, ConstructServerDataPacket(
6242 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416243 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576244 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436245 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436246 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436247 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336248 ASYNC, ConstructServerDataPacket(
6249 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416250 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336251 mock_quic_data.AddWrite(SYNCHRONOUS,
6252 ConstructClientAckAndRstPacket(
6253 client_packet_number++,
6254 GetNthServerInitiatedUnidirectionalStreamId(0),
6255 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136256 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6257 mock_quic_data.AddRead(ASYNC, 0); // EOF
6258 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6259
6260 // The non-alternate protocol job needs to hang in order to guarantee that
6261 // the alternate-protocol job will "win".
6262 AddHangingNonAlternateProtocolSocketData();
6263
6264 CreateSession();
6265
6266 // PUSH_PROMISE handling in the http layer gets exercised here.
6267 SendRequestAndExpectQuicResponse("hello!");
6268
6269 request_.url = GURL("https://mail.example.org/pushed.jpg");
6270 SendRequestAndExpectQuicResponse("and hello!");
6271
6272 // Check that the NetLog was filled reasonably.
6273 TestNetLogEntry::List entries;
6274 net_log_.GetEntries(&entries);
6275 EXPECT_LT(0u, entries.size());
6276
6277 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6278 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006279 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6280 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136281 EXPECT_LT(0, pos);
6282}
6283
rch56ec40a2017-06-23 14:48:446284// Regression test for http://crbug.com/719461 in which a promised stream
6285// is closed before the pushed headers arrive, but after the connection
6286// is closed and before the callbacks are executed.
6287TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486288 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446289 session_params_.origins_to_force_quic_on.insert(
6290 HostPortPair::FromString("mail.example.org:443"));
6291
6292 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526293 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236294 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446295 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436296 mock_quic_data.AddWrite(
6297 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6298 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446299 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436300 mock_quic_data.AddWrite(
6301 SYNCHRONOUS,
6302 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336303 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6304 true, true, GetRequestHeaders("GET", "https", "/"),
6305 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526306 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446307 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436308 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336309 ASYNC, ConstructServerPushPromisePacket(
6310 1, GetNthClientInitiatedBidirectionalStreamId(0),
6311 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6312 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6313 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576314 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266315 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336316 mock_quic_data.AddWrite(SYNCHRONOUS,
6317 ConstructClientPriorityPacket(
6318 client_packet_number++, false,
6319 GetNthServerInitiatedUnidirectionalStreamId(0),
6320 GetNthClientInitiatedBidirectionalStreamId(0),
6321 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576322 }
rch56ec40a2017-06-23 14:48:446323 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436324 mock_quic_data.AddRead(
6325 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336326 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436327 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446328 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576329 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436330 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446331 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436332 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436333 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336334 ASYNC, ConstructServerDataPacket(
6335 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416336 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446337 // Write error for the third request.
6338 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6339 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6340 mock_quic_data.AddRead(ASYNC, 0); // EOF
6341 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6342
6343 CreateSession();
6344
6345 // Send a request which triggers a push promise from the server.
6346 SendRequestAndExpectQuicResponse("hello!");
6347
6348 // Start a push transaction that will be cancelled after the connection
6349 // is closed, but before the callback is executed.
6350 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196351 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446352 session_.get());
6353 TestCompletionCallback callback2;
6354 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6356 base::RunLoop().RunUntilIdle();
6357
6358 // Cause the connection to close on a write error.
6359 HttpRequestInfo request3;
6360 request3.method = "GET";
6361 request3.url = GURL("https://mail.example.org/");
6362 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106363 request3.traffic_annotation =
6364 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446365 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6366 TestCompletionCallback callback3;
6367 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6368 IsError(ERR_IO_PENDING));
6369
6370 base::RunLoop().RunUntilIdle();
6371
6372 // When |trans2| is destroyed, the underlying stream will be closed.
6373 EXPECT_FALSE(callback2.have_result());
6374 trans2 = nullptr;
6375
6376 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6377}
6378
ckrasicda193a82016-07-09 00:39:366379TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416380 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366381 HostPortPair::FromString("mail.example.org:443"));
6382
6383 MockQuicData mock_quic_data;
6384
Ryan Hamilton8d9ee76e2018-05-29 23:52:526385 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416386 int write_packet_index = 1;
6387 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6388 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366389
Victor Vasiliev076657c2019-03-12 02:46:436390 std::string header = ConstructDataHeader(1);
Renjief49758b2019-01-11 23:32:416391 if (version_ != quic::QUIC_VERSION_99) {
6392 mock_quic_data.AddWrite(
6393 SYNCHRONOUS,
6394 ConstructClientRequestHeadersAndDataFramesPacket(
6395 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6396 true, true, DEFAULT_PRIORITY,
6397 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6398 {"1"}));
6399 } else {
6400 mock_quic_data.AddWrite(
6401 SYNCHRONOUS,
6402 ConstructClientRequestHeadersAndDataFramesPacket(
6403 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6404 true, true, DEFAULT_PRIORITY,
6405 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6406 {header, "1"}));
6407 }
ckrasicda193a82016-07-09 00:39:366408
Zhongyi Shi32f2fd02018-04-16 18:23:436409 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336410 ASYNC, ConstructServerResponseHeadersPacket(
6411 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6412 GetResponseHeaders("200 OK")));
6413
Victor Vasiliev076657c2019-03-12 02:46:436414 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336415 mock_quic_data.AddRead(
6416 ASYNC, ConstructServerDataPacket(
6417 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416418 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366419
Renjief49758b2019-01-11 23:32:416420 mock_quic_data.AddWrite(
6421 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366422
6423 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6424 mock_quic_data.AddRead(ASYNC, 0); // EOF
6425 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6426
6427 // The non-alternate protocol job needs to hang in order to guarantee that
6428 // the alternate-protocol job will "win".
6429 AddHangingNonAlternateProtocolSocketData();
6430
6431 CreateSession();
6432 request_.method = "POST";
6433 ChunkedUploadDataStream upload_data(0);
6434 upload_data.AppendData("1", 1, true);
6435
6436 request_.upload_data_stream = &upload_data;
6437
6438 SendRequestAndExpectQuicResponse("hello!");
6439}
6440
allada71b2efb2016-09-09 04:57:486441class QuicURLRequestContext : public URLRequestContext {
6442 public:
6443 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6444 MockClientSocketFactory* socket_factory)
6445 : storage_(this) {
6446 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076447 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046448 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486449 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046450 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596451 storage_.set_proxy_resolution_service(
6452 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076453 storage_.set_ssl_config_service(
6454 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486455 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116456 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486457 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076458 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046459 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486460 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046461 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6462 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6463 false));
allada71b2efb2016-09-09 04:57:486464 }
6465
6466 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6467
6468 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6469
6470 private:
6471 MockClientSocketFactory* socket_factory_;
6472 URLRequestContextStorage storage_;
6473};
6474
6475TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416476 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486477 HostPortPair::FromString("mail.example.org:443"));
6478
6479 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526480 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366481 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436482 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136483 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486484 headers["user-agent"] = "";
6485 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336486 mock_quic_data.AddWrite(
6487 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6488 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6489 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486490
Ryan Hamilton8d9ee76e2018-05-29 23:52:526491 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336492 mock_quic_data.AddRead(
6493 ASYNC,
6494 ConstructServerResponseHeadersPacket(
6495 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6496 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486497
Victor Vasiliev076657c2019-03-12 02:46:436498 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366499 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336500 ASYNC, ConstructServerDataPacket(
6501 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6502 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436503 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486504
6505 mock_quic_data.AddRead(ASYNC, 0); // EOF
6506
6507 CreateSession();
6508
6509 TestDelegate delegate;
6510 QuicURLRequestContext quic_url_request_context(std::move(session_),
6511 &socket_factory_);
6512
6513 mock_quic_data.AddSocketDataToFactory(
6514 &quic_url_request_context.socket_factory());
6515 TestNetworkDelegate network_delegate;
6516 quic_url_request_context.set_network_delegate(&network_delegate);
6517
6518 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296519 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6520 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486521 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6522 &ssl_data_);
6523
6524 request->Start();
Wez2a31b222018-06-07 22:07:156525 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486526
6527 EXPECT_LT(0, request->GetTotalSentBytes());
6528 EXPECT_LT(0, request->GetTotalReceivedBytes());
6529 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6530 request->GetTotalSentBytes());
6531 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6532 request->GetTotalReceivedBytes());
6533 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6534 request->raw_header_size());
Wez0e717112018-06-18 23:09:226535
6536 // Pump the message loop to allow all data to be consumed.
6537 base::RunLoop().RunUntilIdle();
6538
allada71b2efb2016-09-09 04:57:486539 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6540 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6541}
6542
6543TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416544 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486545 HostPortPair::FromString("mail.example.org:443"));
6546
6547 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526548 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236549 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436550 mock_quic_data.AddWrite(
6551 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6552 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136553 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486554 headers["user-agent"] = "";
6555 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436556 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336557 SYNCHRONOUS,
6558 ConstructClientRequestHeadersPacket(
6559 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6560 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486561
Ryan Hamilton8d9ee76e2018-05-29 23:52:526562 quic::QuicStreamOffset server_header_offset = 0;
6563 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486564
Zhongyi Shi32f2fd02018-04-16 18:23:436565 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336566 ASYNC, ConstructServerPushPromisePacket(
6567 1, GetNthClientInitiatedBidirectionalStreamId(0),
6568 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6569 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6570 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486571
Yixin Wangb470bc882018-02-15 18:43:576572 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266573 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336574 mock_quic_data.AddWrite(SYNCHRONOUS,
6575 ConstructClientPriorityPacket(
6576 client_packet_number++, false,
6577 GetNthServerInitiatedUnidirectionalStreamId(0),
6578 GetNthClientInitiatedBidirectionalStreamId(0),
6579 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576580 }
6581
allada71b2efb2016-09-09 04:57:486582 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436583 mock_quic_data.AddRead(
6584 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336585 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436586 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486587 expected_raw_header_response_size =
6588 server_header_offset - expected_raw_header_response_size;
6589
Yixin Wangb470bc882018-02-15 18:43:576590 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436591 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486592
ckrasicbf2f59c2017-05-04 23:54:366593 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436594 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336595 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6596 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436597 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436598 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336599 ASYNC, ConstructServerDataPacket(
6600 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416601 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486602
Yixin Wangb470bc882018-02-15 18:43:576603 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436604 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436605 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366606 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336607 ASYNC, ConstructServerDataPacket(
6608 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416609 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486610
Zhongyi Shi32f2fd02018-04-16 18:23:436611 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486612
6613 CreateSession();
6614
6615 TestDelegate delegate;
6616 QuicURLRequestContext quic_url_request_context(std::move(session_),
6617 &socket_factory_);
6618
6619 mock_quic_data.AddSocketDataToFactory(
6620 &quic_url_request_context.socket_factory());
6621 TestNetworkDelegate network_delegate;
6622 quic_url_request_context.set_network_delegate(&network_delegate);
6623
6624 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296625 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6626 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486627 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6628 &ssl_data_);
6629
6630 request->Start();
Wez2a31b222018-06-07 22:07:156631 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486632
6633 EXPECT_LT(0, request->GetTotalSentBytes());
6634 EXPECT_LT(0, request->GetTotalReceivedBytes());
6635 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6636 request->GetTotalSentBytes());
6637 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6638 request->GetTotalReceivedBytes());
6639 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6640 request->raw_header_size());
Wez0e717112018-06-18 23:09:226641
6642 // Pump the message loop to allow all data to be consumed.
6643 base::RunLoop().RunUntilIdle();
6644
allada71b2efb2016-09-09 04:57:486645 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6646 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6647}
6648
Yixin Wang10f477ed2017-11-21 04:20:206649TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6650 session_params_.quic_host_whitelist.insert("mail.example.org");
6651
6652 MockRead http_reads[] = {
6653 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6654 MockRead("hello world"),
6655 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6656 MockRead(ASYNC, OK)};
6657
Ryan Sleevib8d7ea02018-05-07 20:01:016658 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206659 socket_factory_.AddSocketDataProvider(&http_data);
6660 AddCertificate(&ssl_data_);
6661 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6662
6663 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526664 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206665 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436666 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6667 mock_quic_data.AddWrite(
6668 SYNCHRONOUS,
6669 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336670 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436671 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436672 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336673 ASYNC, ConstructServerResponseHeadersPacket(
6674 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6675 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436676 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336677 mock_quic_data.AddRead(
6678 ASYNC, ConstructServerDataPacket(
6679 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416680 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436681 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206682 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6683 mock_quic_data.AddRead(ASYNC, 0); // EOF
6684
6685 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6686
6687 AddHangingNonAlternateProtocolSocketData();
6688 CreateSession();
6689
6690 SendRequestAndExpectHttpResponse("hello world");
6691 SendRequestAndExpectQuicResponse("hello!");
6692}
6693
6694TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6695 session_params_.quic_host_whitelist.insert("mail.example.com");
6696
6697 MockRead http_reads[] = {
6698 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6699 MockRead("hello world"),
6700 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6701 MockRead(ASYNC, OK)};
6702
Ryan Sleevib8d7ea02018-05-07 20:01:016703 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206704 socket_factory_.AddSocketDataProvider(&http_data);
6705 AddCertificate(&ssl_data_);
6706 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6707 socket_factory_.AddSocketDataProvider(&http_data);
6708 AddCertificate(&ssl_data_);
6709 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6710
6711 AddHangingNonAlternateProtocolSocketData();
6712 CreateSession();
6713
6714 SendRequestAndExpectHttpResponse("hello world");
6715 SendRequestAndExpectHttpResponse("hello world");
6716}
6717
bnc359ed2a2016-04-29 20:43:456718class QuicNetworkTransactionWithDestinationTest
6719 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016720 public ::testing::WithParamInterface<PoolingTestParams>,
6721 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456722 protected:
6723 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556724 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056725 client_headers_include_h2_stream_dependency_(
6726 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526727 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456728 destination_type_(GetParam().destination_type),
6729 cert_transparency_verifier_(new MultiLogCTVerifier()),
6730 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596731 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116732 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456733 random_generator_(0),
6734 ssl_data_(ASYNC, OK) {}
6735
6736 void SetUp() override {
6737 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556738 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456739
mmenke6ddfbea2017-05-31 21:48:416740 HttpNetworkSession::Params session_params;
6741 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346742 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446743 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056744 session_params.quic_headers_include_h2_stream_dependency =
6745 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416746
6747 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456748
Ryan Hamilton8d9ee76e2018-05-29 23:52:526749 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416750 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456751
6752 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276753 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416754 session_context.quic_crypto_client_stream_factory =
6755 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456756
mmenke6ddfbea2017-05-31 21:48:416757 session_context.quic_random = &random_generator_;
6758 session_context.client_socket_factory = &socket_factory_;
6759 session_context.host_resolver = &host_resolver_;
6760 session_context.cert_verifier = &cert_verifier_;
6761 session_context.transport_security_state = &transport_security_state_;
6762 session_context.cert_transparency_verifier =
6763 cert_transparency_verifier_.get();
6764 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6765 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456766 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416767 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596768 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416769 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6770 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456771
mmenke6ddfbea2017-05-31 21:48:416772 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456773 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456774 }
6775
6776 void TearDown() override {
6777 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6778 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556779 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456780 PlatformTest::TearDown();
6781 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556782 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406783 session_.reset();
bnc359ed2a2016-04-29 20:43:456784 }
6785
zhongyie537a002017-06-27 16:48:216786 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456787 HostPortPair destination;
6788 switch (destination_type_) {
6789 case SAME_AS_FIRST:
6790 destination = HostPortPair(origin1_, 443);
6791 break;
6792 case SAME_AS_SECOND:
6793 destination = HostPortPair(origin2_, 443);
6794 break;
6795 case DIFFERENT:
6796 destination = HostPortPair(kDifferentHostname, 443);
6797 break;
6798 }
bnc3472afd2016-11-17 15:27:216799 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456800 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216801 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456802 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446803 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456804 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526805 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236806 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526807 quic::QuicStreamId stream_id,
6808 bool should_include_version,
6809 quic::QuicStreamOffset* offset,
6810 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486811 return ConstructClientRequestHeadersPacket(
6812 packet_number, stream_id, should_include_version, 0, offset, maker);
6813 }
bnc359ed2a2016-04-29 20:43:456814
Ryan Hamilton8d9ee76e2018-05-29 23:52:526815 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236816 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526817 quic::QuicStreamId stream_id,
6818 bool should_include_version,
6819 quic::QuicStreamId parent_stream_id,
6820 quic::QuicStreamOffset* offset,
6821 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136822 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456823 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136824 spdy::SpdyHeaderBlock headers(
6825 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456826 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6827 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486828 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456829 }
6830
Ryan Hamilton8d9ee76e2018-05-29 23:52:526831 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236832 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526833 quic::QuicStreamId stream_id,
6834 bool should_include_version,
6835 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586836 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456837 packet_number, stream_id, should_include_version, nullptr, maker);
6838 }
6839
Ryan Hamilton8d9ee76e2018-05-29 23:52:526840 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236841 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526842 quic::QuicStreamId stream_id,
6843 quic::QuicStreamOffset* offset,
6844 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136845 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456846 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266847 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456848 }
6849
Ryan Hamilton8d9ee76e2018-05-29 23:52:526850 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236851 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526852 quic::QuicStreamId stream_id,
6853 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586854 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6855 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456856 }
6857
Ryan Hamilton8d9ee76e2018-05-29 23:52:526858 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236859 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526860 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456861 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436862 std::string header = "";
Renjief49758b2019-01-11 23:32:416863 if (version_ == quic::QUIC_VERSION_99) {
6864 quic::HttpEncoder encoder;
6865 std::unique_ptr<char[]> buffer;
6866 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436867 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416868 }
bnc359ed2a2016-04-29 20:43:456869 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416870 header + "hello");
bnc359ed2a2016-04-29 20:43:456871 }
6872
Ryan Hamilton8d9ee76e2018-05-29 23:52:526873 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236874 uint64_t packet_number,
6875 uint64_t largest_received,
6876 uint64_t smallest_received,
6877 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456878 QuicTestPacketMaker* maker) {
6879 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496880 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456881 }
6882
Ryan Hamilton8d9ee76e2018-05-29 23:52:526883 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236884 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526885 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376886 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366887 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376888 }
6889
bnc359ed2a2016-04-29 20:43:456890 void AddRefusedSocketData() {
6891 std::unique_ptr<StaticSocketDataProvider> refused_data(
6892 new StaticSocketDataProvider());
6893 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6894 refused_data->set_connect_data(refused_connect);
6895 socket_factory_.AddSocketDataProvider(refused_data.get());
6896 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6897 }
6898
6899 void AddHangingSocketData() {
6900 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6901 new StaticSocketDataProvider());
6902 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6903 hanging_data->set_connect_data(hanging_connect);
6904 socket_factory_.AddSocketDataProvider(hanging_data.get());
6905 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6907 }
6908
6909 bool AllDataConsumed() {
6910 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6911 if (!socket_data_ptr->AllReadDataConsumed() ||
6912 !socket_data_ptr->AllWriteDataConsumed()) {
6913 return false;
6914 }
6915 }
6916 return true;
6917 }
6918
6919 void SendRequestAndExpectQuicResponse(const std::string& host) {
6920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6921 HttpRequestInfo request;
6922 std::string url("https://");
6923 url.append(host);
6924 request.url = GURL(url);
6925 request.load_flags = 0;
6926 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106927 request.traffic_annotation =
6928 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456929 TestCompletionCallback callback;
6930 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016931 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456932
6933 std::string response_data;
robpercival214763f2016-07-01 23:27:016934 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456935 EXPECT_EQ("hello", response_data);
6936
6937 const HttpResponseInfo* response = trans.GetResponseInfo();
6938 ASSERT_TRUE(response != nullptr);
6939 ASSERT_TRUE(response->headers.get() != nullptr);
6940 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6941 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526942 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446943 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456944 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376945 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456946 }
6947
Fan Yang32c5a112018-12-10 20:06:336948 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
6949 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366950 }
6951
Ryan Hamilton8d9ee76e2018-05-29 23:52:526952 quic::MockClock clock_;
6953 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056954 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526955 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456956 DestinationType destination_type_;
6957 std::string origin1_;
6958 std::string origin2_;
6959 std::unique_ptr<HttpNetworkSession> session_;
6960 MockClientSocketFactory socket_factory_;
6961 MockHostResolver host_resolver_;
6962 MockCertVerifier cert_verifier_;
6963 TransportSecurityState transport_security_state_;
6964 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236965 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456966 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076967 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596968 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456969 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526970 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456971 HttpServerPropertiesImpl http_server_properties_;
6972 BoundTestNetLog net_log_;
6973 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6974 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6975 static_socket_data_provider_vector_;
6976 SSLSocketDataProvider ssl_data_;
6977};
6978
Victor Costane635086f2019-01-27 05:20:306979INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6980 QuicNetworkTransactionWithDestinationTest,
6981 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:456982
6983// A single QUIC request fails because the certificate does not match the origin
6984// hostname, regardless of whether it matches the alternative service hostname.
6985TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6986 if (destination_type_ == DIFFERENT)
6987 return;
6988
6989 GURL url("https://mail.example.com/");
6990 origin1_ = url.host();
6991
6992 // Not used for requests, but this provides a test case where the certificate
6993 // is valid for the hostname of the alternative service.
6994 origin2_ = "mail.example.org";
6995
zhongyie537a002017-06-27 16:48:216996 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456997
6998 scoped_refptr<X509Certificate> cert(
6999 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247000 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7001 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457002
7003 ProofVerifyDetailsChromium verify_details;
7004 verify_details.cert_verify_result.verified_cert = cert;
7005 verify_details.cert_verify_result.is_issued_by_known_root = true;
7006 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7007
7008 MockQuicData mock_quic_data;
7009 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7010 mock_quic_data.AddRead(ASYNC, 0);
7011
7012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7013
7014 AddRefusedSocketData();
7015
7016 HttpRequestInfo request;
7017 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107018 request.traffic_annotation =
7019 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457020
7021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7022 TestCompletionCallback callback;
7023 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017024 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457025
7026 EXPECT_TRUE(AllDataConsumed());
7027}
7028
7029// First request opens QUIC session to alternative service. Second request
7030// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527031// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457032TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7033 origin1_ = "mail.example.org";
7034 origin2_ = "news.example.org";
7035
zhongyie537a002017-06-27 16:48:217036 SetQuicAlternativeService(origin1_);
7037 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457038
7039 scoped_refptr<X509Certificate> cert(
7040 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247041 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7042 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7043 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457044
7045 ProofVerifyDetailsChromium verify_details;
7046 verify_details.cert_verify_result.verified_cert = cert;
7047 verify_details.cert_verify_result.is_issued_by_known_root = true;
7048 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7049
Yixin Wang079ad542018-01-11 04:06:057050 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177051 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7052 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057053 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177054 QuicTestPacketMaker server_maker(
7055 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7056 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457057
Ryan Hamilton8d9ee76e2018-05-29 23:52:527058 quic::QuicStreamOffset request_header_offset(0);
7059 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457060
7061 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057062 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437063 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057064 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337065 mock_quic_data.AddWrite(
7066 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7067 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7068 &request_header_offset, &client_maker));
7069 mock_quic_data.AddRead(ASYNC,
7070 ConstructServerResponseHeadersPacket(
7071 1, GetNthClientInitiatedBidirectionalStreamId(0),
7072 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437073 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337074 ASYNC,
7075 ConstructServerDataPacket(
7076 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437077 mock_quic_data.AddWrite(SYNCHRONOUS,
7078 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457079
Yixin Wang079ad542018-01-11 04:06:057080 client_maker.set_hostname(origin2_);
7081 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457082
Zhongyi Shi32f2fd02018-04-16 18:23:437083 mock_quic_data.AddWrite(
7084 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337085 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7086 GetNthClientInitiatedBidirectionalStreamId(0),
7087 &request_header_offset, &client_maker));
7088 mock_quic_data.AddRead(ASYNC,
7089 ConstructServerResponseHeadersPacket(
7090 3, GetNthClientInitiatedBidirectionalStreamId(1),
7091 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437092 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337093 ASYNC,
7094 ConstructServerDataPacket(
7095 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437096 mock_quic_data.AddWrite(SYNCHRONOUS,
7097 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457098 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7099 mock_quic_data.AddRead(ASYNC, 0); // EOF
7100
7101 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7102
7103 AddHangingSocketData();
7104 AddHangingSocketData();
7105
Fan Yangc9e00dc2018-10-09 14:17:567106 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7107 QuicStreamFactoryPeer::SetAlarmFactory(
7108 session_->quic_stream_factory(),
7109 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7110 &clock_));
7111
bnc359ed2a2016-04-29 20:43:457112 SendRequestAndExpectQuicResponse(origin1_);
7113 SendRequestAndExpectQuicResponse(origin2_);
7114
7115 EXPECT_TRUE(AllDataConsumed());
7116}
7117
7118// First request opens QUIC session to alternative service. Second request does
7119// not pool to it, even though destination matches, because certificate is not
7120// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527121// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457122TEST_P(QuicNetworkTransactionWithDestinationTest,
7123 DoNotPoolIfCertificateInvalid) {
7124 origin1_ = "news.example.org";
7125 origin2_ = "mail.example.com";
7126
zhongyie537a002017-06-27 16:48:217127 SetQuicAlternativeService(origin1_);
7128 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457129
7130 scoped_refptr<X509Certificate> cert1(
7131 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247132 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7133 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7134 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457135
7136 scoped_refptr<X509Certificate> cert2(
7137 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247138 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7139 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457140
7141 ProofVerifyDetailsChromium verify_details1;
7142 verify_details1.cert_verify_result.verified_cert = cert1;
7143 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7144 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7145
7146 ProofVerifyDetailsChromium verify_details2;
7147 verify_details2.cert_verify_result.verified_cert = cert2;
7148 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7149 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7150
Yixin Wang079ad542018-01-11 04:06:057151 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177152 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7153 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057154 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177155 QuicTestPacketMaker server_maker1(
7156 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7157 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457158
7159 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527160 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457161 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437162 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7163 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337164 mock_quic_data1.AddWrite(
7165 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7166 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7167 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437168 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337169 ASYNC,
7170 ConstructServerResponseHeadersPacket(
7171 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437172 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337173 ASYNC,
7174 ConstructServerDataPacket(
7175 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437176 mock_quic_data1.AddWrite(
7177 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457178 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7179 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7180
7181 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7182
Yixin Wang079ad542018-01-11 04:06:057183 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177184 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7185 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057186 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177187 QuicTestPacketMaker server_maker2(
7188 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7189 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457190
7191 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527192 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457193 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437194 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7195 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337196 mock_quic_data2.AddWrite(
7197 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7198 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7199 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437200 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337201 ASYNC,
7202 ConstructServerResponseHeadersPacket(
7203 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437204 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337205 ASYNC,
7206 ConstructServerDataPacket(
7207 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437208 mock_quic_data2.AddWrite(
7209 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457210 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7211 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7212
7213 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7214
bnc359ed2a2016-04-29 20:43:457215 SendRequestAndExpectQuicResponse(origin1_);
7216 SendRequestAndExpectQuicResponse(origin2_);
7217
7218 EXPECT_TRUE(AllDataConsumed());
7219}
7220
ckrasicdee37572017-04-06 22:42:277221// crbug.com/705109 - this confirms that matching request with a body
7222// triggers a crash (pre-fix).
7223TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417224 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277225 HostPortPair::FromString("mail.example.org:443"));
7226
7227 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527228 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237229 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437230 mock_quic_data.AddWrite(
7231 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7232 &header_stream_offset));
7233 mock_quic_data.AddWrite(
7234 SYNCHRONOUS,
7235 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337236 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7237 true, true, GetRequestHeaders("GET", "https", "/"),
7238 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527239 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437240 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337241 ASYNC, ConstructServerPushPromisePacket(
7242 1, GetNthClientInitiatedBidirectionalStreamId(0),
7243 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7244 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7245 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577246 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267247 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337248 mock_quic_data.AddWrite(SYNCHRONOUS,
7249 ConstructClientPriorityPacket(
7250 client_packet_number++, false,
7251 GetNthServerInitiatedUnidirectionalStreamId(0),
7252 GetNthClientInitiatedBidirectionalStreamId(0),
7253 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577254 }
Zhongyi Shi32f2fd02018-04-16 18:23:437255 mock_quic_data.AddRead(
7256 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337257 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437258 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577259 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437260 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7261 mock_quic_data.AddRead(
7262 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337263 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7264 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437265 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437266 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337267 ASYNC, ConstructServerDataPacket(
7268 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417269 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577270 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437271 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417272
Victor Vasiliev076657c2019-03-12 02:46:437273 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437274 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337275 ASYNC, ConstructServerDataPacket(
7276 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417277 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277278
7279 // Because the matching request has a body, we will see the push
7280 // stream get cancelled, and the matching request go out on the
7281 // wire.
Fan Yang32c5a112018-12-10 20:06:337282 mock_quic_data.AddWrite(SYNCHRONOUS,
7283 ConstructClientAckAndRstPacket(
7284 client_packet_number++,
7285 GetNthServerInitiatedUnidirectionalStreamId(0),
7286 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277287 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437288 std::string header3 = ConstructDataHeader(1);
Renjief49758b2019-01-11 23:32:417289 if (version_ != quic::QUIC_VERSION_99) {
7290 mock_quic_data.AddWrite(
7291 SYNCHRONOUS,
7292 ConstructClientRequestHeadersAndDataFramesPacket(
7293 client_packet_number++,
7294 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7295 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7296 GetNthServerInitiatedUnidirectionalStreamId(0),
7297 &header_stream_offset, nullptr, {kBody}));
7298 } else {
7299 mock_quic_data.AddWrite(
7300 SYNCHRONOUS,
7301 ConstructClientRequestHeadersAndDataFramesPacket(
7302 client_packet_number++,
7303 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7304 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7305 GetNthServerInitiatedUnidirectionalStreamId(0),
7306 &header_stream_offset, nullptr, {header3, kBody}));
7307 }
ckrasicdee37572017-04-06 22:42:277308
7309 // We see the same response as for the earlier pushed and cancelled
7310 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437311 mock_quic_data.AddRead(
7312 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337313 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437314 GetResponseHeaders("200 OK"), &server_header_offset));
7315 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337316 ASYNC, ConstructServerDataPacket(
7317 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417318 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277319
Yixin Wangb470bc882018-02-15 18:43:577320 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437321 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277322 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7323 mock_quic_data.AddRead(ASYNC, 0); // EOF
7324 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7325
7326 // The non-alternate protocol job needs to hang in order to guarantee that
7327 // the alternate-protocol job will "win".
7328 AddHangingNonAlternateProtocolSocketData();
7329
7330 CreateSession();
7331
7332 // PUSH_PROMISE handling in the http layer gets exercised here.
7333 SendRequestAndExpectQuicResponse("hello!");
7334
7335 request_.url = GURL("https://mail.example.org/pushed.jpg");
7336 ChunkedUploadDataStream upload_data(0);
7337 upload_data.AppendData("1", 1, true);
7338 request_.upload_data_stream = &upload_data;
7339 SendRequestAndExpectQuicResponse("and hello!");
7340}
7341
Bence Béky7538a952018-02-01 16:59:527342// Regression test for https://crbug.com/797825: If pushed headers describe a
7343// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7344// not be called (otherwise a DCHECK fails).
7345TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137346 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527347 pushed_request_headers[":authority"] = "";
7348 pushed_request_headers[":method"] = "GET";
7349 pushed_request_headers[":path"] = "/";
7350 pushed_request_headers[":scheme"] = "nosuchscheme";
7351
7352 session_params_.origins_to_force_quic_on.insert(
7353 HostPortPair::FromString("mail.example.org:443"));
7354
7355 MockQuicData mock_quic_data;
7356
Ryan Hamilton8d9ee76e2018-05-29 23:52:527357 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527358 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437359 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7360 mock_quic_data.AddWrite(
7361 SYNCHRONOUS,
7362 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337363 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437364 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527365
Ryan Hamilton8d9ee76e2018-05-29 23:52:527366 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337367 mock_quic_data.AddRead(
7368 ASYNC, ConstructServerPushPromisePacket(
7369 1, GetNthClientInitiatedBidirectionalStreamId(0),
7370 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7371 std::move(pushed_request_headers), &server_header_offset,
7372 &server_maker_));
7373 mock_quic_data.AddWrite(SYNCHRONOUS,
7374 ConstructClientRstPacket(
7375 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7376 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527377
Zhongyi Shi32f2fd02018-04-16 18:23:437378 mock_quic_data.AddRead(
7379 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337380 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437381 GetResponseHeaders("200 OK"), &server_header_offset));
7382 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527383
Zhongyi Shi32f2fd02018-04-16 18:23:437384 mock_quic_data.AddRead(
7385 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337386 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7387 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437388 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437389 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337390 ASYNC, ConstructServerDataPacket(
7391 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417392 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437393 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527394
7395 mock_quic_data.AddRead(ASYNC, 0);
7396 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7397
7398 // The non-alternate protocol job needs to hang in order to guarantee that
7399 // the alternate-protocol job will "win".
7400 AddHangingNonAlternateProtocolSocketData();
7401
7402 CreateSession();
7403
7404 // PUSH_PROMISE handling in the http layer gets exercised here.
7405 SendRequestAndExpectQuicResponse("hello!");
7406
7407 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7408 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7409}
7410
Yixin Wang46a273ec302018-01-23 17:59:567411// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147412TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567413 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147414 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567415 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497416 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567417
7418 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527419 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567420 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357421 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337422 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357423 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7424 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047425 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7426 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357427 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337428 mock_quic_data.AddRead(
7429 ASYNC, ConstructServerResponseHeadersPacket(
7430 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7431 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567432
7433 const char get_request[] =
7434 "GET / HTTP/1.1\r\n"
7435 "Host: mail.example.org\r\n"
7436 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437437 std::string header = ConstructDataHeader(strlen(get_request));
Renjief49758b2019-01-11 23:32:417438 if (version_ != quic::QUIC_VERSION_99) {
7439 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357440 SYNCHRONOUS,
7441 ConstructClientAckAndDataPacket(
7442 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7443 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417444 } else {
7445 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417446 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357447 ConstructClientAckAndMultipleDataFramesPacket(
7448 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437449 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417450 }
7451
Yixin Wang46a273ec302018-01-23 17:59:567452 const char get_response[] =
7453 "HTTP/1.1 200 OK\r\n"
7454 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437455 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437456 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337457 ASYNC, ConstructServerDataPacket(
7458 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437459 0, header2 + std::string(get_response)));
7460 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337461 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417462 SYNCHRONOUS, ConstructServerDataPacket(
7463 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7464 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437465 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357466 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567467 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7468
7469 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417470 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357471 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7472 quic::QUIC_STREAM_CANCELLED,
7473 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567474
7475 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7476
7477 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7478
7479 CreateSession();
7480
7481 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097482 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567483 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7484 HeadersHandler headers_handler;
7485 trans.SetBeforeHeadersSentCallback(
7486 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7487 base::Unretained(&headers_handler)));
7488 RunTransaction(&trans);
7489 CheckWasHttpResponse(&trans);
7490 CheckResponsePort(&trans, 70);
7491 CheckResponseData(&trans, "0123456789");
7492 EXPECT_TRUE(headers_handler.was_proxied());
7493 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7494
7495 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7496 // proxy socket to disconnect.
7497 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7498
7499 base::RunLoop().RunUntilIdle();
7500 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7501 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7502}
7503
7504// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147505TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567506 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147507 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567508 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497509 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567510
7511 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527512 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567513 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357514 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337515 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357516 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7517 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047518 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7519 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357520 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337521 mock_quic_data.AddRead(
7522 ASYNC, ConstructServerResponseHeadersPacket(
7523 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7524 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567525
7526 SpdyTestUtil spdy_util;
7527
Ryan Hamilton0239aac2018-05-19 00:03:137528 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567529 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437530 std::string header = ConstructDataHeader(get_frame.size());
Renjief49758b2019-01-11 23:32:417531 if (version_ != quic::QUIC_VERSION_99) {
7532 mock_quic_data.AddWrite(
7533 SYNCHRONOUS,
7534 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357535 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7536 false, 0,
Renjief49758b2019-01-11 23:32:417537 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7538 } else {
7539 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417540 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357541 ConstructClientAckAndMultipleDataFramesPacket(
7542 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7543 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437544 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417545 }
Ryan Hamilton0239aac2018-05-19 00:03:137546 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567547 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437548 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437549 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337550 ASYNC,
7551 ConstructServerDataPacket(
7552 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437553 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567554
Ryan Hamilton0239aac2018-05-19 00:03:137555 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197556 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437557 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437558 mock_quic_data.AddRead(
7559 SYNCHRONOUS,
7560 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337561 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417562 resp_frame.size() + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437563 header3 + std::string(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357564 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567565 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7566
7567 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437568 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357569 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7570 quic::QUIC_STREAM_CANCELLED,
7571 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567572
7573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7574
7575 SSLSocketDataProvider ssl_data(ASYNC, OK);
7576 ssl_data.next_proto = kProtoHTTP2;
7577 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7578
7579 CreateSession();
7580
7581 request_.url = GURL("https://mail.example.org/");
7582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7583 HeadersHandler headers_handler;
7584 trans.SetBeforeHeadersSentCallback(
7585 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7586 base::Unretained(&headers_handler)));
7587 RunTransaction(&trans);
7588 CheckWasSpdyResponse(&trans);
7589 CheckResponsePort(&trans, 70);
7590 CheckResponseData(&trans, "0123456789");
7591 EXPECT_TRUE(headers_handler.was_proxied());
7592 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7593
Wez0e717112018-06-18 23:09:227594 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7595 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567596 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7597
7598 base::RunLoop().RunUntilIdle();
7599 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7600 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7601}
7602
7603// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7604// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147605TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567606 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147607 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567608 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497609 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567610
7611 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527612 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417613 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567614 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417615 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7616 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337617 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417618 SYNCHRONOUS,
7619 ConstructClientRequestHeadersPacket(
7620 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047621 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7622 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjief49758b2019-01-11 23:32:417623 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337624 mock_quic_data.AddRead(
7625 ASYNC, ConstructServerResponseHeadersPacket(
7626 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7627 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567628
Ryan Hamilton8d9ee76e2018-05-29 23:52:527629 quic::QuicStreamOffset client_data_offset = 0;
7630 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567631 const char get_request_1[] =
7632 "GET / HTTP/1.1\r\n"
7633 "Host: mail.example.org\r\n"
7634 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437635 std::string header = ConstructDataHeader(strlen(get_request_1));
Renjief49758b2019-01-11 23:32:417636 if (version_ != quic::QUIC_VERSION_99) {
7637 mock_quic_data.AddWrite(
7638 SYNCHRONOUS,
7639 ConstructClientAckAndDataPacket(
7640 write_packet_index++, false,
7641 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7642 client_data_offset, quic::QuicStringPiece(get_request_1)));
7643 } else {
7644 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417645 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357646 ConstructClientAckAndMultipleDataFramesPacket(
7647 write_packet_index++, false,
7648 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
Victor Vasiliev076657c2019-03-12 02:46:437649 client_data_offset, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417650 }
7651
7652 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567653
7654 const char get_response_1[] =
7655 "HTTP/1.1 200 OK\r\n"
7656 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437657 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437658 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437659 ASYNC, ConstructServerDataPacket(
7660 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7661 server_data_offset, header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417662 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567663
Victor Vasiliev076657c2019-03-12 02:46:437664 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337665 mock_quic_data.AddRead(
7666 SYNCHRONOUS,
7667 ConstructServerDataPacket(
7668 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437669 server_data_offset, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417670 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567671
Renjief49758b2019-01-11 23:32:417672 mock_quic_data.AddWrite(
7673 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567674
7675 const char get_request_2[] =
7676 "GET /2 HTTP/1.1\r\n"
7677 "Host: mail.example.org\r\n"
7678 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437679 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Renjief49758b2019-01-11 23:32:417680 if (version_ == quic::QUIC_VERSION_99) {
7681 mock_quic_data.AddWrite(
7682 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357683 ConstructClientMultipleDataFramesPacket(
7684 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7685 false, false, client_data_offset,
Victor Vasiliev076657c2019-03-12 02:46:437686 {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357687 client_data_offset += header4.length() + strlen(get_request_2);
7688 } else {
7689 mock_quic_data.AddWrite(
7690 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417691 ConstructClientDataPacket(write_packet_index++,
7692 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357693 false, false, client_data_offset,
7694 quic::QuicStringPiece(get_request_2)));
7695 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417696 }
Yixin Wang46a273ec302018-01-23 17:59:567697
7698 const char get_response_2[] =
7699 "HTTP/1.1 200 OK\r\n"
7700 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437701 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437702 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437703 ASYNC, ConstructServerDataPacket(
7704 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7705 server_data_offset, header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417706 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567707
Victor Vasiliev076657c2019-03-12 02:46:437708 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527709 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337710 SYNCHRONOUS,
7711 ConstructServerDataPacket(
7712 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437713 server_data_offset, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417714 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567715
Renjief49758b2019-01-11 23:32:417716 mock_quic_data.AddWrite(
7717 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567718 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7719
Renjief49758b2019-01-11 23:32:417720 mock_quic_data.AddWrite(
7721 SYNCHRONOUS,
7722 ConstructClientRstPacket(
7723 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7724 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567725
7726 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7727
7728 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7729
7730 CreateSession();
7731
7732 request_.url = GURL("https://mail.example.org/");
7733 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7734 HeadersHandler headers_handler_1;
7735 trans_1.SetBeforeHeadersSentCallback(
7736 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7737 base::Unretained(&headers_handler_1)));
7738 RunTransaction(&trans_1);
7739 CheckWasHttpResponse(&trans_1);
7740 CheckResponsePort(&trans_1, 70);
7741 CheckResponseData(&trans_1, "0123456789");
7742 EXPECT_TRUE(headers_handler_1.was_proxied());
7743 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7744
7745 request_.url = GURL("https://mail.example.org/2");
7746 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7747 HeadersHandler headers_handler_2;
7748 trans_2.SetBeforeHeadersSentCallback(
7749 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7750 base::Unretained(&headers_handler_2)));
7751 RunTransaction(&trans_2);
7752 CheckWasHttpResponse(&trans_2);
7753 CheckResponsePort(&trans_2, 70);
7754 CheckResponseData(&trans_2, "0123456");
7755 EXPECT_TRUE(headers_handler_2.was_proxied());
7756 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7757
7758 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7759 // proxy socket to disconnect.
7760 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7761
7762 base::RunLoop().RunUntilIdle();
7763 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7764 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7765}
7766
7767// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7768// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7769// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147770TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567771 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147772 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567773 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497774 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567775
7776 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527777 quic::QuicStreamOffset client_header_stream_offset = 0;
7778 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357779 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7780 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567781
7782 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337783 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357784 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7785 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047786 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7787 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357788 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437789 mock_quic_data.AddRead(
7790 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337791 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437792 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567793
7794 // GET request, response, and data over QUIC tunnel for first request
7795 const char get_request[] =
7796 "GET / HTTP/1.1\r\n"
7797 "Host: mail.example.org\r\n"
7798 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437799 std::string header = ConstructDataHeader(strlen(get_request));
Renjief49758b2019-01-11 23:32:417800 if (version_ != quic::QUIC_VERSION_99) {
7801 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357802 SYNCHRONOUS,
7803 ConstructClientAckAndDataPacket(
7804 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7805 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417806 } else {
7807 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417808 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357809 ConstructClientAckAndMultipleDataFramesPacket(
7810 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437811 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417812 }
7813
Yixin Wang46a273ec302018-01-23 17:59:567814 const char get_response[] =
7815 "HTTP/1.1 200 OK\r\n"
7816 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437817 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567818 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337819 ASYNC, ConstructServerDataPacket(
7820 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437821 0, header2 + std::string(get_response)));
7822 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337823 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417824 SYNCHRONOUS, ConstructServerDataPacket(
7825 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7826 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437827 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357828 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567829
7830 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437831 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047832 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7833 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
7834 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7835 ConnectRequestHeaders("different.example.org:443"),
7836 GetNthClientInitiatedBidirectionalStreamId(0),
7837 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437838 mock_quic_data.AddRead(
7839 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337840 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437841 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567842
7843 // GET request, response, and data over QUIC tunnel for second request
7844 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137845 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567846 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437847 std::string header4 = ConstructDataHeader(get_frame.size());
Renjief49758b2019-01-11 23:32:417848 if (version_ != quic::QUIC_VERSION_99) {
7849 mock_quic_data.AddWrite(
7850 SYNCHRONOUS,
7851 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357852 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7853 false, 0,
Renjief49758b2019-01-11 23:32:417854 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7855 } else {
7856 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417857 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357858 ConstructClientAckAndMultipleDataFramesPacket(
7859 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7860 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437861 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417862 }
Yixin Wang46a273ec302018-01-23 17:59:567863
Ryan Hamilton0239aac2018-05-19 00:03:137864 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567865 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437866 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437867 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337868 ASYNC,
7869 ConstructServerDataPacket(
7870 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437871 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567872
Ryan Hamilton0239aac2018-05-19 00:03:137873 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197874 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437875 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437876 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437877 ASYNC, ConstructServerDataPacket(
7878 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7879 resp_frame.size() + header5.length(),
7880 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567881
Renjied172e812019-01-16 05:12:357882 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567883 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7884
7885 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417886 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357887 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7888 quic::QUIC_STREAM_CANCELLED,
7889 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567890 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437891 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357892 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7893 quic::QUIC_STREAM_CANCELLED,
7894 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567895
7896 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7897
7898 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7899
7900 SSLSocketDataProvider ssl_data(ASYNC, OK);
7901 ssl_data.next_proto = kProtoHTTP2;
7902 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7903
7904 CreateSession();
7905
7906 request_.url = GURL("https://mail.example.org/");
7907 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7908 HeadersHandler headers_handler_1;
7909 trans_1.SetBeforeHeadersSentCallback(
7910 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7911 base::Unretained(&headers_handler_1)));
7912 RunTransaction(&trans_1);
7913 CheckWasHttpResponse(&trans_1);
7914 CheckResponsePort(&trans_1, 70);
7915 CheckResponseData(&trans_1, "0123456789");
7916 EXPECT_TRUE(headers_handler_1.was_proxied());
7917 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7918
7919 request_.url = GURL("https://different.example.org/");
7920 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7921 HeadersHandler headers_handler_2;
7922 trans_2.SetBeforeHeadersSentCallback(
7923 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7924 base::Unretained(&headers_handler_2)));
7925 RunTransaction(&trans_2);
7926 CheckWasSpdyResponse(&trans_2);
7927 CheckResponsePort(&trans_2, 70);
7928 CheckResponseData(&trans_2, "0123456");
7929 EXPECT_TRUE(headers_handler_2.was_proxied());
7930 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7931
7932 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7933 // proxy socket to disconnect.
7934 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7935
7936 base::RunLoop().RunUntilIdle();
7937 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7938 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7939}
7940
7941// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147942TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567943 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147944 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567945 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497946 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567947
7948 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527949 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567950 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437951 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527952 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337953 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7954 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047955 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7956 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:337957 &header_stream_offset));
7958 mock_quic_data.AddRead(
7959 ASYNC, ConstructServerResponseHeadersPacket(
7960 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7961 GetResponseHeaders("500")));
7962 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7963 mock_quic_data.AddWrite(SYNCHRONOUS,
7964 ConstructClientAckAndRstPacket(
7965 3, GetNthClientInitiatedBidirectionalStreamId(0),
7966 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567967
7968 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7969
7970 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7971
7972 CreateSession();
7973
7974 request_.url = GURL("https://mail.example.org/");
7975 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7976 HeadersHandler headers_handler;
7977 trans.SetBeforeHeadersSentCallback(
7978 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7979 base::Unretained(&headers_handler)));
7980 TestCompletionCallback callback;
7981 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7982 EXPECT_EQ(ERR_IO_PENDING, rv);
7983 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7984 EXPECT_EQ(false, headers_handler.was_proxied());
7985
7986 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7987 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7988}
7989
7990// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:147991TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:567992 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147993 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567994 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497995 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567996
7997 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527998 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567999 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438000 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338001 mock_quic_data.AddWrite(
8002 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8003 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048004 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8005 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338006 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568007 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8008
8009 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8010
8011 CreateSession();
8012
8013 request_.url = GURL("https://mail.example.org/");
8014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8015 HeadersHandler headers_handler;
8016 trans.SetBeforeHeadersSentCallback(
8017 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8018 base::Unretained(&headers_handler)));
8019 TestCompletionCallback callback;
8020 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8021 EXPECT_EQ(ERR_IO_PENDING, rv);
8022 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8023
8024 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8025 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8026}
8027
8028// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8029// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148030TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568031 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148032 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568033 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498034 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568035
8036 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528037 quic::QuicStreamOffset client_header_stream_offset = 0;
8038 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358039 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8040 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338041 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358042 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8043 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048044 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8045 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:358046 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438047 mock_quic_data.AddRead(
8048 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338049 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438050 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358051 mock_quic_data.AddWrite(SYNCHRONOUS,
8052 ConstructClientAckAndRstPacket(
8053 3, GetNthClientInitiatedBidirectionalStreamId(0),
8054 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568055
Zhongyi Shi32f2fd02018-04-16 18:23:438056 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358057 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8058 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Matt Menke6e879bd2019-03-18 17:26:048059 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8060 ConnectRequestHeaders("mail.example.org:443"),
Renjied172e812019-01-16 05:12:358061 GetNthClientInitiatedBidirectionalStreamId(0),
8062 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438063 mock_quic_data.AddRead(
8064 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338065 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438066 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568067
8068 const char get_request[] =
8069 "GET / HTTP/1.1\r\n"
8070 "Host: mail.example.org\r\n"
8071 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438072 std::string header = ConstructDataHeader(strlen(get_request));
Renjief49758b2019-01-11 23:32:418073 if (version_ != quic::QUIC_VERSION_99) {
8074 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358075 SYNCHRONOUS,
8076 ConstructClientAckAndDataPacket(
8077 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8078 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418079 } else {
8080 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418081 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358082 ConstructClientAckAndMultipleDataFramesPacket(
8083 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Victor Vasiliev076657c2019-03-12 02:46:438084 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418085 }
Yixin Wang46a273ec302018-01-23 17:59:568086 const char get_response[] =
8087 "HTTP/1.1 200 OK\r\n"
8088 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438089 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438090 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338091 ASYNC, ConstructServerDataPacket(
8092 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438093 0, header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528094
Victor Vasiliev076657c2019-03-12 02:46:438095 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338096 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418097 SYNCHRONOUS, ConstructServerDataPacket(
8098 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8099 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:438100 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:358101 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568102 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8103
8104 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418105 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358106 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8107 quic::QUIC_STREAM_CANCELLED,
8108 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568109
8110 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8111
8112 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8113 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8114
8115 SSLSocketDataProvider ssl_data(ASYNC, OK);
8116 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8117
8118 CreateSession();
8119
8120 request_.url = GURL("https://mail.example.org/");
8121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8122 HeadersHandler headers_handler;
8123 trans.SetBeforeHeadersSentCallback(
8124 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8125 base::Unretained(&headers_handler)));
8126 TestCompletionCallback callback;
8127 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8128 EXPECT_EQ(ERR_IO_PENDING, rv);
8129 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8130
8131 rv = trans.RestartIgnoringLastError(callback.callback());
8132 EXPECT_EQ(ERR_IO_PENDING, rv);
8133 EXPECT_EQ(OK, callback.WaitForResult());
8134
8135 CheckWasHttpResponse(&trans);
8136 CheckResponsePort(&trans, 70);
8137 CheckResponseData(&trans, "0123456789");
8138 EXPECT_EQ(true, headers_handler.was_proxied());
8139 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8140
8141 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8142 // proxy socket to disconnect.
8143 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8144
8145 base::RunLoop().RunUntilIdle();
8146 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8147 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8148}
8149
8150// Checks if a request's specified "user-agent" header shows up correctly in the
8151// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148152TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008153 const char kConfiguredUserAgent[] = "Configured User-Agent";
8154 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568155 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148156 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568157 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498158 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568159
8160 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528161 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568162 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438163 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568164
Ryan Hamilton0239aac2018-05-19 00:03:138165 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008166 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338167 mock_quic_data.AddWrite(
8168 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8169 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048170 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8171 std::move(headers), 0, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568172 // Return an error, so the transaction stops here (this test isn't interested
8173 // in the rest).
8174 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8175
8176 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8177
Matt Menked732ea42019-03-08 12:05:008178 StaticHttpUserAgentSettings http_user_agent_settings(
8179 std::string() /* accept_language */, kConfiguredUserAgent);
8180 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568181 CreateSession();
8182
8183 request_.url = GURL("https://mail.example.org/");
8184 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008185 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8187 HeadersHandler headers_handler;
8188 trans.SetBeforeHeadersSentCallback(
8189 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8190 base::Unretained(&headers_handler)));
8191 TestCompletionCallback callback;
8192 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8193 EXPECT_EQ(ERR_IO_PENDING, rv);
8194 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8195
8196 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8197 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8198}
8199
Yixin Wang00fc44c2018-01-23 21:12:208200// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8201// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148202TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208203 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148204 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208205 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498206 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208207
8208 const RequestPriority request_priority = MEDIUM;
8209
8210 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528211 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208212 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438213 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8214 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048215 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8216 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8217 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8218 ConnectRequestHeaders("mail.example.org:443"), 0,
8219 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208220 // Return an error, so the transaction stops here (this test isn't interested
8221 // in the rest).
8222 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8223
8224 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8225
8226 CreateSession();
8227
8228 request_.url = GURL("https://mail.example.org/");
8229 HttpNetworkTransaction trans(request_priority, session_.get());
8230 TestCompletionCallback callback;
8231 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8232 EXPECT_EQ(ERR_IO_PENDING, rv);
8233 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8234
8235 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8236 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8237}
8238
Matt Menkeedaf3b82019-03-14 21:39:448239// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8240// HTTP/2 stream dependency and weights given the request priority.
8241TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8242 session_params_.enable_quic = true;
8243 session_params_.enable_quic_proxies_for_https_urls = true;
8244 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8245 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8246
8247 const RequestPriority kRequestPriority = MEDIUM;
8248 const RequestPriority kRequestPriority2 = LOWEST;
8249
8250 MockQuicData mock_quic_data;
8251 quic::QuicStreamOffset header_stream_offset = 0;
8252 mock_quic_data.AddWrite(
8253 ASYNC, ConstructInitialSettingsPacket(1, &header_stream_offset));
8254 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8255 // This should never be reached.
8256 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8257 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8258
8259 // Second connection attempt just fails - result doesn't really matter.
8260 MockQuicData mock_quic_data2;
8261 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8262 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8263
8264 int original_max_sockets_per_group =
8265 ClientSocketPoolManager::max_sockets_per_group(
8266 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8267 ClientSocketPoolManager::set_max_sockets_per_group(
8268 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8269 int original_max_sockets_per_pool =
8270 ClientSocketPoolManager::max_sockets_per_pool(
8271 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8272 ClientSocketPoolManager::set_max_sockets_per_pool(
8273 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8274 CreateSession();
8275
8276 request_.url = GURL("https://mail.example.org/");
8277 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8278 TestCompletionCallback callback;
8279 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8280 EXPECT_EQ(ERR_IO_PENDING, rv);
8281
8282 HttpRequestInfo request2;
8283 request2.url = GURL("https://mail.example.org/some/other/path/");
8284 request2.traffic_annotation =
8285 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8286
8287 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8288 TestCompletionCallback callback2;
8289 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8290 EXPECT_EQ(ERR_IO_PENDING, rv2);
8291
8292 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8293 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8294
8295 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8296
8297 ClientSocketPoolManager::set_max_sockets_per_pool(
8298 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8299 original_max_sockets_per_pool);
8300 ClientSocketPoolManager::set_max_sockets_per_group(
8301 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8302 original_max_sockets_per_group);
8303}
8304
Yixin Wang46a273ec302018-01-23 17:59:568305// Test the request-challenge-retry sequence for basic auth, over a QUIC
8306// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148307TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568308 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8309 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568310
8311 std::unique_ptr<QuicTestPacketMaker> client_maker;
8312 std::unique_ptr<QuicTestPacketMaker> server_maker;
8313
8314 // On the second pass, the body read of the auth challenge is synchronous, so
8315 // IsConnectedAndIdle returns false. The socket should still be drained and
8316 // reused. See http://crbug.com/544255.
8317 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338318 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178319 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8320 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338321 client_headers_include_h2_stream_dependency_));
8322 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178323 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8324 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568325
8326 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148327 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568328 proxy_resolution_service_ =
8329 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498330 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568331
8332 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528333 quic::QuicStreamOffset client_header_stream_offset = 0;
8334 quic::QuicStreamOffset server_header_stream_offset = 0;
8335 quic::QuicStreamOffset client_data_offset = 0;
8336 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568337
Zhongyi Shi32f2fd02018-04-16 18:23:438338 mock_quic_data.AddWrite(SYNCHRONOUS,
8339 client_maker->MakeInitialSettingsPacket(
8340 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568341
8342 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438343 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568344 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338345 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
Matt Menke6e879bd2019-03-18 17:26:048346 ConvertRequestPriorityToQuicPriority(
8347 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568348 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8349 &client_header_stream_offset));
8350
Ryan Hamilton0239aac2018-05-19 00:03:138351 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568352 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8353 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8354 headers["content-length"] = "10";
8355 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438356 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338357 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8358 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568359
8360 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438361 mock_quic_data.AddRead(
8362 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338363 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8364 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568365 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438366 mock_quic_data.AddRead(
8367 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338368 2, GetNthClientInitiatedBidirectionalStreamId(0),
8369 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568370 }
8371 server_data_offset += 10;
8372
Zhongyi Shi32f2fd02018-04-16 18:23:438373 mock_quic_data.AddWrite(SYNCHRONOUS,
8374 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568375
8376 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338377 SYNCHRONOUS,
8378 client_maker->MakeRstPacket(
8379 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188380 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8381 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568382
8383 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8384 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8385 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048386 SYNCHRONOUS,
8387 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8388 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8389 ConvertRequestPriorityToQuicPriority(
8390 HttpProxyConnectJob::kH2QuicTunnelPriority),
8391 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
8392 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568393
8394 // Response to wrong password
8395 headers =
8396 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8397 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8398 headers["content-length"] = "10";
8399 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438400 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338401 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8402 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568403 mock_quic_data.AddRead(SYNCHRONOUS,
8404 ERR_IO_PENDING); // No more data to read
8405
Fan Yang32c5a112018-12-10 20:06:338406 mock_quic_data.AddWrite(
8407 SYNCHRONOUS,
8408 client_maker->MakeAckAndRstPacket(
8409 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8410 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568411
8412 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8413 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8414
8415 CreateSession();
8416
8417 request_.url = GURL("https://mail.example.org/");
8418 // Ensure that proxy authentication is attempted even
8419 // when the no authentication data flag is set.
8420 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8421 {
8422 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8423 HeadersHandler headers_handler;
8424 trans.SetBeforeHeadersSentCallback(
8425 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8426 base::Unretained(&headers_handler)));
8427 RunTransaction(&trans);
8428
8429 const HttpResponseInfo* response = trans.GetResponseInfo();
8430 ASSERT_TRUE(response != nullptr);
8431 ASSERT_TRUE(response->headers.get() != nullptr);
8432 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8433 response->headers->GetStatusLine());
8434 EXPECT_TRUE(response->headers->IsKeepAlive());
8435 EXPECT_EQ(407, response->headers->response_code());
8436 EXPECT_EQ(10, response->headers->GetContentLength());
8437 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588438 base::Optional<AuthChallengeInfo> auth_challenge =
8439 response->auth_challenge;
8440 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568441 EXPECT_TRUE(auth_challenge->is_proxy);
8442 EXPECT_EQ("https://proxy.example.org:70",
8443 auth_challenge->challenger.Serialize());
8444 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8445 EXPECT_EQ("basic", auth_challenge->scheme);
8446
8447 TestCompletionCallback callback;
8448 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8449 callback.callback());
8450 EXPECT_EQ(ERR_IO_PENDING, rv);
8451 EXPECT_EQ(OK, callback.WaitForResult());
8452
8453 response = trans.GetResponseInfo();
8454 ASSERT_TRUE(response != nullptr);
8455 ASSERT_TRUE(response->headers.get() != nullptr);
8456 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8457 response->headers->GetStatusLine());
8458 EXPECT_TRUE(response->headers->IsKeepAlive());
8459 EXPECT_EQ(407, response->headers->response_code());
8460 EXPECT_EQ(10, response->headers->GetContentLength());
8461 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588462 auth_challenge = response->auth_challenge;
8463 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568464 EXPECT_TRUE(auth_challenge->is_proxy);
8465 EXPECT_EQ("https://proxy.example.org:70",
8466 auth_challenge->challenger.Serialize());
8467 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8468 EXPECT_EQ("basic", auth_challenge->scheme);
8469 }
8470 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8471 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8472 // reused because it's not connected).
8473 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8474 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8475 }
8476}
8477
Yixin Wang385652a2018-02-16 02:37:238478TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8479 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8480 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268481 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238482 !client_headers_include_h2_stream_dependency_) {
8483 return;
8484 }
8485
8486 session_params_.origins_to_force_quic_on.insert(
8487 HostPortPair::FromString("mail.example.org:443"));
8488
Fan Yang32c5a112018-12-10 20:06:338489 const quic::QuicStreamId client_stream_0 =
8490 GetNthClientInitiatedBidirectionalStreamId(0);
8491 const quic::QuicStreamId client_stream_1 =
8492 GetNthClientInitiatedBidirectionalStreamId(1);
8493 const quic::QuicStreamId client_stream_2 =
8494 GetNthClientInitiatedBidirectionalStreamId(2);
8495 const quic::QuicStreamId push_stream_0 =
8496 GetNthServerInitiatedUnidirectionalStreamId(0);
8497 const quic::QuicStreamId push_stream_1 =
8498 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238499
8500 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528501 quic::QuicStreamOffset header_stream_offset = 0;
8502 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238503 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438504 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238505
8506 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438507 mock_quic_data.AddWrite(SYNCHRONOUS,
8508 ConstructClientRequestHeadersPacket(
8509 2, client_stream_0, true, true, HIGHEST,
8510 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8511 &header_stream_offset));
8512 mock_quic_data.AddWrite(SYNCHRONOUS,
8513 ConstructClientRequestHeadersPacket(
8514 3, client_stream_1, true, true, MEDIUM,
8515 GetRequestHeaders("GET", "https", "/1.jpg"),
8516 client_stream_0, &header_stream_offset));
8517 mock_quic_data.AddWrite(SYNCHRONOUS,
8518 ConstructClientRequestHeadersPacket(
8519 4, client_stream_2, true, true, MEDIUM,
8520 GetRequestHeaders("GET", "https", "/2.jpg"),
8521 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238522
8523 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438524 mock_quic_data.AddRead(
8525 ASYNC, ConstructServerResponseHeadersPacket(
8526 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8527 &server_header_offset));
8528 mock_quic_data.AddRead(
8529 ASYNC, ConstructServerResponseHeadersPacket(
8530 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8531 &server_header_offset));
8532 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8533 mock_quic_data.AddRead(
8534 ASYNC, ConstructServerResponseHeadersPacket(
8535 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8536 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238537
8538 // Server sends two push promises associated with |client_stream_0|; client
8539 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8540 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438541 mock_quic_data.AddRead(ASYNC,
8542 ConstructServerPushPromisePacket(
8543 4, client_stream_0, push_stream_0, false,
8544 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8545 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238546 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438547 SYNCHRONOUS,
8548 ConstructClientAckAndPriorityFramesPacket(
8549 6, false, 4, 3, 1,
8550 {{push_stream_0, client_stream_2,
8551 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8552 &header_stream_offset));
8553 mock_quic_data.AddRead(ASYNC,
8554 ConstructServerPushPromisePacket(
8555 5, client_stream_0, push_stream_1, false,
8556 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8557 &server_header_offset, &server_maker_));
8558 mock_quic_data.AddWrite(
8559 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238560 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8561 DEFAULT_PRIORITY, &header_stream_offset));
8562
8563 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438564 mock_quic_data.AddRead(
8565 ASYNC, ConstructServerResponseHeadersPacket(
8566 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8567 &server_header_offset));
8568 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8569 mock_quic_data.AddRead(
8570 ASYNC, ConstructServerResponseHeadersPacket(
8571 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8572 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238573
8574 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8575 // priority updates to match the request's priority. Client sends PRIORITY
8576 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438577 mock_quic_data.AddWrite(
8578 SYNCHRONOUS,
8579 ConstructClientAckAndPriorityFramesPacket(
8580 9, false, 7, 7, 1,
8581 {{push_stream_1, client_stream_2,
8582 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8583 {push_stream_0, client_stream_0,
8584 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8585 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238586
8587 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438588 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438589 mock_quic_data.AddRead(
8590 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418591 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438592 mock_quic_data.AddRead(
8593 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418594 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438595 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8596 mock_quic_data.AddRead(
8597 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418598 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438599 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438600 mock_quic_data.AddRead(
8601 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418602 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438603 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8604 mock_quic_data.AddRead(
8605 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418606 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238607
Yixin Wang385652a2018-02-16 02:37:238608 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8609 mock_quic_data.AddRead(ASYNC, 0); // EOF
8610 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8611
8612 // The non-alternate protocol job needs to hang in order to guarantee that
8613 // the alternate-protocol job will "win".
8614 AddHangingNonAlternateProtocolSocketData();
8615
8616 CreateSession();
8617
8618 request_.url = GURL("https://mail.example.org/0.jpg");
8619 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8620 TestCompletionCallback callback_0;
8621 EXPECT_EQ(ERR_IO_PENDING,
8622 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8623 base::RunLoop().RunUntilIdle();
8624
8625 request_.url = GURL("https://mail.example.org/1.jpg");
8626 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8627 TestCompletionCallback callback_1;
8628 EXPECT_EQ(ERR_IO_PENDING,
8629 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8630 base::RunLoop().RunUntilIdle();
8631
8632 request_.url = GURL("https://mail.example.org/2.jpg");
8633 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8634 TestCompletionCallback callback_2;
8635 EXPECT_EQ(ERR_IO_PENDING,
8636 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8637 base::RunLoop().RunUntilIdle();
8638
8639 // Client makes request that matches resource pushed in |pushed_stream_0|.
8640 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8641 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8642 TestCompletionCallback callback_3;
8643 EXPECT_EQ(ERR_IO_PENDING,
8644 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8645 base::RunLoop().RunUntilIdle();
8646
8647 EXPECT_TRUE(callback_0.have_result());
8648 EXPECT_EQ(OK, callback_0.WaitForResult());
8649 EXPECT_TRUE(callback_1.have_result());
8650 EXPECT_EQ(OK, callback_1.WaitForResult());
8651 EXPECT_TRUE(callback_2.have_result());
8652 EXPECT_EQ(OK, callback_2.WaitForResult());
8653
8654 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8655 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8656 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8657 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8658
8659 mock_quic_data.Resume();
8660 base::RunLoop().RunUntilIdle();
8661 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8662 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8663}
8664
[email protected]61a527782013-02-21 03:58:008665} // namespace test
8666} // namespace net