blob: ccffb7386c0f7fc9c255fe17a23cd9b92b9bc58a [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) {
Nick Harper23290b82019-05-02 00:02:56122 os << "{ version: " << ParsedQuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45123 << ", 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
Nick Harper23290b82019-05-02 00:02:56141 quic::ParsedQuicVersion 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(
Nick Harper23290b82019-05-02 00:02:56147 const quic::ParsedQuicVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21148 std::string result = "";
Nick Harper23290b82019-05-02 00:02:56149 for (const quic::ParsedQuicVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21150 if (!result.empty())
151 result.append(",");
Nick Harper23290b82019-05-02 00:02:56152 result.append(base::NumberToString(version.transport_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;
Nick Harper23290b82019-05-02 00:02:56159 quic::ParsedQuicVersionVector all_supported_versions =
160 quic::AllSupportedVersions();
161 for (const quic::ParsedQuicVersion 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<
Nick Harper23290b82019-05-02 00:02:56259 std::tuple<quic::ParsedQuicVersion, bool>>,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52260 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())),
Nick Harper23290b82019-05-02 00:02:56265 supported_versions_(quic::test::SupportedVersions(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) {
Nick Harper23290b82019-05-02 00:02:56678 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41679 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
Nick Harper23290b82019-05-02 00:02:56687 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41688 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21689 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05690 session_params_.quic_headers_include_h2_stream_dependency =
691 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00692
mmenke6ddfbea2017-05-31 21:48:41693 session_context_.quic_clock = &clock_;
694 session_context_.quic_random = &random_generator_;
695 session_context_.client_socket_factory = &socket_factory_;
696 session_context_.quic_crypto_client_stream_factory =
697 &crypto_client_stream_factory_;
698 session_context_.host_resolver = &host_resolver_;
699 session_context_.cert_verifier = &cert_verifier_;
700 session_context_.transport_security_state = &transport_security_state_;
701 session_context_.cert_transparency_verifier =
702 cert_transparency_verifier_.get();
703 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
704 session_context_.socket_performance_watcher_factory =
705 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59706 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41707 session_context_.ssl_config_service = ssl_config_service_.get();
708 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
709 session_context_.http_server_properties = &http_server_properties_;
710 session_context_.net_log = net_log_.bound().net_log();
711
712 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12713 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56714 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
715 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00716 }
717
zhongyi86838d52017-06-30 01:19:44718 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21719
bnc691fda62016-08-12 00:43:16720 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19721 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42722 ASSERT_TRUE(response != nullptr);
723 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19724 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
725 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52726 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:56727 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
728 version_.transport_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) {
Nick Harper23290b82019-05-02 00:02:56938 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
939 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36940 }
941
Fan Yang32c5a112018-12-10 20:06:33942 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56943 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
944 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36945 }
946
Bence Béky230ac612017-08-30 19:17:08947 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49948 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08949 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49950 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08951 }
952
Nick Harper23290b82019-05-02 00:02:56953 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05954 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56955 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01956 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52957 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17958 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58959 QuicTestPacketMaker client_maker_;
960 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42961 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00962 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56963 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05964 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43965 MockHostResolver host_resolver_;
966 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11967 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42968 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23969 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38970 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07971 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59972 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42973 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07974 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41975 HttpNetworkSession::Params session_params_;
976 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19977 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51978 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42979 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56980 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03981 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12982
983 private:
984 void SendRequestAndExpectQuicResponseMaybeFromProxy(
985 const std::string& expected,
bnc62a44f022015-04-02 15:59:41986 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46987 uint16_t port) {
bnc691fda62016-08-12 00:43:16988 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09989 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16990 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09991 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
992 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16993 RunTransaction(&trans);
994 CheckWasQuicResponse(&trans);
995 CheckResponsePort(&trans, port);
996 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09997 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47998 if (used_proxy) {
999 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1000 } else {
1001 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1002 }
tbansal7cec3812015-02-05 21:25:121003 }
[email protected]61a527782013-02-21 03:58:001004};
1005
Victor Costane635086f2019-01-27 05:20:301006INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231007 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051008 QuicNetworkTransactionTest,
Nick Harper23290b82019-05-02 00:02:561009 ::testing::Combine(::testing::ValuesIn(quic::AllSupportedVersions()),
1010 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201011
Ryan Hamiltona64a5bcf2017-11-30 07:35:281012TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481013 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281014 base::HistogramTester histograms;
1015 session_params_.origins_to_force_quic_on.insert(
1016 HostPortPair::FromString("mail.example.org:443"));
1017 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271018 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281019
1020 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521021 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281022 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431023 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281024 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1025 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1026 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1027
1028 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1029
1030 CreateSession();
1031
1032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1033 TestCompletionCallback callback;
1034 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1035 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1036 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1037
1038 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1039 -ERR_INTERNET_DISCONNECTED, 1);
1040 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1041 -ERR_INTERNET_DISCONNECTED, 1);
1042}
1043
1044TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481045 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281046 base::HistogramTester histograms;
1047 session_params_.origins_to_force_quic_on.insert(
1048 HostPortPair::FromString("mail.example.org:443"));
1049 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271050 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281051
1052 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521053 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281054 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431055 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281056 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1057 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1058 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1059
1060 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1061
1062 CreateSession();
1063
1064 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1065 TestCompletionCallback callback;
1066 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1068 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1069
1070 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1071 -ERR_INTERNET_DISCONNECTED, 1);
1072 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1073 -ERR_INTERNET_DISCONNECTED, 1);
1074}
1075
tbansal180587c2017-02-16 15:13:231076TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411077 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231078 HostPortPair::FromString("mail.example.org:443"));
1079
1080 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521081 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361082 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431083 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1084 mock_quic_data.AddWrite(
1085 SYNCHRONOUS,
1086 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331087 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431088 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431089 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331090 ASYNC, ConstructServerResponseHeadersPacket(
1091 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1092 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431093 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331094 mock_quic_data.AddRead(
1095 ASYNC, ConstructServerDataPacket(
1096 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411097 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431098 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231099 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1100
1101 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1102
1103 CreateSession();
1104 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1105
1106 EXPECT_FALSE(
1107 test_socket_performance_watcher_factory_.rtt_notification_received());
1108 SendRequestAndExpectQuicResponse("hello!");
1109 EXPECT_TRUE(
1110 test_socket_performance_watcher_factory_.rtt_notification_received());
1111}
1112
1113TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411114 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231115 HostPortPair::FromString("mail.example.org:443"));
1116
1117 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521118 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361119 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431120 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1121 mock_quic_data.AddWrite(
1122 SYNCHRONOUS,
1123 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331124 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431125 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431126 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331127 ASYNC, ConstructServerResponseHeadersPacket(
1128 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1129 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431130 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331131 mock_quic_data.AddRead(
1132 ASYNC, ConstructServerDataPacket(
1133 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411134 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431135 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231136 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1137
1138 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1139
1140 CreateSession();
1141 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1142
1143 EXPECT_FALSE(
1144 test_socket_performance_watcher_factory_.rtt_notification_received());
1145 SendRequestAndExpectQuicResponse("hello!");
1146 EXPECT_FALSE(
1147 test_socket_performance_watcher_factory_.rtt_notification_received());
1148}
1149
[email protected]1e960032013-12-20 19:00:201150TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411151 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571152 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471153
[email protected]1e960032013-12-20 19:00:201154 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521155 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361156 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431157 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1158 mock_quic_data.AddWrite(
1159 SYNCHRONOUS,
1160 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331161 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431162 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431163 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331164 ASYNC, ConstructServerResponseHeadersPacket(
1165 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1166 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431167 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331168 mock_quic_data.AddRead(
1169 ASYNC, ConstructServerDataPacket(
1170 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411171 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431172 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591173 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471174
rcha5399e02015-04-21 19:32:041175 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471176
[email protected]4dca587c2013-03-07 16:54:471177 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471178
[email protected]aa9b14d2013-05-10 23:45:191179 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471180
[email protected]98b20ce2013-05-10 05:55:261181 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461182 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191183 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261184 EXPECT_LT(0u, entries.size());
1185
1186 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291187 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001188 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1189 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261190 EXPECT_LT(0, pos);
1191
rchfd527212015-08-25 00:41:261192 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291193 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261194 entries, 0,
mikecirone8b85c432016-09-08 19:11:001195 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1196 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261197 EXPECT_LT(0, pos);
1198
Eric Romanaefc98c2018-12-18 21:38:011199 int packet_number;
1200 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1201 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261202
rchfd527212015-08-25 00:41:261203 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1204 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001205 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1206 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261207 EXPECT_LT(0, pos);
1208
[email protected]98b20ce2013-05-10 05:55:261209 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291210 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001211 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1212 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261213 EXPECT_LT(0, pos);
1214
1215 int log_stream_id;
1216 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Nick Harper23290b82019-05-02 00:02:561217 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
Fan Yang7c68f632018-11-06 03:05:381218 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471219}
1220
rchbd089ab2017-05-26 23:05:041221TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411222 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041223 HostPortPair::FromString("mail.example.org:443"));
1224
1225 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521226 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041227 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431228 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1229 mock_quic_data.AddWrite(
1230 SYNCHRONOUS,
1231 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331232 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431233 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131234 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041235 response_headers["key1"] = std::string(30000, 'A');
1236 response_headers["key2"] = std::string(30000, 'A');
1237 response_headers["key3"] = std::string(30000, 'A');
1238 response_headers["key4"] = std::string(30000, 'A');
1239 response_headers["key5"] = std::string(30000, 'A');
1240 response_headers["key6"] = std::string(30000, 'A');
1241 response_headers["key7"] = std::string(30000, 'A');
1242 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331243 spdy::SpdyHeadersIR headers_frame(
1244 GetNthClientInitiatedBidirectionalStreamId(0),
1245 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131246 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1247 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041248 response_framer.SerializeFrame(headers_frame);
1249
Fan Yangac867502019-01-28 21:10:231250 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041251 size_t chunk_size = 1200;
1252 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1253 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431254 mock_quic_data.AddRead(
Nick Harper23290b82019-05-02 00:02:561255 ASYNC,
1256 ConstructServerDataPacket(
1257 packet_number++,
1258 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1259 false, false, offset,
1260 base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041261 }
1262
Victor Vasiliev076657c2019-03-12 02:46:431263 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041264 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331265 ASYNC, ConstructServerDataPacket(
1266 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411267 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041268 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431269 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1270 mock_quic_data.AddWrite(ASYNC,
1271 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041272
1273 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1274
1275 CreateSession();
1276
1277 SendRequestAndExpectQuicResponse("hello!");
1278}
1279
1280TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481281 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411282 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041283 HostPortPair::FromString("mail.example.org:443"));
1284
1285 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521286 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041287 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431288 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1289 mock_quic_data.AddWrite(
1290 SYNCHRONOUS,
1291 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331292 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431293 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131294 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041295 response_headers["key1"] = std::string(30000, 'A');
1296 response_headers["key2"] = std::string(30000, 'A');
1297 response_headers["key3"] = std::string(30000, 'A');
1298 response_headers["key4"] = std::string(30000, 'A');
1299 response_headers["key5"] = std::string(30000, 'A');
1300 response_headers["key6"] = std::string(30000, 'A');
1301 response_headers["key7"] = std::string(30000, 'A');
1302 response_headers["key8"] = std::string(30000, 'A');
1303 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331304 spdy::SpdyHeadersIR headers_frame(
1305 GetNthClientInitiatedBidirectionalStreamId(0),
1306 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131307 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1308 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041309 response_framer.SerializeFrame(headers_frame);
1310
Fan Yangac867502019-01-28 21:10:231311 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041312 size_t chunk_size = 1200;
1313 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1314 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431315 mock_quic_data.AddRead(
Nick Harper23290b82019-05-02 00:02:561316 ASYNC,
1317 ConstructServerDataPacket(
1318 packet_number++,
1319 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1320 false, false, offset,
1321 base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041322 }
1323
Victor Vasiliev076657c2019-03-12 02:46:431324 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411325
rchbd089ab2017-05-26 23:05:041326 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331327 ASYNC, ConstructServerDataPacket(
1328 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411329 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041330 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431331 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1332 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331333 ASYNC, ConstructClientAckAndRstPacket(
1334 4, GetNthClientInitiatedBidirectionalStreamId(0),
1335 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041336
1337 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1338
1339 CreateSession();
1340
1341 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1342 TestCompletionCallback callback;
1343 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1344 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1345 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1346}
1347
rcha2bd44b2016-07-02 00:42:551348TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411349 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551350
Ryan Hamilton9835e662018-08-02 05:36:271351 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551352
1353 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521354 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361355 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431356 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1357 mock_quic_data.AddWrite(
1358 SYNCHRONOUS,
1359 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331360 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431361 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431362 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331363 ASYNC, ConstructServerResponseHeadersPacket(
1364 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1365 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431366 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331367 mock_quic_data.AddRead(
1368 ASYNC, ConstructServerDataPacket(
1369 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411370 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431371 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551372 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1373
1374 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1375
1376 CreateSession();
1377
1378 SendRequestAndExpectQuicResponse("hello!");
1379 EXPECT_TRUE(
1380 test_socket_performance_watcher_factory_.rtt_notification_received());
1381}
1382
[email protected]cf3e3cd62014-02-05 16:16:161383TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411384 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591385 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491386 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161387
[email protected]cf3e3cd62014-02-05 16:16:161388 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521389 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361390 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431391 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1392 mock_quic_data.AddWrite(
1393 SYNCHRONOUS,
1394 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331395 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431396 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431397 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331398 ASYNC, ConstructServerResponseHeadersPacket(
1399 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1400 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431401 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331402 mock_quic_data.AddRead(
1403 ASYNC, ConstructServerDataPacket(
1404 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411405 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431406 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501407 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591408 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161409
rcha5399e02015-04-21 19:32:041410 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161411
tbansal0f56a39a2016-04-07 22:03:381412 EXPECT_FALSE(
1413 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161414 // There is no need to set up an alternate protocol job, because
1415 // no attempt will be made to speak to the proxy over TCP.
1416
rch9ae5b3b2016-02-11 00:36:291417 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161418 CreateSession();
1419
bnc62a44f022015-04-02 15:59:411420 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381421 EXPECT_TRUE(
1422 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161423}
1424
bnc313ba9c2015-06-11 15:42:311425// Regression test for https://crbug.com/492458. Test that for an HTTP
1426// connection through a QUIC proxy, the certificate exhibited by the proxy is
1427// checked against the proxy hostname, not the origin hostname.
1428TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291429 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311430 const std::string proxy_host = "www.example.org";
1431
mmenke6ddfbea2017-05-31 21:48:411432 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591433 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491434 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311435
alyssar2adf3ac2016-05-03 17:12:581436 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311437 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521438 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361439 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431440 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1441 mock_quic_data.AddWrite(
1442 SYNCHRONOUS,
1443 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331444 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431445 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431446 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331447 ASYNC, ConstructServerResponseHeadersPacket(
1448 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1449 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431450 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331451 mock_quic_data.AddRead(
1452 ASYNC, ConstructServerDataPacket(
1453 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411454 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431455 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501456 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591457 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311458 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1459
1460 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291461 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311462 ASSERT_TRUE(cert.get());
1463 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241464 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1465 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311466 ProofVerifyDetailsChromium verify_details;
1467 verify_details.cert_verify_result.verified_cert = cert;
1468 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561469 ProofVerifyDetailsChromium verify_details2;
1470 verify_details2.cert_verify_result.verified_cert = cert;
1471 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311472
1473 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091474 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321475 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271476 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311477 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1478}
1479
rchbe69cb902016-02-11 01:10:481480TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341481 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481482 HostPortPair origin("www.example.org", 443);
1483 HostPortPair alternative("mail.example.org", 443);
1484
1485 base::FilePath certs_dir = GetTestCertsDirectory();
1486 scoped_refptr<X509Certificate> cert(
1487 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1488 ASSERT_TRUE(cert.get());
1489 // TODO(rch): the connection should be "to" the origin, so if the cert is
1490 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241491 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1492 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481493 ProofVerifyDetailsChromium verify_details;
1494 verify_details.cert_verify_result.verified_cert = cert;
1495 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1496
alyssar2adf3ac2016-05-03 17:12:581497 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481498 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521499 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361500 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431501 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1502 mock_quic_data.AddWrite(
1503 SYNCHRONOUS,
1504 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331505 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431506 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431507 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331508 ASYNC, ConstructServerResponseHeadersPacket(
1509 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1510 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431511 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331512 mock_quic_data.AddRead(
1513 ASYNC, ConstructServerDataPacket(
1514 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411515 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431516 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481517 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1518 mock_quic_data.AddRead(ASYNC, 0);
1519 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1520
1521 request_.url = GURL("https://" + origin.host());
1522 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271523 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091524 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321525 CreateSession();
rchbe69cb902016-02-11 01:10:481526
1527 SendRequestAndExpectQuicResponse("hello!");
1528}
1529
zhongyief3f4ce52017-07-05 23:53:281530TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561531 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281532 // Add support for another QUIC version besides |version_|. Also find a
1533 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561534 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281535 if (version == version_)
1536 continue;
1537 if (supported_versions_.size() != 2) {
1538 supported_versions_.push_back(version);
1539 continue;
1540 }
1541 unsupported_version = version;
1542 break;
1543 }
Nick Harper23290b82019-05-02 00:02:561544 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281545
1546 // Set up alternative service to use QUIC with a version that is not
1547 // supported.
1548 url::SchemeHostPort server(request_.url);
1549 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1550 443);
1551 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1552 http_server_properties_.SetQuicAlternativeService(
1553 server, alternative_service, expiration, {unsupported_version});
1554
1555 AlternativeServiceInfoVector alt_svc_info_vector =
1556 http_server_properties_.GetAlternativeServiceInfos(server);
1557 EXPECT_EQ(1u, alt_svc_info_vector.size());
1558 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1559 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1560 EXPECT_EQ(unsupported_version,
1561 alt_svc_info_vector[0].advertised_versions()[0]);
1562
1563 // First request should still be sent via TCP as the QUIC version advertised
1564 // in the stored AlternativeService is not supported by the client. However,
1565 // the response from the server will advertise new Alt-Svc with supported
1566 // versions.
1567 std::string advertised_versions_list_str =
Nick Harper23290b82019-05-02 00:02:561568 GenerateQuicVersionsListForAltSvcHeader(quic::AllSupportedVersions());
zhongyief3f4ce52017-07-05 23:53:281569 std::string altsvc_header =
1570 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1571 advertised_versions_list_str.c_str());
1572 MockRead http_reads[] = {
1573 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1574 MockRead("hello world"),
1575 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1576 MockRead(ASYNC, OK)};
1577
Ryan Sleevib8d7ea02018-05-07 20:01:011578 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281579 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081580 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281581 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1582
1583 // Second request should be sent via QUIC as a new list of verions supported
1584 // by the client has been advertised by the server.
1585 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521586 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281587 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431588 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1589 mock_quic_data.AddWrite(
1590 SYNCHRONOUS,
1591 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331592 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431593 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431594 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331595 ASYNC, ConstructServerResponseHeadersPacket(
1596 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1597 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431598 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331599 mock_quic_data.AddRead(
1600 ASYNC, ConstructServerDataPacket(
1601 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411602 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431603 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281604 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1605 mock_quic_data.AddRead(ASYNC, 0); // EOF
1606
1607 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1608
1609 AddHangingNonAlternateProtocolSocketData();
1610
1611 CreateSession(supported_versions_);
1612
1613 SendRequestAndExpectHttpResponse("hello world");
1614 SendRequestAndExpectQuicResponse("hello!");
1615
1616 // Check alternative service list is updated with new versions.
1617 alt_svc_info_vector =
1618 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1619 EXPECT_EQ(1u, alt_svc_info_vector.size());
1620 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1621 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1622 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561623 std::sort(
1624 supported_versions_.begin(), supported_versions_.end(),
1625 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1626 return a.transport_version < b.transport_version;
1627 });
zhongyief3f4ce52017-07-05 23:53:281628 EXPECT_EQ(supported_versions_[0],
1629 alt_svc_info_vector[0].advertised_versions()[0]);
1630 EXPECT_EQ(supported_versions_[1],
1631 alt_svc_info_vector[0].advertised_versions()[1]);
1632}
1633
bncaccd4962017-04-06 21:00:261634// Regression test for https://crbug.com/546991.
1635// The server might not be able to serve a request on an alternative connection,
1636// and might send a 421 Misdirected Request response status to indicate this.
1637// HttpNetworkTransaction should reset the request and retry without using
1638// alternative services.
1639TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1640 // Set up alternative service to use QUIC.
1641 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1642 // that overrides |enable_alternative_services|.
1643 url::SchemeHostPort server(request_.url);
1644 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1645 443);
1646 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211647 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441648 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261649
davidbena4449722017-05-05 23:30:531650 // First try: The alternative job uses QUIC and reports an HTTP 421
1651 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1652 // paused at Connect(), so it will never exit the socket pool. This ensures
1653 // that the alternate job always wins the race and keeps whether the
1654 // |http_data| exits the socket pool before the main job is aborted
1655 // deterministic. The first main job gets aborted without the socket pool ever
1656 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261657 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521658 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361659 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431660 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1661 mock_quic_data.AddWrite(
1662 SYNCHRONOUS,
1663 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331664 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431665 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331666 mock_quic_data.AddRead(
1667 ASYNC, ConstructServerResponseHeadersPacket(
1668 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1669 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261670 mock_quic_data.AddRead(ASYNC, OK);
1671 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1672
davidbena4449722017-05-05 23:30:531673 // Second try: The main job uses TCP, and there is no alternate job. Once the
1674 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1675 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261676 // Note that if there was an alternative QUIC Job created for the second try,
1677 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1678 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531679 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1680 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1681 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1682 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1683 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1684 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011685 reads, writes);
bncaccd4962017-04-06 21:00:261686 socket_factory_.AddSocketDataProvider(&http_data);
1687 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1688
bncaccd4962017-04-06 21:00:261689 CreateSession();
1690 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531691
1692 // Run until |mock_quic_data| has failed and |http_data| has paused.
1693 TestCompletionCallback callback;
1694 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1695 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1696 base::RunLoop().RunUntilIdle();
1697
1698 // |mock_quic_data| must have run to completion.
1699 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1700 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1701
1702 // Now that the QUIC data has been consumed, unblock |http_data|.
1703 http_data.socket()->OnConnectComplete(MockConnect());
1704
1705 // The retry logic must hide the 421 status. The transaction succeeds on
1706 // |http_data|.
1707 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261708 CheckWasHttpResponse(&trans);
1709 CheckResponsePort(&trans, 443);
1710 CheckResponseData(&trans, "hello!");
1711}
1712
[email protected]1e960032013-12-20 19:00:201713TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411714 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571715 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301716
tbansalfdf5665b2015-09-21 22:46:401717 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521718 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361719 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431720 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401721 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401722 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371723 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361724 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431725 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301726 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401727 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431728 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401729
1730 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1731 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301732
1733 CreateSession();
1734
tbansal0f56a39a2016-04-07 22:03:381735 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401736 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161737 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401738 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161739 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011740 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1741 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381742 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531743
1744 NetErrorDetails details;
1745 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521746 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401747 }
[email protected]cebe3282013-05-22 23:49:301748}
1749
tbansalc8a94ea2015-11-02 23:58:511750TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1751 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411752 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571753 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511754
1755 MockRead http_reads[] = {
1756 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1757 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1758 MockRead(ASYNC, OK)};
1759
Ryan Sleevib8d7ea02018-05-07 20:01:011760 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511761 socket_factory_.AddSocketDataProvider(&data);
1762 SSLSocketDataProvider ssl(ASYNC, OK);
1763 socket_factory_.AddSSLSocketDataProvider(&ssl);
1764
1765 CreateSession();
1766
1767 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381768 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511769}
1770
bncc958faa2015-07-31 18:14:521771TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521772 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561773 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1774 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521775 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1776 MockRead(ASYNC, OK)};
1777
Ryan Sleevib8d7ea02018-05-07 20:01:011778 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521779 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081780 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561781 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521782
1783 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521784 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361785 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431786 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1787 mock_quic_data.AddWrite(
1788 SYNCHRONOUS,
1789 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331790 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431791 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431792 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331793 ASYNC, ConstructServerResponseHeadersPacket(
1794 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1795 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431796 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331797 mock_quic_data.AddRead(
1798 ASYNC, ConstructServerDataPacket(
1799 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411800 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431801 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521802 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591803 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521804
1805 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1806
rtennetib8e80fb2016-05-16 00:12:091807 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321808 CreateSession();
bncc958faa2015-07-31 18:14:521809
1810 SendRequestAndExpectHttpResponse("hello world");
1811 SendRequestAndExpectQuicResponse("hello!");
1812}
1813
zhongyia00ca012017-07-06 23:36:391814TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1815 // Both server advertises and client supports two QUIC versions.
1816 // Only |version_| is advertised and supported.
1817 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1818 // PacketMakers are using |version_|.
1819
1820 // Add support for another QUIC version besides |version_| on the client side.
1821 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:561822 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
1823 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391824 if (version == version_)
1825 continue;
1826 if (supported_versions_.size() != 2) {
1827 supported_versions_.push_back(version);
1828 continue;
1829 }
1830 advertised_version_2 = version;
1831 break;
1832 }
Nick Harper23290b82019-05-02 00:02:561833 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391834
Nick Harper23290b82019-05-02 00:02:561835 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1836 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1837 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391838
1839 MockRead http_reads[] = {
1840 MockRead("HTTP/1.1 200 OK\r\n"),
1841 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1842 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1843 MockRead(ASYNC, OK)};
1844
Ryan Sleevib8d7ea02018-05-07 20:01:011845 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391846 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081847 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391848 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1849
1850 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521851 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391852 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431853 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1854 mock_quic_data.AddWrite(
1855 SYNCHRONOUS,
1856 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331857 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431858 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431859 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331860 ASYNC, ConstructServerResponseHeadersPacket(
1861 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1862 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431863 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331864 mock_quic_data.AddRead(
1865 ASYNC, ConstructServerDataPacket(
1866 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411867 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431868 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391869 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1870 mock_quic_data.AddRead(ASYNC, 0); // EOF
1871
1872 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1873
1874 AddHangingNonAlternateProtocolSocketData();
1875 CreateSession(supported_versions_);
1876
1877 SendRequestAndExpectHttpResponse("hello world");
1878 SendRequestAndExpectQuicResponse("hello!");
1879}
1880
1881TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1882 // Client and server mutually support more than one QUIC_VERSION.
1883 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1884 // which is verified as the PacketMakers are using |version_|.
1885
Nick Harper23290b82019-05-02 00:02:561886 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
1887 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391888 if (version == version_)
1889 continue;
1890 common_version_2 = version;
1891 break;
1892 }
Nick Harper23290b82019-05-02 00:02:561893 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391894
1895 supported_versions_.push_back(
1896 common_version_2); // Supported but unpreferred.
1897
1898 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:561899 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1900 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391901
1902 MockRead http_reads[] = {
1903 MockRead("HTTP/1.1 200 OK\r\n"),
1904 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1905 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1906 MockRead(ASYNC, OK)};
1907
Ryan Sleevib8d7ea02018-05-07 20:01:011908 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391909 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081910 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391911 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1912
1913 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521914 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391915 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431916 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1917 mock_quic_data.AddWrite(
1918 SYNCHRONOUS,
1919 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331920 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431921 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431922 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331923 ASYNC, ConstructServerResponseHeadersPacket(
1924 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1925 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431926 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331927 mock_quic_data.AddRead(
1928 ASYNC, ConstructServerDataPacket(
1929 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411930 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431931 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391932 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1933 mock_quic_data.AddRead(ASYNC, 0); // EOF
1934
1935 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1936
1937 AddHangingNonAlternateProtocolSocketData();
1938 CreateSession(supported_versions_);
1939
1940 SendRequestAndExpectHttpResponse("hello world");
1941 SendRequestAndExpectQuicResponse("hello!");
1942}
1943
rchf47265dc2016-03-21 21:33:121944TEST_P(QuicNetworkTransactionTest,
1945 UseAlternativeServiceWithProbabilityForQuic) {
1946 MockRead http_reads[] = {
1947 MockRead("HTTP/1.1 200 OK\r\n"),
1948 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1949 MockRead("hello world"),
1950 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1951 MockRead(ASYNC, OK)};
1952
Ryan Sleevib8d7ea02018-05-07 20:01:011953 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121954 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081955 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121956 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1957
1958 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521959 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361960 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431961 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1962 mock_quic_data.AddWrite(
1963 SYNCHRONOUS,
1964 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331965 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431966 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431967 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331968 ASYNC, ConstructServerResponseHeadersPacket(
1969 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1970 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431971 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331972 mock_quic_data.AddRead(
1973 ASYNC, ConstructServerDataPacket(
1974 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411975 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431976 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121977 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1978 mock_quic_data.AddRead(ASYNC, 0); // EOF
1979
1980 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1981
rtennetib8e80fb2016-05-16 00:12:091982 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121983 CreateSession();
1984
1985 SendRequestAndExpectHttpResponse("hello world");
1986 SendRequestAndExpectQuicResponse("hello!");
1987}
1988
zhongyi3d4a55e72016-04-22 20:36:461989TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1990 MockRead http_reads[] = {
1991 MockRead("HTTP/1.1 200 OK\r\n"),
1992 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1993 MockRead("hello world"),
1994 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1995 MockRead(ASYNC, OK)};
1996
Ryan Sleevib8d7ea02018-05-07 20:01:011997 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461998 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081999 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462000 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2001
2002 CreateSession();
bncb26024382016-06-29 02:39:452003 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462004 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452005 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462006 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402007 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462008 session_->http_server_properties();
2009 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2010 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2011 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462012 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342013 2u,
2014 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452015 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342016 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462017}
2018
2019TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2020 MockRead http_reads[] = {
2021 MockRead("HTTP/1.1 200 OK\r\n"),
2022 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2023 MockRead("hello world"),
2024 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2025 MockRead(ASYNC, OK)};
2026
Ryan Sleevib8d7ea02018-05-07 20:01:012027 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082028 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462029
2030 socket_factory_.AddSocketDataProvider(&http_data);
2031 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2032 socket_factory_.AddSocketDataProvider(&http_data);
2033 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2034
2035 CreateSession();
2036
2037 // Send https request and set alternative services if response header
2038 // advertises alternative service for mail.example.org.
2039 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402040 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462041 session_->http_server_properties();
2042
2043 const url::SchemeHostPort https_server(request_.url);
2044 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342045 EXPECT_EQ(
2046 2u,
2047 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462048
2049 // Send http request to the same origin but with diffrent scheme, should not
2050 // use QUIC.
2051 request_.url = GURL("http://mail.example.org:443");
2052 SendRequestAndExpectHttpResponse("hello world");
2053}
2054
zhongyie537a002017-06-27 16:48:212055TEST_P(QuicNetworkTransactionTest,
2056 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442057 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562058 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442059 if (version == version_)
2060 continue;
2061 supported_versions_.push_back(version);
2062 break;
2063 }
2064
zhongyie537a002017-06-27 16:48:212065 std::string advertised_versions_list_str =
Nick Harper23290b82019-05-02 00:02:562066 GenerateQuicVersionsListForAltSvcHeader(quic::AllSupportedVersions());
zhongyie537a002017-06-27 16:48:212067 std::string altsvc_header =
2068 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2069 advertised_versions_list_str.c_str());
2070 MockRead http_reads[] = {
2071 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2072 MockRead("hello world"),
2073 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2074 MockRead(ASYNC, OK)};
2075
Ryan Sleevib8d7ea02018-05-07 20:01:012076 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212077 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082078 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212079 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2080
2081 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522082 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212083 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432084 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2085 mock_quic_data.AddWrite(
2086 SYNCHRONOUS,
2087 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332088 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432089 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432090 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332091 ASYNC, ConstructServerResponseHeadersPacket(
2092 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2093 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432094 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332095 mock_quic_data.AddRead(
2096 ASYNC, ConstructServerDataPacket(
2097 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412098 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432099 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212100 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2101 mock_quic_data.AddRead(ASYNC, 0); // EOF
2102
2103 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2104
2105 AddHangingNonAlternateProtocolSocketData();
2106
zhongyi86838d52017-06-30 01:19:442107 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212108
2109 SendRequestAndExpectHttpResponse("hello world");
2110 SendRequestAndExpectQuicResponse("hello!");
2111
2112 // Check alternative service is set with only mutually supported versions.
2113 const url::SchemeHostPort https_server(request_.url);
2114 const AlternativeServiceInfoVector alt_svc_info_vector =
2115 session_->http_server_properties()->GetAlternativeServiceInfos(
2116 https_server);
2117 EXPECT_EQ(1u, alt_svc_info_vector.size());
2118 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2119 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2120 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562121 std::sort(
2122 supported_versions_.begin(), supported_versions_.end(),
2123 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2124 return a.transport_version < b.transport_version;
2125 });
zhongyi86838d52017-06-30 01:19:442126 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212127 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442128 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212129 alt_svc_info_vector[0].advertised_versions()[1]);
2130}
2131
danzh3134c2562016-08-12 14:07:522132TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562133 std::string altsvc_header = base::StringPrintf(
2134 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072135 MockRead http_reads[] = {
2136 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2137 MockRead("hello world"),
2138 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2139 MockRead(ASYNC, OK)};
2140
Ryan Sleevib8d7ea02018-05-07 20:01:012141 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072142 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082143 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072144 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2145
2146 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522147 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362148 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432149 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2150 mock_quic_data.AddWrite(
2151 SYNCHRONOUS,
2152 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332153 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432154 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432155 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332156 ASYNC, ConstructServerResponseHeadersPacket(
2157 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2158 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432159 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332160 mock_quic_data.AddRead(
2161 ASYNC, ConstructServerDataPacket(
2162 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412163 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432164 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072165 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592166 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072167
2168 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2169
rtennetib8e80fb2016-05-16 00:12:092170 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322171 CreateSession();
bnc8be55ebb2015-10-30 14:12:072172
2173 SendRequestAndExpectHttpResponse("hello world");
2174 SendRequestAndExpectQuicResponse("hello!");
2175}
2176
zhongyi6b5a3892016-03-12 04:46:202177TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562178 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092179 // Not available under version 99
2180 return;
2181 }
zhongyi6b5a3892016-03-12 04:46:202182 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522183 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362184 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432185 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2186 mock_quic_data.AddWrite(
2187 SYNCHRONOUS,
2188 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332189 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432190 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332191 mock_quic_data.AddRead(
2192 ASYNC, ConstructServerResponseHeadersPacket(
2193 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2194 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202195 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522196 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432197 mock_quic_data.AddRead(SYNCHRONOUS,
2198 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522199 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432200 "connection migration with port change only"));
2201 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432202 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332203 mock_quic_data.AddRead(
2204 SYNCHRONOUS, ConstructServerDataPacket(
2205 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412206 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332207 mock_quic_data.AddWrite(SYNCHRONOUS,
2208 ConstructClientAckAndRstPacket(
2209 4, GetNthClientInitiatedBidirectionalStreamId(0),
2210 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202211 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2212 mock_quic_data.AddRead(ASYNC, 0); // EOF
2213
2214 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2215
2216 // The non-alternate protocol job needs to hang in order to guarantee that
2217 // the alternate-protocol job will "win".
2218 AddHangingNonAlternateProtocolSocketData();
2219
2220 // In order for a new QUIC session to be established via alternate-protocol
2221 // without racing an HTTP connection, we need the host resolution to happen
2222 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2223 // connection to the the server, in this test we require confirmation
2224 // before encrypting so the HTTP job will still start.
2225 host_resolver_.set_synchronous_mode(true);
2226 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2227 "");
zhongyi6b5a3892016-03-12 04:46:202228
2229 CreateSession();
2230 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272231 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202232
bnc691fda62016-08-12 00:43:162233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202234 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362235 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202237
2238 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522239 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012240 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202241
2242 // Check whether this transaction is correctly marked as received a go-away
2243 // because of migrating port.
2244 NetErrorDetails details;
2245 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162246 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202247 EXPECT_TRUE(details.quic_port_migration_detected);
2248}
2249
Zhongyi Shia6b68d112018-09-24 07:49:032250// This test verifies that a new QUIC connection will be attempted on the
2251// alternate network if the original QUIC connection fails with idle timeout
2252// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2253// alternate network as well, QUIC is marked as broken and the brokenness will
2254// not expire when default network changes.
2255TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Nick Harper23290b82019-05-02 00:02:562256 if (version_.transport_version >= quic::QUIC_VERSION_47) {
Michael Warres167db3e2019-03-01 21:38:032257 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2258 return;
2259 }
Zhongyi Shia6b68d112018-09-24 07:49:032260 SetUpTestForRetryConnectionOnAlternateNetwork();
2261
2262 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032263 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032264
2265 // The request will initially go out over QUIC.
2266 MockQuicData quic_data;
2267 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2268 int packet_num = 1;
2269 quic_data.AddWrite(SYNCHRONOUS,
2270 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2271 // Retranmit the handshake messages.
2272 quic_data.AddWrite(SYNCHRONOUS,
2273 client_maker_.MakeDummyCHLOPacket(packet_num++));
2274 quic_data.AddWrite(SYNCHRONOUS,
2275 client_maker_.MakeDummyCHLOPacket(packet_num++));
2276 quic_data.AddWrite(SYNCHRONOUS,
2277 client_maker_.MakeDummyCHLOPacket(packet_num++));
2278 quic_data.AddWrite(SYNCHRONOUS,
2279 client_maker_.MakeDummyCHLOPacket(packet_num++));
2280 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562281 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032282 quic_data.AddWrite(SYNCHRONOUS,
2283 client_maker_.MakeDummyCHLOPacket(packet_num++));
2284 }
2285 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2286 quic_data.AddWrite(SYNCHRONOUS,
2287 client_maker_.MakeConnectionClosePacket(
2288 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2289 "No recent network activity."));
2290 quic_data.AddSocketDataToFactory(&socket_factory_);
2291
2292 // Add successful TCP data so that TCP job will succeed.
2293 MockWrite http_writes[] = {
2294 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2295 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2296 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2297
2298 MockRead http_reads[] = {
2299 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2300 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2301 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2302 SequencedSocketData http_data(http_reads, http_writes);
2303 socket_factory_.AddSocketDataProvider(&http_data);
2304 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2305
2306 // Add data for the second QUIC connection to fail.
2307 MockQuicData quic_data2;
2308 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2309 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2310 quic_data2.AddSocketDataToFactory(&socket_factory_);
2311
2312 // Resolve the host resolution synchronously.
2313 host_resolver_.set_synchronous_mode(true);
2314 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2315 "");
Zhongyi Shia6b68d112018-09-24 07:49:032316
2317 CreateSession();
2318 session_->quic_stream_factory()->set_require_confirmation(true);
2319 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2320 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2321 QuicStreamFactoryPeer::SetAlarmFactory(
2322 session_->quic_stream_factory(),
2323 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2324 &clock_));
2325 // Add alternate protocol mapping to race QUIC and TCP.
2326 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2327 // peer.
2328 AddQuicAlternateProtocolMapping(
2329 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2330
2331 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2332 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362333 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032334 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2335
2336 // Pump the message loop to get the request started.
2337 // Request will be served with TCP job.
2338 base::RunLoop().RunUntilIdle();
2339 EXPECT_THAT(callback.WaitForResult(), IsOk());
2340 CheckResponseData(&trans, "TCP succeeds");
2341
2342 // Fire the retransmission alarm, from this point, connection will idle
2343 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062344 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182345 quic_fix_time_of_first_packet_sent_after_receiving)) {
2346 quic_task_runner_->RunNextTask();
2347 }
Zhongyi Shia6b68d112018-09-24 07:49:032348 // Fast forward to idle timeout the original connection. A new connection will
2349 // be kicked off on the alternate network.
2350 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2351 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2352 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2353
2354 // Run the message loop to execute posted tasks, which will report job status.
2355 base::RunLoop().RunUntilIdle();
2356
2357 // Verify that QUIC is marked as broken.
2358 ExpectBrokenAlternateProtocolMapping();
2359
2360 // Deliver a message to notify the new network becomes default, the brokenness
2361 // will not expire as QUIC is broken on both networks.
2362 scoped_mock_change_notifier_->mock_network_change_notifier()
2363 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2364 ExpectBrokenAlternateProtocolMapping();
2365
2366 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2367 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2368}
2369
2370// This test verifies that a new QUIC connection will be attempted on the
2371// alternate network if the original QUIC connection fails with idle timeout
2372// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2373// alternate network, QUIC is marked as broken. The brokenness will expire when
2374// the default network changes.
2375TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Nick Harper23290b82019-05-02 00:02:562376 if (version_.transport_version >= quic::QUIC_VERSION_47) {
Michael Warres167db3e2019-03-01 21:38:032377 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2378 return;
2379 }
Zhongyi Shia6b68d112018-09-24 07:49:032380 SetUpTestForRetryConnectionOnAlternateNetwork();
2381
2382 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032383 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032384
2385 // The request will initially go out over QUIC.
2386 MockQuicData quic_data;
2387 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2388 int packet_num = 1;
2389 quic_data.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2391 // Retranmit the handshake messages.
2392 quic_data.AddWrite(SYNCHRONOUS,
2393 client_maker_.MakeDummyCHLOPacket(packet_num++));
2394 quic_data.AddWrite(SYNCHRONOUS,
2395 client_maker_.MakeDummyCHLOPacket(packet_num++));
2396 quic_data.AddWrite(SYNCHRONOUS,
2397 client_maker_.MakeDummyCHLOPacket(packet_num++));
2398 quic_data.AddWrite(SYNCHRONOUS,
2399 client_maker_.MakeDummyCHLOPacket(packet_num++));
2400 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562401 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032402 quic_data.AddWrite(SYNCHRONOUS,
2403 client_maker_.MakeDummyCHLOPacket(packet_num++));
2404 }
2405 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2406 quic_data.AddWrite(SYNCHRONOUS,
2407 client_maker_.MakeConnectionClosePacket(
2408 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2409 "No recent network activity."));
2410 quic_data.AddSocketDataToFactory(&socket_factory_);
2411
2412 // Add successful TCP data so that TCP job will succeed.
2413 MockWrite http_writes[] = {
2414 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2415 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2416 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2417
2418 MockRead http_reads[] = {
2419 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2420 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2421 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2422 SequencedSocketData http_data(http_reads, http_writes);
2423 socket_factory_.AddSocketDataProvider(&http_data);
2424 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2425
2426 // Quic connection will be retried on the alternate network after the initial
2427 // one fails on the default network.
2428 MockQuicData quic_data2;
2429 quic::QuicStreamOffset header_stream_offset = 0;
2430 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2431 quic_data2.AddWrite(SYNCHRONOUS,
2432 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2433
2434 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2435 quic_data2.AddWrite(SYNCHRONOUS,
2436 ConstructInitialSettingsPacket(2, &header_stream_offset));
2437 quic_data2.AddSocketDataToFactory(&socket_factory_);
2438
2439 // Resolve the host resolution synchronously.
2440 host_resolver_.set_synchronous_mode(true);
2441 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2442 "");
Zhongyi Shia6b68d112018-09-24 07:49:032443
2444 CreateSession();
2445 session_->quic_stream_factory()->set_require_confirmation(true);
2446 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2447 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2448 QuicStreamFactoryPeer::SetAlarmFactory(
2449 session_->quic_stream_factory(),
2450 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2451 &clock_));
2452 // Add alternate protocol mapping to race QUIC and TCP.
2453 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2454 // peer.
2455 AddQuicAlternateProtocolMapping(
2456 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2457
2458 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2459 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362460 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032461 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2462
2463 // Pump the message loop to get the request started.
2464 // Request will be served with TCP job.
2465 base::RunLoop().RunUntilIdle();
2466 EXPECT_THAT(callback.WaitForResult(), IsOk());
2467 CheckResponseData(&trans, "TCP succeeds");
2468
2469 // Fire the retransmission alarm, after which connection will idle
2470 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062471 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182472 quic_fix_time_of_first_packet_sent_after_receiving)) {
2473 quic_task_runner_->RunNextTask();
2474 }
Zhongyi Shia6b68d112018-09-24 07:49:032475 // Fast forward to idle timeout the original connection. A new connection will
2476 // be kicked off on the alternate network.
2477 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2478 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2479 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2480
2481 // The second connection hasn't finish handshake, verify that QUIC is not
2482 // marked as broken.
2483 ExpectQuicAlternateProtocolMapping();
2484 // Explicitly confirm the handshake on the second connection.
2485 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2486 quic::QuicSession::HANDSHAKE_CONFIRMED);
2487 // Run message loop to execute posted tasks, which will notify JoController
2488 // about the orphaned job status.
2489 base::RunLoop().RunUntilIdle();
2490
2491 // Verify that QUIC is marked as broken.
2492 ExpectBrokenAlternateProtocolMapping();
2493
2494 // Deliver a message to notify the new network becomes default, the previous
2495 // brokenness will be clear as the brokenness is bond with old default
2496 // network.
2497 scoped_mock_change_notifier_->mock_network_change_notifier()
2498 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2499 ExpectQuicAlternateProtocolMapping();
2500
2501 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2502 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2503}
2504
2505// This test verifies that a new QUIC connection will be attempted on the
2506// alternate network if the original QUIC connection fails with idle timeout
2507// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2508// alternative network succeeds, QUIC is not marked as broken.
2509TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Nick Harper23290b82019-05-02 00:02:562510 if (version_.transport_version >= quic::QUIC_VERSION_47) {
Michael Warres167db3e2019-03-01 21:38:032511 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2512 return;
2513 }
Zhongyi Shia6b68d112018-09-24 07:49:032514 SetUpTestForRetryConnectionOnAlternateNetwork();
2515
2516 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032517 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032518
2519 // The request will initially go out over QUIC.
2520 MockQuicData quic_data;
2521 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2522 int packet_num = 1;
2523 quic_data.AddWrite(SYNCHRONOUS,
2524 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2525 // Retranmit the handshake messages.
2526 quic_data.AddWrite(SYNCHRONOUS,
2527 client_maker_.MakeDummyCHLOPacket(packet_num++));
2528 quic_data.AddWrite(SYNCHRONOUS,
2529 client_maker_.MakeDummyCHLOPacket(packet_num++));
2530 quic_data.AddWrite(SYNCHRONOUS,
2531 client_maker_.MakeDummyCHLOPacket(packet_num++));
2532 quic_data.AddWrite(SYNCHRONOUS,
2533 client_maker_.MakeDummyCHLOPacket(packet_num++));
2534 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2535 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562536 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032537 quic_data.AddWrite(SYNCHRONOUS,
2538 client_maker_.MakeDummyCHLOPacket(packet_num++));
2539 }
2540 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2541 quic_data.AddWrite(SYNCHRONOUS,
2542 client_maker_.MakeConnectionClosePacket(
2543 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2544 "No recent network activity."));
2545 quic_data.AddSocketDataToFactory(&socket_factory_);
2546
2547 // Add hanging TCP data so that TCP job will never succeeded.
2548 AddHangingNonAlternateProtocolSocketData();
2549
2550 // Quic connection will then be retried on the alternate network.
2551 MockQuicData quic_data2;
2552 quic::QuicStreamOffset header_stream_offset = 0;
2553 quic_data2.AddWrite(SYNCHRONOUS,
2554 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2555
Victor Vasiliev076657c2019-03-12 02:46:432556 const std::string body = "hello!";
2557 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412558
Zhongyi Shia6b68d112018-09-24 07:49:032559 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2560 quic_data2.AddWrite(SYNCHRONOUS,
2561 ConstructInitialSettingsPacket(2, &header_stream_offset));
2562 quic_data2.AddWrite(
2563 SYNCHRONOUS,
2564 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332565 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032566 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032567 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332568 ASYNC, ConstructServerResponseHeadersPacket(
2569 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2570 GetResponseHeaders("200 OK")));
2571 quic_data2.AddRead(
2572 ASYNC, ConstructServerDataPacket(
2573 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412574 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032575 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2576 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2577 quic_data2.AddSocketDataToFactory(&socket_factory_);
2578
2579 // Resolve the host resolution synchronously.
2580 host_resolver_.set_synchronous_mode(true);
2581 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2582 "");
Zhongyi Shia6b68d112018-09-24 07:49:032583
2584 CreateSession();
2585 session_->quic_stream_factory()->set_require_confirmation(true);
2586 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2587 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2588 QuicStreamFactoryPeer::SetAlarmFactory(
2589 session_->quic_stream_factory(),
2590 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2591 &clock_));
2592 // Add alternate protocol mapping to race QUIC and TCP.
2593 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2594 // peer.
2595 AddQuicAlternateProtocolMapping(
2596 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2597
2598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2599 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362600 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032601 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2602
2603 // Pump the message loop to get the request started.
2604 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062605 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182606 quic_fix_time_of_first_packet_sent_after_receiving)) {
2607 quic_task_runner_->RunNextTask();
2608 }
Zhongyi Shia6b68d112018-09-24 07:49:032609
2610 // Fast forward to idle timeout the original connection. A new connection will
2611 // be kicked off on the alternate network.
2612 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2613 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2614 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2615
2616 // Verify that QUIC is not marked as broken.
2617 ExpectQuicAlternateProtocolMapping();
2618 // Explicitly confirm the handshake on the second connection.
2619 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2620 quic::QuicSession::HANDSHAKE_CONFIRMED);
2621
2622 // Read the response.
2623 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412624 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032625 // Verify that QUIC is not marked as broken.
2626 ExpectQuicAlternateProtocolMapping();
2627
2628 // Deliver a message to notify the new network becomes default.
2629 scoped_mock_change_notifier_->mock_network_change_notifier()
2630 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2631 ExpectQuicAlternateProtocolMapping();
2632 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2633 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2634}
2635
rch9ecde09b2017-04-08 00:18:232636// Verify that if a QUIC connection times out, the QuicHttpStream will
2637// return QUIC_PROTOCOL_ERROR.
2638TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482639 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412640 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232641
2642 // The request will initially go out over QUIC.
2643 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522644 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132645 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232646 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2647
2648 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032649 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432650 quic_data.AddWrite(SYNCHRONOUS,
2651 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332652 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2653 true, priority, GetRequestHeaders("GET", "https", "/"),
2654 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232655
2656 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522657 quic::QuicStreamOffset settings_offset = header_stream_offset;
2658 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432659 quic_data.AddWrite(SYNCHRONOUS,
2660 client_maker_.MakeInitialSettingsPacketAndSaveData(
2661 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232662 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522663 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562664 SYNCHRONOUS,
2665 client_maker_.MakeDataPacket(
2666 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2667 true, false, 0, request_data));
2668 // TLP 2
2669 quic_data.AddWrite(
2670 SYNCHRONOUS,
2671 client_maker_.MakeDataPacket(
2672 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2673 true, false, settings_offset, settings_data));
2674 // RTO 1
2675 quic_data.AddWrite(
2676 SYNCHRONOUS,
2677 client_maker_.MakeDataPacket(
2678 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2679 true, false, 0, request_data));
2680 quic_data.AddWrite(
2681 SYNCHRONOUS,
2682 client_maker_.MakeDataPacket(
2683 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2684 true, false, settings_offset, settings_data));
2685 // RTO 2
2686 quic_data.AddWrite(
2687 SYNCHRONOUS,
2688 client_maker_.MakeDataPacket(
2689 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2690 true, false, 0, request_data));
2691 quic_data.AddWrite(
2692 SYNCHRONOUS,
2693 client_maker_.MakeDataPacket(
2694 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2695 true, false, settings_offset, settings_data));
2696 // RTO 3
2697 quic_data.AddWrite(
2698 SYNCHRONOUS,
2699 client_maker_.MakeDataPacket(
2700 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2701 true, false, 0, request_data));
2702 quic_data.AddWrite(
2703 SYNCHRONOUS,
2704 client_maker_.MakeDataPacket(
2705 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2706 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232707
Zhongyi Shi32f2fd02018-04-16 18:23:432708 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522709 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432710 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222711
rch9ecde09b2017-04-08 00:18:232712 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2713 quic_data.AddRead(ASYNC, OK);
2714 quic_data.AddSocketDataToFactory(&socket_factory_);
2715
2716 // In order for a new QUIC session to be established via alternate-protocol
2717 // without racing an HTTP connection, we need the host resolution to happen
2718 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2719 // connection to the the server, in this test we require confirmation
2720 // before encrypting so the HTTP job will still start.
2721 host_resolver_.set_synchronous_mode(true);
2722 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2723 "");
rch9ecde09b2017-04-08 00:18:232724
2725 CreateSession();
2726 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552727 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232728 QuicStreamFactoryPeer::SetAlarmFactory(
2729 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192730 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552731 &clock_));
rch9ecde09b2017-04-08 00:18:232732
Ryan Hamilton9835e662018-08-02 05:36:272733 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232734
2735 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2736 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362737 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2739
2740 // Pump the message loop to get the request started.
2741 base::RunLoop().RunUntilIdle();
2742 // Explicitly confirm the handshake.
2743 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522744 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232745
2746 // Run the QUIC session to completion.
2747 quic_task_runner_->RunUntilIdle();
2748
2749 ExpectQuicAlternateProtocolMapping();
2750 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2751 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2752}
2753
2754// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2755// return QUIC_PROTOCOL_ERROR.
2756TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482757 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522758 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232759
2760 // The request will initially go out over QUIC.
2761 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522762 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132763 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232764 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2765
2766 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032767 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432768 quic_data.AddWrite(SYNCHRONOUS,
2769 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332770 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2771 true, priority, GetRequestHeaders("GET", "https", "/"),
2772 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232773
2774 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522775 quic::QuicStreamOffset settings_offset = header_stream_offset;
2776 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432777 quic_data.AddWrite(SYNCHRONOUS,
2778 client_maker_.MakeInitialSettingsPacketAndSaveData(
2779 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232780 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522781 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562782 SYNCHRONOUS,
2783 client_maker_.MakeDataPacket(
2784 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2785 true, false, 0, request_data));
2786 // TLP 2
2787 quic_data.AddWrite(
2788 SYNCHRONOUS,
2789 client_maker_.MakeDataPacket(
2790 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2791 true, false, settings_offset, settings_data));
2792 // RTO 1
2793 quic_data.AddWrite(
2794 SYNCHRONOUS,
2795 client_maker_.MakeDataPacket(
2796 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2797 true, false, 0, request_data));
2798 quic_data.AddWrite(
2799 SYNCHRONOUS,
2800 client_maker_.MakeDataPacket(
2801 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2802 true, false, settings_offset, settings_data));
2803 // RTO 2
2804 quic_data.AddWrite(
2805 SYNCHRONOUS,
2806 client_maker_.MakeDataPacket(
2807 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2808 true, false, 0, request_data));
2809 quic_data.AddWrite(
2810 SYNCHRONOUS,
2811 client_maker_.MakeDataPacket(
2812 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2813 true, false, settings_offset, settings_data));
2814 // RTO 3
2815 quic_data.AddWrite(
2816 SYNCHRONOUS,
2817 client_maker_.MakeDataPacket(
2818 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2819 true, false, 0, request_data));
2820 quic_data.AddWrite(
2821 SYNCHRONOUS,
2822 client_maker_.MakeDataPacket(
2823 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2824 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232825 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522826 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562827 SYNCHRONOUS,
2828 client_maker_.MakeDataPacket(
2829 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2830 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:092831 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562832 SYNCHRONOUS,
2833 client_maker_.MakeDataPacket(
2834 12, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2835 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232836 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432837 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522838 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432839 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232840
2841 quic_data.AddRead(ASYNC, OK);
2842 quic_data.AddSocketDataToFactory(&socket_factory_);
2843
2844 // In order for a new QUIC session to be established via alternate-protocol
2845 // without racing an HTTP connection, we need the host resolution to happen
2846 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2847 // connection to the the server, in this test we require confirmation
2848 // before encrypting so the HTTP job will still start.
2849 host_resolver_.set_synchronous_mode(true);
2850 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2851 "");
rch9ecde09b2017-04-08 00:18:232852
2853 CreateSession();
2854 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552855 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232856 QuicStreamFactoryPeer::SetAlarmFactory(
2857 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192858 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552859 &clock_));
rch9ecde09b2017-04-08 00:18:232860
Ryan Hamilton9835e662018-08-02 05:36:272861 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232862
2863 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2864 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362865 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2867
2868 // Pump the message loop to get the request started.
2869 base::RunLoop().RunUntilIdle();
2870 // Explicitly confirm the handshake.
2871 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522872 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232873
2874 // Run the QUIC session to completion.
2875 quic_task_runner_->RunUntilIdle();
2876
2877 ExpectQuicAlternateProtocolMapping();
2878 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2879 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2880}
2881
2882// Verify that if a QUIC connection RTOs, while there are no active streams
2883// QUIC will not be marked as broken.
2884TEST_P(QuicNetworkTransactionTest,
2885 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522886 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232887
2888 // The request will initially go out over QUIC.
2889 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522890 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132891 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232892 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2893
2894 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032895 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432896 quic_data.AddWrite(SYNCHRONOUS,
2897 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332898 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2899 true, priority, GetRequestHeaders("GET", "https", "/"),
2900 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232901
2902 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522903 quic::QuicStreamOffset settings_offset = header_stream_offset;
2904 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432905 quic_data.AddWrite(SYNCHRONOUS,
2906 client_maker_.MakeInitialSettingsPacketAndSaveData(
2907 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232908
Fan Yang32c5a112018-12-10 20:06:332909 quic_data.AddWrite(SYNCHRONOUS,
2910 client_maker_.MakeRstPacket(
2911 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2912 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232913 // TLP 1
Nick Harper23290b82019-05-02 00:02:562914 quic_data.AddWrite(
2915 SYNCHRONOUS,
2916 client_maker_.MakeDataPacket(
2917 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2918 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232919 // TLP 2
Nick Harper23290b82019-05-02 00:02:562920 quic_data.AddWrite(
2921 SYNCHRONOUS,
2922 client_maker_.MakeDataPacket(
2923 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2924 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232925 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332926 quic_data.AddWrite(SYNCHRONOUS,
2927 client_maker_.MakeRstPacket(
2928 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2929 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:562930 quic_data.AddWrite(
2931 SYNCHRONOUS,
2932 client_maker_.MakeDataPacket(
2933 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2934 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232935 // RTO 2
Nick Harper23290b82019-05-02 00:02:562936 quic_data.AddWrite(
2937 SYNCHRONOUS,
2938 client_maker_.MakeDataPacket(
2939 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2940 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332941 quic_data.AddWrite(SYNCHRONOUS,
2942 client_maker_.MakeRstPacket(
2943 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2944 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232945 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522946 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562947 SYNCHRONOUS,
2948 client_maker_.MakeDataPacket(
2949 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2950 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:092951 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562952 SYNCHRONOUS,
2953 client_maker_.MakeDataPacket(
2954 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2955 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232956 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432957 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332958 SYNCHRONOUS, client_maker_.MakeRstPacket(
2959 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2960 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522961 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562962 SYNCHRONOUS,
2963 client_maker_.MakeDataPacket(
2964 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2965 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232966 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432967 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522968 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432969 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232970
2971 quic_data.AddRead(ASYNC, OK);
2972 quic_data.AddSocketDataToFactory(&socket_factory_);
2973
2974 // In order for a new QUIC session to be established via alternate-protocol
2975 // without racing an HTTP connection, we need the host resolution to happen
2976 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2977 // connection to the the server, in this test we require confirmation
2978 // before encrypting so the HTTP job will still start.
2979 host_resolver_.set_synchronous_mode(true);
2980 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2981 "");
rch9ecde09b2017-04-08 00:18:232982
2983 CreateSession();
2984 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552985 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232986 QuicStreamFactoryPeer::SetAlarmFactory(
2987 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192988 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552989 &clock_));
rch9ecde09b2017-04-08 00:18:232990
Ryan Hamilton9835e662018-08-02 05:36:272991 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232992
Jeremy Roman0579ed62017-08-29 15:56:192993 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232994 session_.get());
2995 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362996 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2998
2999 // Pump the message loop to get the request started.
3000 base::RunLoop().RunUntilIdle();
3001 // Explicitly confirm the handshake.
3002 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523003 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233004
3005 // Now cancel the request.
3006 trans.reset();
3007
3008 // Run the QUIC session to completion.
3009 quic_task_runner_->RunUntilIdle();
3010
3011 ExpectQuicAlternateProtocolMapping();
3012
3013 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3014}
3015
rch2f2991c2017-04-13 19:28:173016// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3017// the request fails with QUIC_PROTOCOL_ERROR.
3018TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:483019 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173020 // The request will initially go out over QUIC.
3021 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523022 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033023 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433024 quic_data.AddWrite(
3025 SYNCHRONOUS,
3026 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333027 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433028 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523029 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433030 quic_data.AddWrite(SYNCHRONOUS,
3031 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173032 // Peer sending data from an non-existing stream causes this end to raise
3033 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333034 quic_data.AddRead(
3035 ASYNC, ConstructServerRstPacket(
3036 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3037 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173038 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433039 quic_data.AddWrite(SYNCHRONOUS,
3040 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523041 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3042 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173043 quic_data.AddSocketDataToFactory(&socket_factory_);
3044
3045 // In order for a new QUIC session to be established via alternate-protocol
3046 // without racing an HTTP connection, we need the host resolution to happen
3047 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3048 // connection to the the server, in this test we require confirmation
3049 // before encrypting so the HTTP job will still start.
3050 host_resolver_.set_synchronous_mode(true);
3051 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3052 "");
rch2f2991c2017-04-13 19:28:173053
3054 CreateSession();
3055
Ryan Hamilton9835e662018-08-02 05:36:273056 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173057
3058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3059 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363060 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3062
3063 // Pump the message loop to get the request started.
3064 base::RunLoop().RunUntilIdle();
3065 // Explicitly confirm the handshake.
3066 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523067 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173068
3069 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3070
3071 // Run the QUIC session to completion.
3072 base::RunLoop().RunUntilIdle();
3073 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3074 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3075
3076 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3077 ExpectQuicAlternateProtocolMapping();
3078 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3079}
3080
rch9ecde09b2017-04-08 00:18:233081// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3082// connection times out, then QUIC will be marked as broken and the request
3083// retried over TCP.
3084TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413085 session_params_.mark_quic_broken_when_network_blackholes = true;
3086 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233087
3088 // The request will initially go out over QUIC.
3089 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523090 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133091 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233092 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3093
3094 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033095 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433096 quic_data.AddWrite(SYNCHRONOUS,
3097 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333098 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3099 true, priority, GetRequestHeaders("GET", "https", "/"),
3100 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233101
3102 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523103 quic::QuicStreamOffset settings_offset = header_stream_offset;
3104 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433105 quic_data.AddWrite(SYNCHRONOUS,
3106 client_maker_.MakeInitialSettingsPacketAndSaveData(
3107 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233108 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523109 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563110 SYNCHRONOUS,
3111 client_maker_.MakeDataPacket(
3112 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3113 true, false, 0, request_data));
3114 // TLP 2
3115 quic_data.AddWrite(
3116 SYNCHRONOUS,
3117 client_maker_.MakeDataPacket(
3118 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3119 true, false, settings_offset, settings_data));
3120 // RTO 1
3121 quic_data.AddWrite(
3122 SYNCHRONOUS,
3123 client_maker_.MakeDataPacket(
3124 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3125 true, false, 0, request_data));
3126 quic_data.AddWrite(
3127 SYNCHRONOUS,
3128 client_maker_.MakeDataPacket(
3129 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3130 true, false, settings_offset, settings_data));
3131 // RTO 2
3132 quic_data.AddWrite(
3133 SYNCHRONOUS,
3134 client_maker_.MakeDataPacket(
3135 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3136 true, false, 0, request_data));
3137 quic_data.AddWrite(
3138 SYNCHRONOUS,
3139 client_maker_.MakeDataPacket(
3140 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3141 true, false, settings_offset, settings_data));
3142 // RTO 3
3143 quic_data.AddWrite(
3144 SYNCHRONOUS,
3145 client_maker_.MakeDataPacket(
3146 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3147 true, false, 0, request_data));
3148 quic_data.AddWrite(
3149 SYNCHRONOUS,
3150 client_maker_.MakeDataPacket(
3151 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3152 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233153
Zhongyi Shi32f2fd02018-04-16 18:23:433154 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523155 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433156 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223157
rch9ecde09b2017-04-08 00:18:233158 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3159 quic_data.AddRead(ASYNC, OK);
3160 quic_data.AddSocketDataToFactory(&socket_factory_);
3161
3162 // After that fails, it will be resent via TCP.
3163 MockWrite http_writes[] = {
3164 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3165 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3166 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3167
3168 MockRead http_reads[] = {
3169 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3170 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3171 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013172 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233173 socket_factory_.AddSocketDataProvider(&http_data);
3174 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3175
3176 // In order for a new QUIC session to be established via alternate-protocol
3177 // without racing an HTTP connection, we need the host resolution to happen
3178 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3179 // connection to the the server, in this test we require confirmation
3180 // before encrypting so the HTTP job will still start.
3181 host_resolver_.set_synchronous_mode(true);
3182 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3183 "");
rch9ecde09b2017-04-08 00:18:233184
3185 CreateSession();
3186 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553187 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233188 QuicStreamFactoryPeer::SetAlarmFactory(
3189 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193190 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553191 &clock_));
rch9ecde09b2017-04-08 00:18:233192
Ryan Hamilton9835e662018-08-02 05:36:273193 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233194
3195 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3196 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363197 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233198 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3199
3200 // Pump the message loop to get the request started.
3201 base::RunLoop().RunUntilIdle();
3202 // Explicitly confirm the handshake.
3203 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523204 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233205
3206 // Run the QUIC session to completion.
3207 quic_task_runner_->RunUntilIdle();
3208 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3209
3210 // Let the transaction proceed which will result in QUIC being marked
3211 // as broken and the request falling back to TCP.
3212 EXPECT_THAT(callback.WaitForResult(), IsOk());
3213
3214 ExpectBrokenAlternateProtocolMapping();
3215 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3216 ASSERT_FALSE(http_data.AllReadDataConsumed());
3217
3218 // Read the response body over TCP.
3219 CheckResponseData(&trans, "hello world");
3220 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3221 ASSERT_TRUE(http_data.AllReadDataConsumed());
3222}
3223
rch2f2991c2017-04-13 19:28:173224// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3225// connection times out, then QUIC will be marked as broken and the request
3226// retried over TCP.
3227TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413228 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173229
3230 // The request will initially go out over QUIC.
3231 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523232 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133233 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173234 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3235
3236 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033237 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433238 quic_data.AddWrite(SYNCHRONOUS,
3239 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333240 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3241 true, priority, GetRequestHeaders("GET", "https", "/"),
3242 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173243
3244 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523245 quic::QuicStreamOffset settings_offset = header_stream_offset;
3246 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433247 quic_data.AddWrite(SYNCHRONOUS,
3248 client_maker_.MakeInitialSettingsPacketAndSaveData(
3249 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173250 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523251 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563252 SYNCHRONOUS,
3253 client_maker_.MakeDataPacket(
3254 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3255 true, false, 0, request_data));
3256 // TLP 2
3257 quic_data.AddWrite(
3258 SYNCHRONOUS,
3259 client_maker_.MakeDataPacket(
3260 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3261 true, false, settings_offset, settings_data));
3262 // RTO 1
3263 quic_data.AddWrite(
3264 SYNCHRONOUS,
3265 client_maker_.MakeDataPacket(
3266 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3267 true, false, 0, request_data));
3268 quic_data.AddWrite(
3269 SYNCHRONOUS,
3270 client_maker_.MakeDataPacket(
3271 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3272 true, false, settings_offset, settings_data));
3273 // RTO 2
3274 quic_data.AddWrite(
3275 SYNCHRONOUS,
3276 client_maker_.MakeDataPacket(
3277 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3278 true, false, 0, request_data));
3279 quic_data.AddWrite(
3280 SYNCHRONOUS,
3281 client_maker_.MakeDataPacket(
3282 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3283 true, false, settings_offset, settings_data));
3284 // RTO 3
3285 quic_data.AddWrite(
3286 SYNCHRONOUS,
3287 client_maker_.MakeDataPacket(
3288 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3289 true, false, 0, request_data));
3290 quic_data.AddWrite(
3291 SYNCHRONOUS,
3292 client_maker_.MakeDataPacket(
3293 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3294 true, false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173295
Zhongyi Shi32f2fd02018-04-16 18:23:433296 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523297 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433298 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223299
rch2f2991c2017-04-13 19:28:173300 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3301 quic_data.AddRead(ASYNC, OK);
3302 quic_data.AddSocketDataToFactory(&socket_factory_);
3303
3304 // After that fails, it will be resent via TCP.
3305 MockWrite http_writes[] = {
3306 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3307 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3308 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3309
3310 MockRead http_reads[] = {
3311 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3312 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3313 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013314 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173315 socket_factory_.AddSocketDataProvider(&http_data);
3316 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3317
3318 // In order for a new QUIC session to be established via alternate-protocol
3319 // without racing an HTTP connection, we need the host resolution to happen
3320 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3321 // connection to the the server, in this test we require confirmation
3322 // before encrypting so the HTTP job will still start.
3323 host_resolver_.set_synchronous_mode(true);
3324 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3325 "");
rch2f2991c2017-04-13 19:28:173326
3327 CreateSession();
3328 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553329 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173330 QuicStreamFactoryPeer::SetAlarmFactory(
3331 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193332 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553333 &clock_));
rch2f2991c2017-04-13 19:28:173334
Ryan Hamilton9835e662018-08-02 05:36:273335 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173336
3337 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3338 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363339 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173340 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3341
3342 // Pump the message loop to get the request started.
3343 base::RunLoop().RunUntilIdle();
3344 // Explicitly confirm the handshake.
3345 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523346 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173347
3348 // Run the QUIC session to completion.
3349 quic_task_runner_->RunUntilIdle();
3350 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3351
3352 ExpectQuicAlternateProtocolMapping();
3353
3354 // Let the transaction proceed which will result in QUIC being marked
3355 // as broken and the request falling back to TCP.
3356 EXPECT_THAT(callback.WaitForResult(), IsOk());
3357
3358 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3359 ASSERT_FALSE(http_data.AllReadDataConsumed());
3360
3361 // Read the response body over TCP.
3362 CheckResponseData(&trans, "hello world");
3363 ExpectBrokenAlternateProtocolMapping();
3364 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3365 ASSERT_TRUE(http_data.AllReadDataConsumed());
3366}
3367
rch9ecde09b2017-04-08 00:18:233368// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3369// connection times out, then QUIC will be marked as broken but the request
3370// will not be retried over TCP.
3371TEST_P(QuicNetworkTransactionTest,
3372 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413373 session_params_.mark_quic_broken_when_network_blackholes = true;
3374 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233375
3376 // The request will initially go out over QUIC.
3377 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523378 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133379 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233380 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3381
3382 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033383 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433384 quic_data.AddWrite(SYNCHRONOUS,
3385 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333386 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3387 true, priority, GetRequestHeaders("GET", "https", "/"),
3388 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233389
3390 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523391 quic::QuicStreamOffset settings_offset = header_stream_offset;
3392 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433393 quic_data.AddWrite(SYNCHRONOUS,
3394 client_maker_.MakeInitialSettingsPacketAndSaveData(
3395 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233396
Zhongyi Shi32f2fd02018-04-16 18:23:433397 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333398 1, GetNthClientInitiatedBidirectionalStreamId(0),
3399 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433400 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523401 quic_data.AddWrite(
3402 SYNCHRONOUS,
3403 ConstructClientAckPacket(3, 1, 1, 1,
3404 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233405
3406 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523407 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563408 SYNCHRONOUS,
3409 client_maker_.MakeDataPacket(
3410 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3411 false, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233412 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093413 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563414 SYNCHRONOUS,
3415 client_maker_.MakeDataPacket(
3416 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3417 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233418 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523419 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563420 SYNCHRONOUS,
3421 client_maker_.MakeDataPacket(
3422 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3423 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093424 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563425 SYNCHRONOUS,
3426 client_maker_.MakeDataPacket(
3427 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3428 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233429 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523430 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563431 SYNCHRONOUS,
3432 client_maker_.MakeDataPacket(
3433 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3434 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093435 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563436 SYNCHRONOUS,
3437 client_maker_.MakeDataPacket(
3438 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3439 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233440 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523441 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563442 SYNCHRONOUS,
3443 client_maker_.MakeDataPacket(
3444 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3445 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093446 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563447 SYNCHRONOUS,
3448 client_maker_.MakeDataPacket(
3449 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3450 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233451
Michael Warres112212822018-12-26 17:51:063452 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183453 quic_fix_time_of_first_packet_sent_after_receiving)) {
3454 quic_data.AddWrite(
3455 SYNCHRONOUS,
3456 client_maker_.MakeAckAndConnectionClosePacket(
3457 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3458 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3459
3460 } else {
3461 quic_data.AddWrite(
3462 SYNCHRONOUS,
3463 client_maker_.MakeAckAndConnectionClosePacket(
3464 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3465 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3466 }
Fan Yang928f1632017-12-14 18:55:223467
rch9ecde09b2017-04-08 00:18:233468 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3469 quic_data.AddRead(ASYNC, OK);
3470 quic_data.AddSocketDataToFactory(&socket_factory_);
3471
3472 // In order for a new QUIC session to be established via alternate-protocol
3473 // without racing an HTTP connection, we need the host resolution to happen
3474 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3475 // connection to the the server, in this test we require confirmation
3476 // before encrypting so the HTTP job will still start.
3477 host_resolver_.set_synchronous_mode(true);
3478 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3479 "");
rch9ecde09b2017-04-08 00:18:233480
3481 CreateSession();
3482 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553483 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233484 QuicStreamFactoryPeer::SetAlarmFactory(
3485 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193486 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553487 &clock_));
rch9ecde09b2017-04-08 00:18:233488
Ryan Hamilton9835e662018-08-02 05:36:273489 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233490
3491 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3492 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363493 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3495
3496 // Pump the message loop to get the request started.
3497 base::RunLoop().RunUntilIdle();
3498 // Explicitly confirm the handshake.
3499 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523500 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233501
3502 // Pump the message loop to get the request started.
3503 base::RunLoop().RunUntilIdle();
3504
3505 // Run the QUIC session to completion.
3506 quic_task_runner_->RunUntilIdle();
3507 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3508
3509 // Let the transaction proceed which will result in QUIC being marked
3510 // as broken and the request falling back to TCP.
3511 EXPECT_THAT(callback.WaitForResult(), IsOk());
3512
3513 ExpectBrokenAlternateProtocolMapping();
3514 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3515
3516 std::string response_data;
3517 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3518 IsError(ERR_QUIC_PROTOCOL_ERROR));
3519}
3520
3521// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3522// connection RTOs, then QUIC will be marked as broken and the request retried
3523// over TCP.
3524TEST_P(QuicNetworkTransactionTest,
3525 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413526 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523527 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233528
3529 // The request will initially go out over QUIC.
3530 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523531 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133532 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233533 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3534
3535 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033536 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433537 quic_data.AddWrite(SYNCHRONOUS,
3538 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333539 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3540 true, priority, GetRequestHeaders("GET", "https", "/"),
3541 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233542
3543 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523544 quic::QuicStreamOffset settings_offset = header_stream_offset;
3545 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433546 quic_data.AddWrite(SYNCHRONOUS,
3547 client_maker_.MakeInitialSettingsPacketAndSaveData(
3548 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233549 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523550 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563551 SYNCHRONOUS,
3552 client_maker_.MakeDataPacket(
3553 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3554 true, false, 0, request_data));
3555 // TLP 2
3556 quic_data.AddWrite(
3557 SYNCHRONOUS,
3558 client_maker_.MakeDataPacket(
3559 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3560 true, false, settings_offset, settings_data));
3561 // RTO 1
3562 quic_data.AddWrite(
3563 SYNCHRONOUS,
3564 client_maker_.MakeDataPacket(
3565 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3566 true, false, 0, request_data));
3567 quic_data.AddWrite(
3568 SYNCHRONOUS,
3569 client_maker_.MakeDataPacket(
3570 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3571 true, false, settings_offset, settings_data));
3572 // RTO 2
3573 quic_data.AddWrite(
3574 SYNCHRONOUS,
3575 client_maker_.MakeDataPacket(
3576 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3577 true, false, 0, request_data));
3578 quic_data.AddWrite(
3579 SYNCHRONOUS,
3580 client_maker_.MakeDataPacket(
3581 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3582 true, false, settings_offset, settings_data));
3583 // RTO 3
3584 quic_data.AddWrite(
3585 SYNCHRONOUS,
3586 client_maker_.MakeDataPacket(
3587 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3588 true, false, 0, request_data));
3589 quic_data.AddWrite(
3590 SYNCHRONOUS,
3591 client_maker_.MakeDataPacket(
3592 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3593 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233594 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523595 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563596 SYNCHRONOUS,
3597 client_maker_.MakeDataPacket(
3598 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3599 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093600 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563601 SYNCHRONOUS,
3602 client_maker_.MakeDataPacket(
3603 12, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3604 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233605
Zhongyi Shi32f2fd02018-04-16 18:23:433606 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523607 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433608 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233609
3610 quic_data.AddRead(ASYNC, OK);
3611 quic_data.AddSocketDataToFactory(&socket_factory_);
3612
3613 // After that fails, it will be resent via TCP.
3614 MockWrite http_writes[] = {
3615 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3616 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3617 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3618
3619 MockRead http_reads[] = {
3620 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3621 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3622 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013623 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233624 socket_factory_.AddSocketDataProvider(&http_data);
3625 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3626
3627 // In order for a new QUIC session to be established via alternate-protocol
3628 // without racing an HTTP connection, we need the host resolution to happen
3629 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3630 // connection to the the server, in this test we require confirmation
3631 // before encrypting so the HTTP job will still start.
3632 host_resolver_.set_synchronous_mode(true);
3633 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3634 "");
rch9ecde09b2017-04-08 00:18:233635
3636 CreateSession();
3637 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553638 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233639 QuicStreamFactoryPeer::SetAlarmFactory(
3640 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193641 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553642 &clock_));
rch9ecde09b2017-04-08 00:18:233643
Ryan Hamilton9835e662018-08-02 05:36:273644 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233645
3646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3647 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363648 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3650
3651 // Pump the message loop to get the request started.
3652 base::RunLoop().RunUntilIdle();
3653 // Explicitly confirm the handshake.
3654 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523655 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233656
3657 // Run the QUIC session to completion.
3658 quic_task_runner_->RunUntilIdle();
3659 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3660
3661 // Let the transaction proceed which will result in QUIC being marked
3662 // as broken and the request falling back to TCP.
3663 EXPECT_THAT(callback.WaitForResult(), IsOk());
3664
3665 ExpectBrokenAlternateProtocolMapping();
3666 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3667 ASSERT_FALSE(http_data.AllReadDataConsumed());
3668
3669 // Read the response body over TCP.
3670 CheckResponseData(&trans, "hello world");
3671 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3672 ASSERT_TRUE(http_data.AllReadDataConsumed());
3673}
3674
3675// Verify that if a QUIC connection RTOs, while there are no active streams
3676// QUIC will be marked as broken.
3677TEST_P(QuicNetworkTransactionTest,
3678 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413679 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523680 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233681
3682 // The request will initially go out over QUIC.
3683 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523684 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133685 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233686 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3687
3688 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033689 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433690 quic_data.AddWrite(SYNCHRONOUS,
3691 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333692 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3693 true, priority, GetRequestHeaders("GET", "https", "/"),
3694 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233695
3696 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523697 quic::QuicStreamOffset settings_offset = header_stream_offset;
3698 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433699 quic_data.AddWrite(SYNCHRONOUS,
3700 client_maker_.MakeInitialSettingsPacketAndSaveData(
3701 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233702
Fan Yang32c5a112018-12-10 20:06:333703 quic_data.AddWrite(SYNCHRONOUS,
3704 client_maker_.MakeRstPacket(
3705 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3706 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233707 // TLP 1
Nick Harper23290b82019-05-02 00:02:563708 quic_data.AddWrite(
3709 SYNCHRONOUS,
3710 client_maker_.MakeDataPacket(
3711 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3712 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233713 // TLP 2
Nick Harper23290b82019-05-02 00:02:563714 quic_data.AddWrite(
3715 SYNCHRONOUS,
3716 client_maker_.MakeDataPacket(
3717 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3718 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233719 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333720 quic_data.AddWrite(SYNCHRONOUS,
3721 client_maker_.MakeRstPacket(
3722 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3723 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:563724 quic_data.AddWrite(
3725 SYNCHRONOUS,
3726 client_maker_.MakeDataPacket(
3727 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3728 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233729 // RTO 2
Nick Harper23290b82019-05-02 00:02:563730 quic_data.AddWrite(
3731 SYNCHRONOUS,
3732 client_maker_.MakeDataPacket(
3733 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3734 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333735 quic_data.AddWrite(SYNCHRONOUS,
3736 client_maker_.MakeRstPacket(
3737 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3738 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233739 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523740 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563741 SYNCHRONOUS,
3742 client_maker_.MakeDataPacket(
3743 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3744 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093745 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563746 SYNCHRONOUS,
3747 client_maker_.MakeDataPacket(
3748 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3749 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233750 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433751 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333752 SYNCHRONOUS, client_maker_.MakeRstPacket(
3753 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3754 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523755 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563756 SYNCHRONOUS,
3757 client_maker_.MakeDataPacket(
3758 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3759 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233760 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433761 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523762 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433763 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233764
3765 quic_data.AddRead(ASYNC, OK);
3766 quic_data.AddSocketDataToFactory(&socket_factory_);
3767
3768 // In order for a new QUIC session to be established via alternate-protocol
3769 // without racing an HTTP connection, we need the host resolution to happen
3770 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3771 // connection to the the server, in this test we require confirmation
3772 // before encrypting so the HTTP job will still start.
3773 host_resolver_.set_synchronous_mode(true);
3774 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3775 "");
rch9ecde09b2017-04-08 00:18:233776
3777 CreateSession();
3778 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553779 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233780 QuicStreamFactoryPeer::SetAlarmFactory(
3781 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193782 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553783 &clock_));
rch9ecde09b2017-04-08 00:18:233784
Ryan Hamilton9835e662018-08-02 05:36:273785 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233786
Jeremy Roman0579ed62017-08-29 15:56:193787 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233788 session_.get());
3789 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363790 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3792
3793 // Pump the message loop to get the request started.
3794 base::RunLoop().RunUntilIdle();
3795 // Explicitly confirm the handshake.
3796 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523797 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233798
3799 // Now cancel the request.
3800 trans.reset();
3801
3802 // Run the QUIC session to completion.
3803 quic_task_runner_->RunUntilIdle();
3804
3805 ExpectBrokenAlternateProtocolMapping();
3806
3807 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3808}
3809
rch2f2991c2017-04-13 19:28:173810// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3811// protocol error occurs after the handshake is confirmed, the request
3812// retried over TCP and the QUIC will be marked as broken.
3813TEST_P(QuicNetworkTransactionTest,
3814 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413815 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173816
3817 // The request will initially go out over QUIC.
3818 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523819 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033820 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433821 quic_data.AddWrite(
3822 SYNCHRONOUS,
3823 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333824 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433825 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523826 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433827 quic_data.AddWrite(SYNCHRONOUS,
3828 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173829 // Peer sending data from an non-existing stream causes this end to raise
3830 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333831 quic_data.AddRead(
3832 ASYNC, ConstructServerRstPacket(
3833 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3834 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173835 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433836 quic_data.AddWrite(SYNCHRONOUS,
3837 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523838 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3839 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173840 quic_data.AddSocketDataToFactory(&socket_factory_);
3841
3842 // After that fails, it will be resent via TCP.
3843 MockWrite http_writes[] = {
3844 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3845 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3846 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3847
3848 MockRead http_reads[] = {
3849 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3850 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3851 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013852 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173853 socket_factory_.AddSocketDataProvider(&http_data);
3854 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3855
3856 // In order for a new QUIC session to be established via alternate-protocol
3857 // without racing an HTTP connection, we need the host resolution to happen
3858 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3859 // connection to the the server, in this test we require confirmation
3860 // before encrypting so the HTTP job will still start.
3861 host_resolver_.set_synchronous_mode(true);
3862 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3863 "");
rch2f2991c2017-04-13 19:28:173864
3865 CreateSession();
3866
Ryan Hamilton9835e662018-08-02 05:36:273867 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173868
3869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3870 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363871 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173872 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3873
3874 // Pump the message loop to get the request started.
3875 base::RunLoop().RunUntilIdle();
3876 // Explicitly confirm the handshake.
3877 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523878 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173879
3880 // Run the QUIC session to completion.
3881 base::RunLoop().RunUntilIdle();
3882 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3883
3884 ExpectQuicAlternateProtocolMapping();
3885
3886 // Let the transaction proceed which will result in QUIC being marked
3887 // as broken and the request falling back to TCP.
3888 EXPECT_THAT(callback.WaitForResult(), IsOk());
3889
3890 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3891 ASSERT_FALSE(http_data.AllReadDataConsumed());
3892
3893 // Read the response body over TCP.
3894 CheckResponseData(&trans, "hello world");
3895 ExpectBrokenAlternateProtocolMapping();
3896 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3897 ASSERT_TRUE(http_data.AllReadDataConsumed());
3898}
3899
rch30943ee2017-06-12 21:28:443900// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3901// request is reset from, then QUIC will be marked as broken and the request
3902// retried over TCP.
3903TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443904 // The request will initially go out over QUIC.
3905 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523906 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133907 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443908 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3909
3910 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033911 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433912 quic_data.AddWrite(SYNCHRONOUS,
3913 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333914 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3915 true, priority, GetRequestHeaders("GET", "https", "/"),
3916 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443917
3918 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523919 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3920 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433921 quic_data.AddWrite(SYNCHRONOUS,
3922 client_maker_.MakeInitialSettingsPacketAndSaveData(
3923 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443924
Fan Yang32c5a112018-12-10 20:06:333925 quic_data.AddRead(ASYNC,
3926 ConstructServerRstPacket(
3927 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3928 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443929
3930 quic_data.AddRead(ASYNC, OK);
3931 quic_data.AddSocketDataToFactory(&socket_factory_);
3932
3933 // After that fails, it will be resent via TCP.
3934 MockWrite http_writes[] = {
3935 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3936 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3937 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3938
3939 MockRead http_reads[] = {
3940 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3941 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3942 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013943 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443944 socket_factory_.AddSocketDataProvider(&http_data);
3945 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3946
3947 // In order for a new QUIC session to be established via alternate-protocol
3948 // without racing an HTTP connection, we need the host resolution to happen
3949 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3950 // connection to the the server, in this test we require confirmation
3951 // before encrypting so the HTTP job will still start.
3952 host_resolver_.set_synchronous_mode(true);
3953 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3954 "");
rch30943ee2017-06-12 21:28:443955
3956 CreateSession();
3957
Ryan Hamilton9835e662018-08-02 05:36:273958 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443959
3960 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3961 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363962 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443963 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3964
3965 // Pump the message loop to get the request started.
3966 base::RunLoop().RunUntilIdle();
3967 // Explicitly confirm the handshake.
3968 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523969 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443970
3971 // Run the QUIC session to completion.
3972 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3973
3974 ExpectQuicAlternateProtocolMapping();
3975
3976 // Let the transaction proceed which will result in QUIC being marked
3977 // as broken and the request falling back to TCP.
3978 EXPECT_THAT(callback.WaitForResult(), IsOk());
3979
3980 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3981 ASSERT_FALSE(http_data.AllReadDataConsumed());
3982
3983 // Read the response body over TCP.
3984 CheckResponseData(&trans, "hello world");
3985 ExpectBrokenAlternateProtocolMapping();
3986 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3987 ASSERT_TRUE(http_data.AllReadDataConsumed());
3988}
3989
Ryan Hamilton6c2a2a82017-12-15 02:06:283990// Verify that when an origin has two alt-svc advertisements, one local and one
3991// remote, that when the local is broken the request will go over QUIC via
3992// the remote Alt-Svc.
3993// This is a regression test for crbug/825646.
3994TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3995 session_params_.quic_allow_remote_alt_svc = true;
3996
3997 GURL origin1 = request_.url; // mail.example.org
3998 GURL origin2("https://www.example.org/");
3999 ASSERT_NE(origin1.host(), origin2.host());
4000
4001 scoped_refptr<X509Certificate> cert(
4002 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244003 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4004 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284005
4006 ProofVerifyDetailsChromium verify_details;
4007 verify_details.cert_verify_result.verified_cert = cert;
4008 verify_details.cert_verify_result.is_issued_by_known_root = true;
4009 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4010
4011 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524012 quic::QuicStreamOffset request_header_offset(0);
4013 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:284014 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434015 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4016 mock_quic_data.AddWrite(
4017 SYNCHRONOUS,
4018 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334019 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434020 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4021 mock_quic_data.AddRead(
4022 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334023 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434024 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434025 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434026 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334027 ASYNC, ConstructServerDataPacket(
4028 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414029 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434030 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284031 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4032 mock_quic_data.AddRead(ASYNC, 0); // EOF
4033
4034 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4035 MockQuicData mock_quic_data2;
4036 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4037 AddHangingNonAlternateProtocolSocketData();
4038
4039 CreateSession();
4040
4041 // Set up alternative service for |origin1|.
4042 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4043 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4044 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4045 AlternativeServiceInfoVector alternative_services;
4046 alternative_services.push_back(
4047 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4048 local_alternative, expiration,
4049 session_->params().quic_supported_versions));
4050 alternative_services.push_back(
4051 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4052 remote_alternative, expiration,
4053 session_->params().quic_supported_versions));
4054 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4055 alternative_services);
4056
4057 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4058
4059 SendRequestAndExpectQuicResponse("hello!");
4060}
4061
rch30943ee2017-06-12 21:28:444062// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4063// request is reset from, then QUIC will be marked as broken and the request
4064// retried over TCP. Then, subsequent requests will go over a new QUIC
4065// connection instead of going back to the broken QUIC connection.
4066// This is a regression tests for crbug/731303.
4067TEST_P(QuicNetworkTransactionTest,
4068 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344069 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444070
4071 GURL origin1 = request_.url;
4072 GURL origin2("https://www.example.org/");
4073 ASSERT_NE(origin1.host(), origin2.host());
4074
4075 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524076 quic::QuicStreamOffset request_header_offset(0);
4077 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444078
4079 scoped_refptr<X509Certificate> cert(
4080 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244081 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4082 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444083
4084 ProofVerifyDetailsChromium verify_details;
4085 verify_details.cert_verify_result.verified_cert = cert;
4086 verify_details.cert_verify_result.is_issued_by_known_root = true;
4087 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4088
4089 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434090 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444091 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434092 mock_quic_data.AddWrite(
4093 SYNCHRONOUS,
4094 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334095 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434096 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4097 mock_quic_data.AddRead(
4098 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334099 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434100 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434101 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434102 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334103 ASYNC, ConstructServerDataPacket(
4104 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414105 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434106 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444107
4108 // Second request will go over the pooled QUIC connection, but will be
4109 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054110 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174111 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4112 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054113 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174114 QuicTestPacketMaker server_maker2(
4115 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4116 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434117 mock_quic_data.AddWrite(
4118 SYNCHRONOUS,
4119 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334120 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434121 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334122 GetNthClientInitiatedBidirectionalStreamId(0),
4123 &request_header_offset));
4124 mock_quic_data.AddRead(
4125 ASYNC, ConstructServerRstPacket(
4126 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4127 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444128 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4129 mock_quic_data.AddRead(ASYNC, 0); // EOF
4130
4131 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4132
4133 // After that fails, it will be resent via TCP.
4134 MockWrite http_writes[] = {
4135 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4136 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4137 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4138
4139 MockRead http_reads[] = {
4140 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4141 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4142 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014143 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444144 socket_factory_.AddSocketDataProvider(&http_data);
4145 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4146
Ryan Hamilton6c2a2a82017-12-15 02:06:284147 // Then the next request to the second origin will be sent over TCP.
4148 socket_factory_.AddSocketDataProvider(&http_data);
4149 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444150
4151 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564152 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4153 QuicStreamFactoryPeer::SetAlarmFactory(
4154 session_->quic_stream_factory(),
4155 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4156 &clock_));
rch30943ee2017-06-12 21:28:444157
4158 // Set up alternative service for |origin1|.
4159 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244160 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214161 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244162 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444163 supported_versions_);
rch30943ee2017-06-12 21:28:444164
4165 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244166 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214167 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244168 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444169 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344170
rch30943ee2017-06-12 21:28:444171 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524172 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444173 SendRequestAndExpectQuicResponse("hello!");
4174
4175 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524176 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444177 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4178 request_.url = origin2;
4179 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284180 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244181 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284182 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244183 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444184
4185 // The third request should use a new QUIC connection, not the broken
4186 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284187 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444188}
4189
bnc8be55ebb2015-10-30 14:12:074190TEST_P(QuicNetworkTransactionTest,
4191 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564192 std::string altsvc_header =
4193 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4194 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074195 MockRead http_reads[] = {
4196 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4197 MockRead("hello world"),
4198 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4199 MockRead(ASYNC, OK)};
4200
Ryan Sleevib8d7ea02018-05-07 20:01:014201 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074202 socket_factory_.AddSocketDataProvider(&http_data);
4203 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4204 socket_factory_.AddSocketDataProvider(&http_data);
4205 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4206
rch3f4b8452016-02-23 16:59:324207 CreateSession();
bnc8be55ebb2015-10-30 14:12:074208
4209 SendRequestAndExpectHttpResponse("hello world");
4210 SendRequestAndExpectHttpResponse("hello world");
4211}
4212
Xida Chen9bfe0b62018-04-24 19:52:214213// When multiple alternative services are advertised, HttpStreamFactory should
4214// select the alternative service which uses existing QUIC session if available.
4215// If no existing QUIC session can be used, use the first alternative service
4216// from the list.
zhongyi32569c62016-01-08 02:54:304217TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344218 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524219 MockRead http_reads[] = {
4220 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294221 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524222 MockRead("hello world"),
4223 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4224 MockRead(ASYNC, OK)};
4225
Ryan Sleevib8d7ea02018-05-07 20:01:014226 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524227 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084228 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564229 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524230
Ryan Hamilton8d9ee76e2018-05-29 23:52:524231 quic::QuicStreamOffset request_header_offset = 0;
4232 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304233 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294234 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304235 // alternative service list.
bncc958faa2015-07-31 18:14:524236 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364237 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434238 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4239 mock_quic_data.AddWrite(
4240 SYNCHRONOUS,
4241 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334242 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434243 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304244
4245 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294246 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4247 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434248 mock_quic_data.AddRead(
4249 ASYNC,
4250 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334251 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434252 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434253 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434254 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334255 ASYNC, ConstructServerDataPacket(
4256 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414257 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434258 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304259
4260 // Second QUIC request data.
4261 // Connection pooling, using existing session, no need to include version
4262 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584263 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334264 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4265 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4266 true, GetRequestHeaders("GET", "https", "/"),
4267 GetNthClientInitiatedBidirectionalStreamId(0),
4268 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434269 mock_quic_data.AddRead(
4270 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334271 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434272 GetResponseHeaders("200 OK"), &response_header_offset));
4273 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334274 ASYNC, ConstructServerDataPacket(
4275 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414276 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434277 mock_quic_data.AddWrite(
4278 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524279 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594280 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524281
4282 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4283
rtennetib8e80fb2016-05-16 00:12:094284 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324285 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564286 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4287 QuicStreamFactoryPeer::SetAlarmFactory(
4288 session_->quic_stream_factory(),
4289 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4290 &clock_));
bncc958faa2015-07-31 18:14:524291
4292 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304293
bnc359ed2a2016-04-29 20:43:454294 SendRequestAndExpectQuicResponse("hello!");
4295 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304296}
4297
tbansal6490783c2016-09-20 17:55:274298// Check that an existing QUIC connection to an alternative proxy server is
4299// used.
4300TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4301 base::HistogramTester histogram_tester;
4302
Ryan Hamilton8d9ee76e2018-05-29 23:52:524303 quic::QuicStreamOffset request_header_offset = 0;
4304 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274305 // First QUIC request data.
4306 // Open a session to foo.example.org:443 using the first entry of the
4307 // alternative service list.
4308 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364309 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434310 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4311 mock_quic_data.AddWrite(
4312 SYNCHRONOUS,
4313 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334314 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434315 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274316
4317 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434318 mock_quic_data.AddRead(
4319 ASYNC,
4320 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334321 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434322 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434323 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434324 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334325 ASYNC, ConstructServerDataPacket(
4326 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414327 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434328 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274329
4330 // Second QUIC request data.
4331 // Connection pooling, using existing session, no need to include version
4332 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274333 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334334 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4335 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4336 true, GetRequestHeaders("GET", "http", "/"),
4337 GetNthClientInitiatedBidirectionalStreamId(0),
4338 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434339 mock_quic_data.AddRead(
4340 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334341 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434342 GetResponseHeaders("200 OK"), &response_header_offset));
4343 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334344 ASYNC, ConstructServerDataPacket(
4345 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414346 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434347 mock_quic_data.AddWrite(
4348 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274349 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4350 mock_quic_data.AddRead(ASYNC, 0); // EOF
4351
4352 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4353
4354 AddHangingNonAlternateProtocolSocketData();
4355
4356 TestProxyDelegate test_proxy_delegate;
4357
Lily Houghton8c2f97d2018-01-22 05:06:594358 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494359 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274360
4361 test_proxy_delegate.set_alternative_proxy_server(
4362 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524363 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274364
4365 request_.url = GURL("http://mail.example.org/");
4366
4367 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564368 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4369 QuicStreamFactoryPeer::SetAlarmFactory(
4370 session_->quic_stream_factory(),
4371 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4372 &clock_));
tbansal6490783c2016-09-20 17:55:274373
4374 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4375 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4376 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4377 1);
4378
4379 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4380 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4381 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4382 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4383 1);
4384}
4385
Ryan Hamilton8d9ee76e2018-05-29 23:52:524386// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454387// even if alternative service destination is different.
4388TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344389 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304390 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524391 quic::QuicStreamOffset request_header_offset(0);
4392 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454393
rch5cb522462017-04-25 20:18:364394 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434395 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454396 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434397 mock_quic_data.AddWrite(
4398 SYNCHRONOUS,
4399 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334400 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434401 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4402 mock_quic_data.AddRead(
4403 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334404 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434405 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434406 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434407 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334408 ASYNC, ConstructServerDataPacket(
4409 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414410 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434411 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304412
bnc359ed2a2016-04-29 20:43:454413 // Second request.
alyssar2adf3ac2016-05-03 17:12:584414 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334415 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4416 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4417 true, GetRequestHeaders("GET", "https", "/"),
4418 GetNthClientInitiatedBidirectionalStreamId(0),
4419 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434420 mock_quic_data.AddRead(
4421 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334422 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434423 GetResponseHeaders("200 OK"), &response_header_offset));
4424 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334425 ASYNC, ConstructServerDataPacket(
4426 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414427 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434428 mock_quic_data.AddWrite(
4429 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304430 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4431 mock_quic_data.AddRead(ASYNC, 0); // EOF
4432
4433 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454434
4435 AddHangingNonAlternateProtocolSocketData();
4436 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304437
rch3f4b8452016-02-23 16:59:324438 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564439 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4440 QuicStreamFactoryPeer::SetAlarmFactory(
4441 session_->quic_stream_factory(),
4442 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4443 &clock_));
zhongyi32569c62016-01-08 02:54:304444
bnc359ed2a2016-04-29 20:43:454445 const char destination1[] = "first.example.com";
4446 const char destination2[] = "second.example.com";
4447
4448 // Set up alternative service entry to destination1.
4449 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214450 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454451 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214452 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444453 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454454 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524455 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454456 SendRequestAndExpectQuicResponse("hello!");
4457
4458 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214459 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214460 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444461 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524462 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454463 // even though alternative service destination is different.
4464 SendRequestAndExpectQuicResponse("hello!");
4465}
4466
4467// Pool to existing session with matching destination and matching certificate
4468// even if origin is different, and even if the alternative service with
4469// matching destination is not the first one on the list.
4470TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344471 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454472 GURL origin1 = request_.url;
4473 GURL origin2("https://www.example.org/");
4474 ASSERT_NE(origin1.host(), origin2.host());
4475
4476 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524477 quic::QuicStreamOffset request_header_offset(0);
4478 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454479
rch5cb522462017-04-25 20:18:364480 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434481 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454482 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434483 mock_quic_data.AddWrite(
4484 SYNCHRONOUS,
4485 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334486 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434487 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4488 mock_quic_data.AddRead(
4489 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334490 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434491 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434492 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434493 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334494 ASYNC, ConstructServerDataPacket(
4495 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414496 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434497 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454498
4499 // Second request.
Yixin Wang079ad542018-01-11 04:06:054500 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174501 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4502 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054503 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174504 QuicTestPacketMaker server_maker2(
4505 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4506 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584507 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434508 SYNCHRONOUS,
4509 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334510 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434511 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334512 GetNthClientInitiatedBidirectionalStreamId(0),
4513 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434514 mock_quic_data.AddRead(
4515 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334516 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434517 GetResponseHeaders("200 OK"), &response_header_offset));
4518 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334519 ASYNC, ConstructServerDataPacket(
4520 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414521 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434522 mock_quic_data.AddWrite(
4523 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454524 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4525 mock_quic_data.AddRead(ASYNC, 0); // EOF
4526
4527 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4528
4529 AddHangingNonAlternateProtocolSocketData();
4530 AddHangingNonAlternateProtocolSocketData();
4531
4532 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564533 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4534 QuicStreamFactoryPeer::SetAlarmFactory(
4535 session_->quic_stream_factory(),
4536 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4537 &clock_));
bnc359ed2a2016-04-29 20:43:454538
4539 const char destination1[] = "first.example.com";
4540 const char destination2[] = "second.example.com";
4541
4542 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214543 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454544 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214545 http_server_properties_.SetQuicAlternativeService(
4546 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444547 supported_versions_);
bnc359ed2a2016-04-29 20:43:454548
4549 // Set up multiple alternative service entries for |origin2|,
4550 // the first one with a different destination as for |origin1|,
4551 // the second one with the same. The second one should be used,
4552 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214553 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454554 AlternativeServiceInfoVector alternative_services;
4555 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214556 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4557 alternative_service2, expiration,
4558 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454559 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214560 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4561 alternative_service1, expiration,
4562 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454563 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4564 alternative_services);
bnc359ed2a2016-04-29 20:43:454565 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524566 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454567 SendRequestAndExpectQuicResponse("hello!");
4568
4569 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524570 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454571 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584572
bnc359ed2a2016-04-29 20:43:454573 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304574}
4575
4576// Multiple origins have listed the same alternative services. When there's a
4577// existing QUIC session opened by a request to other origin,
4578// if the cert is valid, should select this QUIC session to make the request
4579// if this is also the first existing QUIC session.
4580TEST_P(QuicNetworkTransactionTest,
4581 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344582 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294583 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304584
rch9ae5b3b2016-02-11 00:36:294585 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304586 MockRead http_reads[] = {
4587 MockRead("HTTP/1.1 200 OK\r\n"),
4588 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294589 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304590 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4591 MockRead(ASYNC, OK)};
4592
Ryan Sleevib8d7ea02018-05-07 20:01:014593 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304594 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084595 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304596 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4597
4598 // HTTP data for request to mail.example.org.
4599 MockRead http_reads2[] = {
4600 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294601 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304602 MockRead("hello world from mail.example.org"),
4603 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4604 MockRead(ASYNC, OK)};
4605
Ryan Sleevib8d7ea02018-05-07 20:01:014606 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304607 socket_factory_.AddSocketDataProvider(&http_data2);
4608 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4609
Ryan Hamilton8d9ee76e2018-05-29 23:52:524610 quic::QuicStreamOffset request_header_offset = 0;
4611 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304612
Yixin Wang079ad542018-01-11 04:06:054613 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174614 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4615 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054616 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584617 server_maker_.set_hostname("www.example.org");
4618 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304619 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364620 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434621 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304622 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584623 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434624 SYNCHRONOUS,
4625 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334626 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434627 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4628
4629 mock_quic_data.AddRead(
4630 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334631 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434632 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434633 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334634 mock_quic_data.AddRead(
4635 ASYNC, ConstructServerDataPacket(
4636 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414637 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434638 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4639 // Second QUIC request data.
4640 mock_quic_data.AddWrite(
4641 SYNCHRONOUS,
4642 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334643 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434644 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334645 GetNthClientInitiatedBidirectionalStreamId(0),
4646 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434647 mock_quic_data.AddRead(
4648 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334649 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434650 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334651 mock_quic_data.AddRead(
4652 ASYNC, ConstructServerDataPacket(
4653 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414654 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434655 mock_quic_data.AddWrite(
4656 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304657 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4658 mock_quic_data.AddRead(ASYNC, 0); // EOF
4659
4660 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304661
rtennetib8e80fb2016-05-16 00:12:094662 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324663 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564664 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4665 QuicStreamFactoryPeer::SetAlarmFactory(
4666 session_->quic_stream_factory(),
4667 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4668 &clock_));
zhongyi32569c62016-01-08 02:54:304669
4670 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294671 request_.url = GURL("https://www.example.org/");
4672 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304673 request_.url = GURL("https://mail.example.org/");
4674 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4675
rch9ae5b3b2016-02-11 00:36:294676 // Open a QUIC session to mail.example.org:443 when making request
4677 // to mail.example.org.
4678 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454679 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304680
rch9ae5b3b2016-02-11 00:36:294681 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304682 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454683 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524684}
4685
4686TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524687 MockRead http_reads[] = {
4688 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564689 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524690 MockRead("hello world"),
4691 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4692 MockRead(ASYNC, OK)};
4693
Ryan Sleevib8d7ea02018-05-07 20:01:014694 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524695 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084696 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564697 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524698
rtennetib8e80fb2016-05-16 00:12:094699 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324700 CreateSession();
bncc958faa2015-07-31 18:14:524701
4702 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454703
4704 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344705 AlternativeServiceInfoVector alternative_service_info_vector =
4706 http_server_properties_.GetAlternativeServiceInfos(http_server);
4707 ASSERT_EQ(1u, alternative_service_info_vector.size());
4708 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544709 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344710 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4711 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4712 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524713}
4714
4715TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524716 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564717 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4718 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524719 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4720 MockRead(ASYNC, OK)};
4721
Ryan Sleevib8d7ea02018-05-07 20:01:014722 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524723 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084724 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564725 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524726
4727 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524728 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364729 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434730 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4731 mock_quic_data.AddWrite(
4732 SYNCHRONOUS,
4733 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334734 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434735 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434736 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334737 ASYNC, ConstructServerResponseHeadersPacket(
4738 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4739 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434740 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334741 mock_quic_data.AddRead(
4742 ASYNC, ConstructServerDataPacket(
4743 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414744 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434745 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524746 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4747 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524748
4749 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4750
rtennetib8e80fb2016-05-16 00:12:094751 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324752 CreateSession();
bncc958faa2015-07-31 18:14:524753
bnc3472afd2016-11-17 15:27:214754 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524755 HostPortPair::FromURL(request_.url));
4756 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4757 alternative_service);
4758 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4759 alternative_service));
4760
4761 SendRequestAndExpectHttpResponse("hello world");
4762 SendRequestAndExpectQuicResponse("hello!");
4763
mmenkee24011922015-12-17 22:12:594764 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524765
4766 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4767 alternative_service));
rchac7f35e2017-03-15 20:42:304768 EXPECT_NE(nullptr,
4769 http_server_properties_.GetServerNetworkStats(
4770 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524771}
4772
bncc958faa2015-07-31 18:14:524773TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524774 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564775 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4776 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524777 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4778 MockRead(ASYNC, OK)};
4779
Ryan Sleevib8d7ea02018-05-07 20:01:014780 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524781 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564782 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524783
4784 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524785 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364786 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434787 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4788 mock_quic_data.AddWrite(
4789 SYNCHRONOUS,
4790 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334791 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434792 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434793 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334794 ASYNC, ConstructServerResponseHeadersPacket(
4795 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4796 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434797 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334798 mock_quic_data.AddRead(
4799 ASYNC, ConstructServerDataPacket(
4800 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414801 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434802 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524803 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4804
4805 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4806
4807 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324808 CreateSession();
bncc958faa2015-07-31 18:14:524809
4810 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4811 SendRequestAndExpectHttpResponse("hello world");
4812}
4813
tbansalc3308d72016-08-27 10:25:044814// Tests that the connection to an HTTPS proxy is raced with an available
4815// alternative proxy server.
4816TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274817 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594818 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494819 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044820
4821 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524822 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364823 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434824 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4825 mock_quic_data.AddWrite(
4826 SYNCHRONOUS,
4827 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334828 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434829 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434830 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334831 ASYNC, ConstructServerResponseHeadersPacket(
4832 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4833 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434834 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334835 mock_quic_data.AddRead(
4836 ASYNC, ConstructServerDataPacket(
4837 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414838 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434839 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044840 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4841 mock_quic_data.AddRead(ASYNC, 0); // EOF
4842
4843 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4844
4845 // There is no need to set up main job, because no attempt will be made to
4846 // speak to the proxy over TCP.
4847 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044848 TestProxyDelegate test_proxy_delegate;
4849 const HostPortPair host_port_pair("mail.example.org", 443);
4850
4851 test_proxy_delegate.set_alternative_proxy_server(
4852 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524853 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044854 CreateSession();
4855 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4856
4857 // The main job needs to hang in order to guarantee that the alternative
4858 // proxy server job will "win".
4859 AddHangingNonAlternateProtocolSocketData();
4860
4861 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4862
4863 // Verify that the alternative proxy server is not marked as broken.
4864 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4865
4866 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594867 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274868
4869 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4870 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4871 1);
tbansalc3308d72016-08-27 10:25:044872}
4873
bnc1c196c6e2016-05-28 13:51:484874TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304875 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274876 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304877
4878 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564879 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294880 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564881 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304882
4883 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564884 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484885 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564886 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304887
Ryan Sleevib8d7ea02018-05-07 20:01:014888 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504889 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084890 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504891 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304892
4893 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454894 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304895 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454896 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304897 };
Ryan Sleevib8d7ea02018-05-07 20:01:014898 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504899 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304900
4901 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014902 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504903 socket_factory_.AddSocketDataProvider(&http_data2);
4904 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304905
bnc912a04b2016-04-20 14:19:504906 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304907
4908 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304909 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174910 ASSERT_TRUE(http_data.AllReadDataConsumed());
4911 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304912
4913 // Now run the second request in which the QUIC socket hangs,
4914 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304915 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454916 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304917
rch37de576c2015-05-17 20:28:174918 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4919 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454920 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304921}
4922
[email protected]1e960032013-12-20 19:00:204923TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204924 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524925 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:034926 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434927 mock_quic_data.AddWrite(
4928 SYNCHRONOUS,
4929 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334930 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434931 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434932 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334933 ASYNC, ConstructServerResponseHeadersPacket(
4934 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4935 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434936 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334937 mock_quic_data.AddRead(
4938 ASYNC, ConstructServerDataPacket(
4939 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414940 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434941 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504942 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594943 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484944
rcha5399e02015-04-21 19:32:044945 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484946
rtennetib8e80fb2016-05-16 00:12:094947 // The non-alternate protocol job needs to hang in order to guarantee that
4948 // the alternate-protocol job will "win".
4949 AddHangingNonAlternateProtocolSocketData();
4950
rch3f4b8452016-02-23 16:59:324951 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274952 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194953 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304954
4955 EXPECT_EQ(nullptr,
4956 http_server_properties_.GetServerNetworkStats(
4957 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484958}
4959
[email protected]1e960032013-12-20 19:00:204960TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204961 MockQuicData mock_quic_data;
Michael Warres167db3e2019-03-01 21:38:034962 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334963 mock_quic_data.AddWrite(
4964 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4965 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4966 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434967 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334968 ASYNC, ConstructServerResponseHeadersPacket(
4969 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4970 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434971 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334972 mock_quic_data.AddRead(
4973 ASYNC, ConstructServerDataPacket(
4974 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414975 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434976 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504977 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594978 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044979 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274980
4981 // In order for a new QUIC session to be established via alternate-protocol
4982 // without racing an HTTP connection, we need the host resolution to happen
4983 // synchronously.
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]3a120a6b2013-06-25 01:08:274987
rtennetib8e80fb2016-05-16 00:12:094988 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324989 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274990 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274991 SendRequestAndExpectQuicResponse("hello!");
4992}
4993
[email protected]0fc924b2014-03-31 04:34:154994TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494995 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4996 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154997
4998 // Since we are using a proxy, the QUIC job will not succeed.
4999 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295000 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5001 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565002 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155003
5004 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565005 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485006 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565007 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155008
Ryan Sleevib8d7ea02018-05-07 20:01:015009 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155010 socket_factory_.AddSocketDataProvider(&http_data);
5011
5012 // In order for a new QUIC session to be established via alternate-protocol
5013 // without racing an HTTP connection, we need the host resolution to happen
5014 // synchronously.
5015 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295016 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565017 "");
[email protected]0fc924b2014-03-31 04:34:155018
rch9ae5b3b2016-02-11 00:36:295019 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325020 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275021 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155022 SendRequestAndExpectHttpResponse("hello world");
5023}
5024
[email protected]1e960032013-12-20 19:00:205025TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:205026 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525027 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365028 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435029 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5030 mock_quic_data.AddWrite(
5031 SYNCHRONOUS,
5032 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335033 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435034 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435035 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335036 ASYNC, ConstructServerResponseHeadersPacket(
5037 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5038 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435039 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335040 mock_quic_data.AddRead(
5041 ASYNC, ConstructServerDataPacket(
5042 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415043 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435044 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595045 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045046 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125047
rtennetib8e80fb2016-05-16 00:12:095048 // The non-alternate protocol job needs to hang in order to guarantee that
5049 // the alternate-protocol job will "win".
5050 AddHangingNonAlternateProtocolSocketData();
5051
[email protected]11c05872013-08-20 02:04:125052 // In order for a new QUIC session to be established via alternate-protocol
5053 // without racing an HTTP connection, we need the host resolution to happen
5054 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5055 // connection to the the server, in this test we require confirmation
5056 // before encrypting so the HTTP job will still start.
5057 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295058 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565059 "");
[email protected]11c05872013-08-20 02:04:125060
rch3f4b8452016-02-23 16:59:325061 CreateSession();
[email protected]11c05872013-08-20 02:04:125062 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275063 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125064
bnc691fda62016-08-12 00:43:165065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125066 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365067 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125069
5070 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525071 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015072 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505073
bnc691fda62016-08-12 00:43:165074 CheckWasQuicResponse(&trans);
5075 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125076}
5077
Steven Valdez58097ec32018-07-16 18:29:045078TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5079 MockQuicData mock_quic_data;
5080 quic::QuicStreamOffset client_header_stream_offset = 0;
5081 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035082 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045083 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335084 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5085 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5086 true, GetRequestHeaders("GET", "https", "/"),
5087 &client_header_stream_offset));
5088 mock_quic_data.AddRead(
5089 ASYNC,
5090 ConstructServerResponseHeadersPacket(
5091 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5092 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5093 mock_quic_data.AddWrite(SYNCHRONOUS,
5094 ConstructClientAckAndRstPacket(
5095 2, GetNthClientInitiatedBidirectionalStreamId(0),
5096 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045097
5098 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5099
5100 spdy::SpdySettingsIR settings_frame;
5101 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5102 quic::kDefaultMaxUncompressedHeaderSize);
5103 spdy::SpdySerializedFrame spdy_frame(
5104 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5105 mock_quic_data.AddWrite(
5106 SYNCHRONOUS,
5107 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565108 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5109 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045110 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5111 client_header_stream_offset += spdy_frame.size();
5112
5113 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335114 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5115 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5116 true, GetRequestHeaders("GET", "https", "/"),
5117 GetNthClientInitiatedBidirectionalStreamId(0),
5118 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045119 mock_quic_data.AddRead(
5120 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335121 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045122 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:435123 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045124 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335125 ASYNC, ConstructServerDataPacket(
5126 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415127 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045128 mock_quic_data.AddWrite(
5129 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5130 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5131 mock_quic_data.AddRead(ASYNC, 0); // EOF
5132
5133 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5134
5135 // In order for a new QUIC session to be established via alternate-protocol
5136 // without racing an HTTP connection, we need the host resolution to happen
5137 // synchronously.
5138 host_resolver_.set_synchronous_mode(true);
5139 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5140 "");
Steven Valdez58097ec32018-07-16 18:29:045141
5142 AddHangingNonAlternateProtocolSocketData();
5143 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275144 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565145 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5146 QuicStreamFactoryPeer::SetAlarmFactory(
5147 session_->quic_stream_factory(),
5148 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5149 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045150
5151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5152 TestCompletionCallback callback;
5153 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5155
5156 // Confirm the handshake after the 425 Too Early.
5157 base::RunLoop().RunUntilIdle();
5158
5159 // The handshake hasn't been confirmed yet, so the retry should not have
5160 // succeeded.
5161 EXPECT_FALSE(callback.have_result());
5162
5163 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5164 quic::QuicSession::HANDSHAKE_CONFIRMED);
5165
5166 EXPECT_THAT(callback.WaitForResult(), IsOk());
5167 CheckWasQuicResponse(&trans);
5168 CheckResponseData(&trans, "hello!");
5169}
5170
5171TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5172 MockQuicData mock_quic_data;
5173 quic::QuicStreamOffset client_header_stream_offset = 0;
5174 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035175 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045176 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335177 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5178 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5179 true, GetRequestHeaders("GET", "https", "/"),
5180 &client_header_stream_offset));
5181 mock_quic_data.AddRead(
5182 ASYNC,
5183 ConstructServerResponseHeadersPacket(
5184 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5185 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5186 mock_quic_data.AddWrite(SYNCHRONOUS,
5187 ConstructClientAckAndRstPacket(
5188 2, GetNthClientInitiatedBidirectionalStreamId(0),
5189 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045190
5191 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5192
5193 spdy::SpdySettingsIR settings_frame;
5194 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5195 quic::kDefaultMaxUncompressedHeaderSize);
5196 spdy::SpdySerializedFrame spdy_frame(
5197 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5198 mock_quic_data.AddWrite(
5199 SYNCHRONOUS,
5200 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565201 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5202 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045203 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5204 client_header_stream_offset += spdy_frame.size();
5205
5206 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335207 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5208 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5209 true, GetRequestHeaders("GET", "https", "/"),
5210 GetNthClientInitiatedBidirectionalStreamId(0),
5211 &client_header_stream_offset));
5212 mock_quic_data.AddRead(
5213 ASYNC,
5214 ConstructServerResponseHeadersPacket(
5215 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5216 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5217 mock_quic_data.AddWrite(SYNCHRONOUS,
5218 ConstructClientAckAndRstPacket(
5219 5, GetNthClientInitiatedBidirectionalStreamId(1),
5220 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045221 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5222 mock_quic_data.AddRead(ASYNC, 0); // EOF
5223
5224 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5225
5226 // In order for a new QUIC session to be established via alternate-protocol
5227 // without racing an HTTP connection, we need the host resolution to happen
5228 // synchronously.
5229 host_resolver_.set_synchronous_mode(true);
5230 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5231 "");
Steven Valdez58097ec32018-07-16 18:29:045232
5233 AddHangingNonAlternateProtocolSocketData();
5234 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275235 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565236 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5237 QuicStreamFactoryPeer::SetAlarmFactory(
5238 session_->quic_stream_factory(),
5239 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5240 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045241
5242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5243 TestCompletionCallback callback;
5244 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5245 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5246
5247 // Confirm the handshake after the 425 Too Early.
5248 base::RunLoop().RunUntilIdle();
5249
5250 // The handshake hasn't been confirmed yet, so the retry should not have
5251 // succeeded.
5252 EXPECT_FALSE(callback.have_result());
5253
5254 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5255 quic::QuicSession::HANDSHAKE_CONFIRMED);
5256
5257 EXPECT_THAT(callback.WaitForResult(), IsOk());
5258 const HttpResponseInfo* response = trans.GetResponseInfo();
5259 ASSERT_TRUE(response != nullptr);
5260 ASSERT_TRUE(response->headers.get() != nullptr);
5261 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5262 EXPECT_TRUE(response->was_fetched_via_spdy);
5263 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565264 EXPECT_EQ(
5265 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5266 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045267}
5268
zhongyica364fbb2015-12-12 03:39:125269TEST_P(QuicNetworkTransactionTest,
5270 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485271 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125272 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525273 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365274 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435275 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5276 mock_quic_data.AddWrite(
5277 SYNCHRONOUS,
5278 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335279 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435280 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125281 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525282 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435283 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125284 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5285
5286 // The non-alternate protocol job needs to hang in order to guarantee that
5287 // the alternate-protocol job will "win".
5288 AddHangingNonAlternateProtocolSocketData();
5289
5290 // In order for a new QUIC session to be established via alternate-protocol
5291 // without racing an HTTP connection, we need the host resolution to happen
5292 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5293 // connection to the the server, in this test we require confirmation
5294 // before encrypting so the HTTP job will still start.
5295 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295296 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125297 "");
zhongyica364fbb2015-12-12 03:39:125298
rch3f4b8452016-02-23 16:59:325299 CreateSession();
zhongyica364fbb2015-12-12 03:39:125300 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275301 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125302
bnc691fda62016-08-12 00:43:165303 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125304 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365305 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015306 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125307
5308 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525309 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015310 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125311
5312 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525313 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125314
bnc691fda62016-08-12 00:43:165315 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125316 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525317 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5318 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125319}
5320
5321TEST_P(QuicNetworkTransactionTest,
5322 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485323 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125324 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525325 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365326 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435327 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5328 mock_quic_data.AddWrite(
5329 SYNCHRONOUS,
5330 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335331 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435332 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215333 // Peer sending data from an non-existing stream causes this end to raise
5334 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335335 mock_quic_data.AddRead(
5336 ASYNC, ConstructServerRstPacket(
5337 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5338 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215339 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525340 mock_quic_data.AddWrite(
5341 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5342 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5343 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125344 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5345
5346 // The non-alternate protocol job needs to hang in order to guarantee that
5347 // the alternate-protocol job will "win".
5348 AddHangingNonAlternateProtocolSocketData();
5349
5350 // In order for a new QUIC session to be established via alternate-protocol
5351 // without racing an HTTP connection, we need the host resolution to happen
5352 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5353 // connection to the the server, in this test we require confirmation
5354 // before encrypting so the HTTP job will still start.
5355 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295356 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125357 "");
zhongyica364fbb2015-12-12 03:39:125358
rch3f4b8452016-02-23 16:59:325359 CreateSession();
zhongyica364fbb2015-12-12 03:39:125360 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275361 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125362
bnc691fda62016-08-12 00:43:165363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125364 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365365 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125367
5368 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525369 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015370 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125371 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525372 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125373
bnc691fda62016-08-12 00:43:165374 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525375 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125376}
5377
rchcd5f1c62016-06-23 02:43:485378TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5379 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525380 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365381 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435382 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5383 mock_quic_data.AddWrite(
5384 SYNCHRONOUS,
5385 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335386 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435387 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485388 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335389 mock_quic_data.AddRead(
5390 ASYNC, ConstructServerResponseHeadersPacket(
5391 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5392 GetResponseHeaders("200 OK")));
5393 mock_quic_data.AddRead(
5394 ASYNC, ConstructServerRstPacket(
5395 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5396 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435397 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485398 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5399 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5400
5401 // The non-alternate protocol job needs to hang in order to guarantee that
5402 // the alternate-protocol job will "win".
5403 AddHangingNonAlternateProtocolSocketData();
5404
5405 // In order for a new QUIC session to be established via alternate-protocol
5406 // without racing an HTTP connection, we need the host resolution to happen
5407 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5408 // connection to the the server, in this test we require confirmation
5409 // before encrypting so the HTTP job will still start.
5410 host_resolver_.set_synchronous_mode(true);
5411 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5412 "");
rchcd5f1c62016-06-23 02:43:485413
5414 CreateSession();
5415 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275416 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485417
bnc691fda62016-08-12 00:43:165418 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485419 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365420 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485422
5423 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525424 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485425 // Read the headers.
robpercival214763f2016-07-01 23:27:015426 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485427
bnc691fda62016-08-12 00:43:165428 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485429 ASSERT_TRUE(response != nullptr);
5430 ASSERT_TRUE(response->headers.get() != nullptr);
5431 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5432 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525433 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565434 EXPECT_EQ(
5435 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5436 response->connection_info);
rchcd5f1c62016-06-23 02:43:485437
5438 std::string response_data;
bnc691fda62016-08-12 00:43:165439 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485440}
5441
5442TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485443 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485444 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525445 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365446 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435447 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5448 mock_quic_data.AddWrite(
5449 SYNCHRONOUS,
5450 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335451 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435452 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335453 mock_quic_data.AddRead(
5454 ASYNC, ConstructServerRstPacket(
5455 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5456 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485457 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5458 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5459
5460 // The non-alternate protocol job needs to hang in order to guarantee that
5461 // the alternate-protocol job will "win".
5462 AddHangingNonAlternateProtocolSocketData();
5463
5464 // In order for a new QUIC session to be established via alternate-protocol
5465 // without racing an HTTP connection, we need the host resolution to happen
5466 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5467 // connection to the the server, in this test we require confirmation
5468 // before encrypting so the HTTP job will still start.
5469 host_resolver_.set_synchronous_mode(true);
5470 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5471 "");
rchcd5f1c62016-06-23 02:43:485472
5473 CreateSession();
5474 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275475 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485476
bnc691fda62016-08-12 00:43:165477 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485478 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365479 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485481
5482 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525483 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485484 // Read the headers.
robpercival214763f2016-07-01 23:27:015485 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485486}
5487
[email protected]1e960032013-12-20 19:00:205488TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305489 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525490 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585491 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305492 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505493 MockRead(ASYNC, close->data(), close->length()),
5494 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5495 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305496 };
Ryan Sleevib8d7ea02018-05-07 20:01:015497 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305498 socket_factory_.AddSocketDataProvider(&quic_data);
5499
5500 // Main job which will succeed even though the alternate job fails.
5501 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025502 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5503 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5504 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305505
Ryan Sleevib8d7ea02018-05-07 20:01:015506 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305507 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565508 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305509
rch3f4b8452016-02-23 16:59:325510 CreateSession();
David Schinazic8281052019-01-24 06:14:175511 AddQuicAlternateProtocolMapping(
5512 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195513 SendRequestAndExpectHttpResponse("hello from http");
5514 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305515}
5516
[email protected]1e960032013-12-20 19:00:205517TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595518 // Alternate-protocol job
5519 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025520 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595521 };
Ryan Sleevib8d7ea02018-05-07 20:01:015522 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595523 socket_factory_.AddSocketDataProvider(&quic_data);
5524
5525 // Main job which will succeed even though the alternate job fails.
5526 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025527 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5528 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5529 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595530
Ryan Sleevib8d7ea02018-05-07 20:01:015531 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595532 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565533 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595534
rch3f4b8452016-02-23 16:59:325535 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595536
Ryan Hamilton9835e662018-08-02 05:36:275537 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195538 SendRequestAndExpectHttpResponse("hello from http");
5539 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595540}
5541
[email protected]00c159f2014-05-21 22:38:165542TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535543 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165544 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025545 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165546 };
Ryan Sleevib8d7ea02018-05-07 20:01:015547 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165548 socket_factory_.AddSocketDataProvider(&quic_data);
5549
[email protected]eb71ab62014-05-23 07:57:535550 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165551 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025552 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165553 };
5554
Ryan Sleevib8d7ea02018-05-07 20:01:015555 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165556 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5557 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565558 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165559
rtennetib8e80fb2016-05-16 00:12:095560 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325561 CreateSession();
[email protected]00c159f2014-05-21 22:38:165562
Ryan Hamilton9835e662018-08-02 05:36:275563 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165564 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165565 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165566 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015567 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5568 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165569 ExpectQuicAlternateProtocolMapping();
5570}
5571
Zhongyi Shia0cef1082017-08-25 01:49:505572TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5573 // Tests that TCP job is delayed and QUIC job does not require confirmation
5574 // if QUIC was recently supported on the same IP on start.
5575
5576 // Set QUIC support on the last IP address, which is same with the local IP
5577 // address. Require confirmation mode will be turned off immediately when
5578 // local IP address is sorted out after we configure the UDP socket.
5579 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5580
5581 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525582 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035583 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435584 mock_quic_data.AddWrite(
5585 SYNCHRONOUS,
5586 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335587 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435588 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435589 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335590 ASYNC, ConstructServerResponseHeadersPacket(
5591 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5592 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435593 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335594 mock_quic_data.AddRead(
5595 ASYNC, ConstructServerDataPacket(
5596 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415597 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435598 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505599 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5600 mock_quic_data.AddRead(ASYNC, 0); // EOF
5601
5602 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5603 // No HTTP data is mocked as TCP job never starts in this case.
5604
5605 CreateSession();
5606 // QuicStreamFactory by default requires confirmation on construction.
5607 session_->quic_stream_factory()->set_require_confirmation(true);
5608
Ryan Hamilton9835e662018-08-02 05:36:275609 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505610
5611 // Stall host resolution so that QUIC job will not succeed synchronously.
5612 // Socket will not be configured immediately and QUIC support is not sorted
5613 // out, TCP job will still be delayed as server properties indicates QUIC
5614 // support on last IP address.
5615 host_resolver_.set_synchronous_mode(false);
5616
5617 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5618 TestCompletionCallback callback;
5619 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5620 IsError(ERR_IO_PENDING));
5621 // Complete host resolution in next message loop so that QUIC job could
5622 // proceed.
5623 base::RunLoop().RunUntilIdle();
5624 EXPECT_THAT(callback.WaitForResult(), IsOk());
5625
5626 CheckWasQuicResponse(&trans);
5627 CheckResponseData(&trans, "hello!");
5628}
5629
5630TEST_P(QuicNetworkTransactionTest,
5631 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5632 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5633 // was recently supported on a different IP address on start.
5634
5635 // Set QUIC support on the last IP address, which is different with the local
5636 // IP address. Require confirmation mode will remain when local IP address is
5637 // sorted out after we configure the UDP socket.
5638 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5639
5640 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525641 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505642 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435643 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5644 mock_quic_data.AddWrite(
5645 SYNCHRONOUS,
5646 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335647 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435648 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435649 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335650 ASYNC, ConstructServerResponseHeadersPacket(
5651 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5652 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435653 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335654 mock_quic_data.AddRead(
5655 ASYNC, ConstructServerDataPacket(
5656 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415657 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435658 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505659 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5660 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5661 // No HTTP data is mocked as TCP job will be delayed and never starts.
5662
5663 CreateSession();
5664 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275665 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505666
5667 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5668 // Socket will not be configured immediately and QUIC support is not sorted
5669 // out, TCP job will still be delayed as server properties indicates QUIC
5670 // support on last IP address.
5671 host_resolver_.set_synchronous_mode(false);
5672
5673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5674 TestCompletionCallback callback;
5675 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5676 IsError(ERR_IO_PENDING));
5677
5678 // Complete host resolution in next message loop so that QUIC job could
5679 // proceed.
5680 base::RunLoop().RunUntilIdle();
5681 // Explicitly confirm the handshake so that QUIC job could succeed.
5682 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525683 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505684 EXPECT_THAT(callback.WaitForResult(), IsOk());
5685
5686 CheckWasQuicResponse(&trans);
5687 CheckResponseData(&trans, "hello!");
5688}
5689
Ryan Hamilton75f197262017-08-17 14:00:075690TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5691 // Test that NetErrorDetails is correctly populated, even if the
5692 // handshake has not yet been confirmed and no stream has been created.
5693
5694 // QUIC job will pause. When resumed, it will fail.
5695 MockQuicData mock_quic_data;
5696 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5697 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5698 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5699
5700 // Main job will also fail.
5701 MockRead http_reads[] = {
5702 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5703 };
5704
Ryan Sleevib8d7ea02018-05-07 20:01:015705 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075706 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5707 socket_factory_.AddSocketDataProvider(&http_data);
5708 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5709
5710 AddHangingNonAlternateProtocolSocketData();
5711 CreateSession();
5712 // Require handshake confirmation to ensure that no QUIC streams are
5713 // created, and to ensure that the TCP job does not wait for the QUIC
5714 // job to fail before it starts.
5715 session_->quic_stream_factory()->set_require_confirmation(true);
5716
Ryan Hamilton9835e662018-08-02 05:36:275717 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075718 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5719 TestCompletionCallback callback;
5720 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5721 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5722 // Allow the TCP job to fail.
5723 base::RunLoop().RunUntilIdle();
5724 // Now let the QUIC job fail.
5725 mock_quic_data.Resume();
5726 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5727 ExpectQuicAlternateProtocolMapping();
5728 NetErrorDetails details;
5729 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525730 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075731}
5732
[email protected]1e960032013-12-20 19:00:205733TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455734 // Alternate-protocol job
5735 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025736 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455737 };
Ryan Sleevib8d7ea02018-05-07 20:01:015738 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455739 socket_factory_.AddSocketDataProvider(&quic_data);
5740
[email protected]c92c1b52014-05-31 04:16:065741 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015742 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065743 socket_factory_.AddSocketDataProvider(&quic_data2);
5744
[email protected]4d283b32013-10-17 12:57:275745 // Final job that will proceed when the QUIC job fails.
5746 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025747 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5748 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5749 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275750
Ryan Sleevib8d7ea02018-05-07 20:01:015751 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275752 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565753 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275754
rtennetiafccbc062016-05-16 18:21:145755 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325756 CreateSession();
[email protected]77c6c162013-08-17 02:57:455757
Ryan Hamilton9835e662018-08-02 05:36:275758 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455759
[email protected]4d283b32013-10-17 12:57:275760 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455761
5762 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275763
rch37de576c2015-05-17 20:28:175764 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5765 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455766}
5767
[email protected]93b31772014-06-19 08:03:355768TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035769 // Alternate-protocol job
5770 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595771 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035772 };
Ryan Sleevib8d7ea02018-05-07 20:01:015773 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035774 socket_factory_.AddSocketDataProvider(&quic_data);
5775
5776 // Main job that will proceed when the QUIC job fails.
5777 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025778 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5779 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5780 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035781
Ryan Sleevib8d7ea02018-05-07 20:01:015782 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035783 socket_factory_.AddSocketDataProvider(&http_data);
5784
rtennetib8e80fb2016-05-16 00:12:095785 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325786 CreateSession();
[email protected]65768442014-06-06 23:37:035787
Ryan Hamilton9835e662018-08-02 05:36:275788 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035789
5790 SendRequestAndExpectHttpResponse("hello from http");
5791}
5792
[email protected]eb71ab62014-05-23 07:57:535793TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335794 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015795 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495796 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335797 socket_factory_.AddSocketDataProvider(&quic_data);
5798
5799 // Main job which will succeed even though the alternate job fails.
5800 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025801 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5802 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5803 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335804
Ryan Sleevib8d7ea02018-05-07 20:01:015805 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335806 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565807 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335808
rch3f4b8452016-02-23 16:59:325809 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275810 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335811 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535812
5813 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335814}
5815
[email protected]4fee9672014-01-08 14:47:155816TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Nick Harper23290b82019-05-02 00:02:565817 if (version_.transport_version >= quic::QUIC_VERSION_47) {
Michael Warres167db3e2019-03-01 21:38:035818 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
5819 return;
5820 }
[email protected]4fee9672014-01-08 14:47:155821 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175822 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5823 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045824 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155825
5826 // When the QUIC connection fails, we will try the request again over HTTP.
5827 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485828 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565829 MockRead("hello world"),
5830 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5831 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155832
Ryan Sleevib8d7ea02018-05-07 20:01:015833 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155834 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565835 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155836
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);
rch9ae5b3b2016-02-11 00:36:295841 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565842 "");
[email protected]4fee9672014-01-08 14:47:155843
rch3f4b8452016-02-23 16:59:325844 CreateSession();
David Schinazic8281052019-01-24 06:14:175845 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5846 AddQuicAlternateProtocolMapping(
5847 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155848 SendRequestAndExpectHttpResponse("hello world");
5849}
5850
tbansalc3308d72016-08-27 10:25:045851// For an alternative proxy that supports QUIC, test that the request is
5852// successfully fetched by the main job when the alternate proxy job encounters
5853// an error.
5854TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5855 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5856}
5857TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5858 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5859}
5860TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5861 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5862}
5863TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5864 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5865}
5866TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5867 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5868}
5869TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5870 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5871}
5872TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5873 TestAlternativeProxy(ERR_IO_PENDING);
5874}
5875TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5876 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5877}
5878
5879TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5880 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175881 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5882 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335883 mock_quic_data.AddWrite(
5884 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5885 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5886 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435887 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045888 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5889
5890 // When the QUIC connection fails, we will try the request again over HTTP.
5891 MockRead http_reads[] = {
5892 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5893 MockRead("hello world"),
5894 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5895 MockRead(ASYNC, OK)};
5896
Ryan Sleevib8d7ea02018-05-07 20:01:015897 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045898 socket_factory_.AddSocketDataProvider(&http_data);
5899 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5900
5901 TestProxyDelegate test_proxy_delegate;
5902 const HostPortPair host_port_pair("myproxy.org", 443);
5903 test_proxy_delegate.set_alternative_proxy_server(
5904 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5905 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5906
Ramin Halavatica8d5252018-03-12 05:33:495907 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5908 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525909 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045910 request_.url = GURL("http://mail.example.org/");
5911
5912 // In order for a new QUIC session to be established via alternate-protocol
5913 // without racing an HTTP connection, we need the host resolution to happen
5914 // synchronously.
5915 host_resolver_.set_synchronous_mode(true);
5916 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045917
5918 CreateSession();
David Schinazic8281052019-01-24 06:14:175919 crypto_client_stream_factory_.set_handshake_mode(
5920 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045921 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595922 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165923 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045924}
5925
bnc508835902015-05-12 20:10:295926TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585927 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385928 EXPECT_FALSE(
5929 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295930 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525931 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365932 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435933 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5934 mock_quic_data.AddWrite(
5935 SYNCHRONOUS,
5936 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335937 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435938 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435939 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335940 ASYNC, ConstructServerResponseHeadersPacket(
5941 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5942 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435943 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335944 mock_quic_data.AddRead(
5945 ASYNC, ConstructServerDataPacket(
5946 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415947 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435948 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505949 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295950 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5951
bncb07c05532015-05-14 19:07:205952 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095953 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325954 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275955 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295956 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385957 EXPECT_TRUE(
5958 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295959}
5960
zhongyi363c91c2017-03-23 23:16:085961// TODO(zhongyi): disabled this broken test as it was not testing the correct
5962// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5963TEST_P(QuicNetworkTransactionTest,
5964 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275965 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595966 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495967 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045968
5969 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045970
5971 test_proxy_delegate.set_alternative_proxy_server(
5972 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525973 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045974
5975 request_.url = GURL("http://mail.example.org/");
5976
5977 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5978 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015979 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045980 socket_factory_.AddSocketDataProvider(&socket_data);
5981
5982 // The non-alternate protocol job needs to hang in order to guarantee that
5983 // the alternate-protocol job will "win".
5984 AddHangingNonAlternateProtocolSocketData();
5985
5986 CreateSession();
5987 request_.method = "POST";
5988 ChunkedUploadDataStream upload_data(0);
5989 upload_data.AppendData("1", 1, true);
5990
5991 request_.upload_data_stream = &upload_data;
5992
5993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5994 TestCompletionCallback callback;
5995 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5997 EXPECT_NE(OK, callback.WaitForResult());
5998
5999 // Verify that the alternative proxy server is not marked as broken.
6000 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6001
6002 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596003 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276004
6005 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6006 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6007 1);
tbansalc3308d72016-08-27 10:25:046008}
6009
rtenneti56977812016-01-15 19:26:566010TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:416011 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576012 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566013
6014 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6015 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016016 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:566017 socket_factory_.AddSocketDataProvider(&socket_data);
6018
rtennetib8e80fb2016-05-16 00:12:096019 // The non-alternate protocol job needs to hang in order to guarantee that
6020 // the alternate-protocol job will "win".
6021 AddHangingNonAlternateProtocolSocketData();
6022
rtenneti56977812016-01-15 19:26:566023 CreateSession();
6024 request_.method = "POST";
6025 ChunkedUploadDataStream upload_data(0);
6026 upload_data.AppendData("1", 1, true);
6027
6028 request_.upload_data_stream = &upload_data;
6029
bnc691fda62016-08-12 00:43:166030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566031 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166032 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566034 EXPECT_NE(OK, callback.WaitForResult());
6035}
6036
rche11300ef2016-09-02 01:44:286037TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486038 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286039 ScopedMockNetworkChangeNotifier network_change_notifier;
6040 MockNetworkChangeNotifier* mock_ncn =
6041 network_change_notifier.mock_network_change_notifier();
6042 mock_ncn->ForceNetworkHandlesSupported();
6043 mock_ncn->SetConnectedNetworksList(
6044 {kDefaultNetworkForTests, kNewNetworkForTests});
6045
mmenke6ddfbea2017-05-31 21:48:416046 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286047 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316048 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286049
6050 MockQuicData socket_data;
6051 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526052 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436053 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336054 socket_data.AddWrite(
6055 SYNCHRONOUS,
6056 ConstructClientRequestHeadersPacket(
6057 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6058 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286059 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6060 socket_data.AddSocketDataToFactory(&socket_factory_);
6061
6062 MockQuicData socket_data2;
6063 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6064 socket_data2.AddSocketDataToFactory(&socket_factory_);
6065
6066 // The non-alternate protocol job needs to hang in order to guarantee that
6067 // the alternate-protocol job will "win".
6068 AddHangingNonAlternateProtocolSocketData();
6069
6070 CreateSession();
6071 request_.method = "POST";
6072 ChunkedUploadDataStream upload_data(0);
6073
6074 request_.upload_data_stream = &upload_data;
6075
rdsmith1d343be52016-10-21 20:37:506076 std::unique_ptr<HttpNetworkTransaction> trans(
6077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286078 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506079 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6081
6082 base::RunLoop().RunUntilIdle();
6083 upload_data.AppendData("1", 1, true);
6084 base::RunLoop().RunUntilIdle();
6085
6086 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506087 trans.reset();
rche11300ef2016-09-02 01:44:286088 session_.reset();
6089}
6090
Ryan Hamilton4b3574532017-10-30 20:17:256091TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6092 session_params_.origins_to_force_quic_on.insert(
6093 HostPortPair::FromString("mail.example.org:443"));
6094
6095 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526096 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436097 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256098 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336099 socket_data.AddWrite(
6100 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6101 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6102 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436103 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336104 ASYNC, ConstructServerResponseHeadersPacket(
6105 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6106 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436107 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336108 socket_data.AddRead(
6109 ASYNC, ConstructServerDataPacket(
6110 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416111 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436112 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256113 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166114 socket_data.AddWrite(
6115 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6116 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6117 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256118
6119 socket_data.AddSocketDataToFactory(&socket_factory_);
6120
6121 CreateSession();
6122
6123 SendRequestAndExpectQuicResponse("hello!");
6124 session_.reset();
6125}
6126
6127TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6128 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;
Zhongyi Shi32f2fd02018-04-16 18:23:436133 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256134 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336135 socket_data.AddWrite(
6136 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6137 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6138 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436139 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336140 ASYNC, ConstructServerResponseHeadersPacket(
6141 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6142 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436143 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336144 socket_data.AddRead(
6145 ASYNC, ConstructServerDataPacket(
6146 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416147 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436148 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256149 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166150 socket_data.AddWrite(
6151 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6152 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6153 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256154
6155 socket_data.AddSocketDataToFactory(&socket_factory_);
6156
6157 CreateSession();
6158
6159 SendRequestAndExpectQuicResponse("hello!");
6160 session_.reset();
6161}
6162
Ryan Hamilton9edcf1a2017-11-22 05:55:176163TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486164 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256165 session_params_.origins_to_force_quic_on.insert(
6166 HostPortPair::FromString("mail.example.org:443"));
6167
6168 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526169 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256170 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436171 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176172 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256173 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6174 }
6175 socket_data.AddSocketDataToFactory(&socket_factory_);
6176
6177 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176178 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6179 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6180 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6181 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256182
Ryan Hamilton8d9ee76e2018-05-29 23:52:526183 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6185 TestCompletionCallback callback;
6186 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176188 while (!callback.have_result()) {
6189 base::RunLoop().RunUntilIdle();
6190 quic_task_runner_->RunUntilIdle();
6191 }
6192 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256193 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176194 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6195 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6196 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526197 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6198 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256199}
6200
Ryan Hamilton9edcf1a2017-11-22 05:55:176201TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486202 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256203 session_params_.origins_to_force_quic_on.insert(
6204 HostPortPair::FromString("mail.example.org:443"));
6205
6206 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526207 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256208 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436209 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176210 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256211 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6212 }
6213 socket_data.AddSocketDataToFactory(&socket_factory_);
6214
6215 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176216 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6217 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6218 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6219 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256220
Ryan Hamilton8d9ee76e2018-05-29 23:52:526221 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256222 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6223 TestCompletionCallback callback;
6224 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176226 while (!callback.have_result()) {
6227 base::RunLoop().RunUntilIdle();
6228 quic_task_runner_->RunUntilIdle();
6229 }
6230 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256231 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176232 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6233 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6234 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526235 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6236 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256237}
6238
Cherie Shi7596de632018-02-22 07:28:186239TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486240 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186241 session_params_.origins_to_force_quic_on.insert(
6242 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436243 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526244 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6245 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186246
6247 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526248 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186249 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436250 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186251 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6252 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526253 socket_data.AddWrite(
6254 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6255 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186256 socket_data.AddSocketDataToFactory(&socket_factory_);
6257
6258 CreateSession();
6259
6260 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6261 TestCompletionCallback callback;
6262 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6264 base::RunLoop().RunUntilIdle();
6265 ASSERT_TRUE(callback.have_result());
6266 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6267 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6268 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6269}
6270
ckrasic769733c2016-06-30 00:42:136271// Adds coverage to catch regression such as https://crbug.com/622043
6272TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416273 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136274 HostPortPair::FromString("mail.example.org:443"));
6275
6276 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526277 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236278 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436279 mock_quic_data.AddWrite(
6280 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6281 &header_stream_offset));
6282 mock_quic_data.AddWrite(
6283 SYNCHRONOUS,
6284 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336285 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6286 true, true, GetRequestHeaders("GET", "https", "/"),
6287 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526288 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436289 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336290 ASYNC, ConstructServerPushPromisePacket(
6291 1, GetNthClientInitiatedBidirectionalStreamId(0),
6292 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6293 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6294 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576295 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566296 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336297 mock_quic_data.AddWrite(SYNCHRONOUS,
6298 ConstructClientPriorityPacket(
6299 client_packet_number++, false,
6300 GetNthServerInitiatedUnidirectionalStreamId(0),
6301 GetNthClientInitiatedBidirectionalStreamId(0),
6302 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576303 }
Zhongyi Shi32f2fd02018-04-16 18:23:436304 mock_quic_data.AddRead(
6305 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336306 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436307 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576308 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436309 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6310 mock_quic_data.AddRead(
6311 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336312 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6313 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436314 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436315 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336316 ASYNC, ConstructServerDataPacket(
6317 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416318 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576319 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436320 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436321 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436322 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336323 ASYNC, ConstructServerDataPacket(
6324 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416325 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336326 mock_quic_data.AddWrite(SYNCHRONOUS,
6327 ConstructClientAckAndRstPacket(
6328 client_packet_number++,
6329 GetNthServerInitiatedUnidirectionalStreamId(0),
6330 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136331 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6332 mock_quic_data.AddRead(ASYNC, 0); // EOF
6333 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6334
6335 // The non-alternate protocol job needs to hang in order to guarantee that
6336 // the alternate-protocol job will "win".
6337 AddHangingNonAlternateProtocolSocketData();
6338
6339 CreateSession();
6340
6341 // PUSH_PROMISE handling in the http layer gets exercised here.
6342 SendRequestAndExpectQuicResponse("hello!");
6343
6344 request_.url = GURL("https://mail.example.org/pushed.jpg");
6345 SendRequestAndExpectQuicResponse("and hello!");
6346
6347 // Check that the NetLog was filled reasonably.
6348 TestNetLogEntry::List entries;
6349 net_log_.GetEntries(&entries);
6350 EXPECT_LT(0u, entries.size());
6351
6352 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6353 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006354 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6355 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136356 EXPECT_LT(0, pos);
6357}
6358
rch56ec40a2017-06-23 14:48:446359// Regression test for http://crbug.com/719461 in which a promised stream
6360// is closed before the pushed headers arrive, but after the connection
6361// is closed and before the callbacks are executed.
6362TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486363 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446364 session_params_.origins_to_force_quic_on.insert(
6365 HostPortPair::FromString("mail.example.org:443"));
6366
6367 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526368 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236369 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446370 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436371 mock_quic_data.AddWrite(
6372 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6373 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446374 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436375 mock_quic_data.AddWrite(
6376 SYNCHRONOUS,
6377 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336378 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6379 true, true, GetRequestHeaders("GET", "https", "/"),
6380 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526381 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446382 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436383 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336384 ASYNC, ConstructServerPushPromisePacket(
6385 1, GetNthClientInitiatedBidirectionalStreamId(0),
6386 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6387 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6388 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576389 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566390 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336391 mock_quic_data.AddWrite(SYNCHRONOUS,
6392 ConstructClientPriorityPacket(
6393 client_packet_number++, false,
6394 GetNthServerInitiatedUnidirectionalStreamId(0),
6395 GetNthClientInitiatedBidirectionalStreamId(0),
6396 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576397 }
rch56ec40a2017-06-23 14:48:446398 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436399 mock_quic_data.AddRead(
6400 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336401 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436402 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446403 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576404 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436405 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446406 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436407 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436408 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336409 ASYNC, ConstructServerDataPacket(
6410 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416411 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446412 // Write error for the third request.
6413 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6414 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6415 mock_quic_data.AddRead(ASYNC, 0); // EOF
6416 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6417
6418 CreateSession();
6419
6420 // Send a request which triggers a push promise from the server.
6421 SendRequestAndExpectQuicResponse("hello!");
6422
6423 // Start a push transaction that will be cancelled after the connection
6424 // is closed, but before the callback is executed.
6425 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196426 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446427 session_.get());
6428 TestCompletionCallback callback2;
6429 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6431 base::RunLoop().RunUntilIdle();
6432
6433 // Cause the connection to close on a write error.
6434 HttpRequestInfo request3;
6435 request3.method = "GET";
6436 request3.url = GURL("https://mail.example.org/");
6437 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106438 request3.traffic_annotation =
6439 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446440 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6441 TestCompletionCallback callback3;
6442 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6443 IsError(ERR_IO_PENDING));
6444
6445 base::RunLoop().RunUntilIdle();
6446
6447 // When |trans2| is destroyed, the underlying stream will be closed.
6448 EXPECT_FALSE(callback2.have_result());
6449 trans2 = nullptr;
6450
6451 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6452}
6453
ckrasicda193a82016-07-09 00:39:366454TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416455 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366456 HostPortPair::FromString("mail.example.org:443"));
6457
6458 MockQuicData mock_quic_data;
6459
Ryan Hamilton8d9ee76e2018-05-29 23:52:526460 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416461 int write_packet_index = 1;
6462 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6463 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366464
Victor Vasiliev076657c2019-03-12 02:46:436465 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566466 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416467 mock_quic_data.AddWrite(
6468 SYNCHRONOUS,
6469 ConstructClientRequestHeadersAndDataFramesPacket(
6470 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6471 true, true, DEFAULT_PRIORITY,
6472 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6473 {"1"}));
6474 } else {
6475 mock_quic_data.AddWrite(
6476 SYNCHRONOUS,
6477 ConstructClientRequestHeadersAndDataFramesPacket(
6478 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6479 true, true, DEFAULT_PRIORITY,
6480 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6481 {header, "1"}));
6482 }
ckrasicda193a82016-07-09 00:39:366483
Zhongyi Shi32f2fd02018-04-16 18:23:436484 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336485 ASYNC, ConstructServerResponseHeadersPacket(
6486 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6487 GetResponseHeaders("200 OK")));
6488
Victor Vasiliev076657c2019-03-12 02:46:436489 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336490 mock_quic_data.AddRead(
6491 ASYNC, ConstructServerDataPacket(
6492 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416493 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366494
Renjief49758b2019-01-11 23:32:416495 mock_quic_data.AddWrite(
6496 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366497
6498 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6499 mock_quic_data.AddRead(ASYNC, 0); // EOF
6500 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6501
6502 // The non-alternate protocol job needs to hang in order to guarantee that
6503 // the alternate-protocol job will "win".
6504 AddHangingNonAlternateProtocolSocketData();
6505
6506 CreateSession();
6507 request_.method = "POST";
6508 ChunkedUploadDataStream upload_data(0);
6509 upload_data.AppendData("1", 1, true);
6510
6511 request_.upload_data_stream = &upload_data;
6512
6513 SendRequestAndExpectQuicResponse("hello!");
6514}
6515
allada71b2efb2016-09-09 04:57:486516class QuicURLRequestContext : public URLRequestContext {
6517 public:
6518 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6519 MockClientSocketFactory* socket_factory)
6520 : storage_(this) {
6521 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076522 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046523 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486524 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046525 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596526 storage_.set_proxy_resolution_service(
6527 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076528 storage_.set_ssl_config_service(
6529 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486530 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116531 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486532 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076533 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046534 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486535 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046536 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6537 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6538 false));
allada71b2efb2016-09-09 04:57:486539 }
6540
6541 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6542
6543 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6544
6545 private:
6546 MockClientSocketFactory* socket_factory_;
6547 URLRequestContextStorage storage_;
6548};
6549
6550TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416551 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486552 HostPortPair::FromString("mail.example.org:443"));
6553
6554 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526555 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366556 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436557 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136558 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486559 headers["user-agent"] = "";
6560 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336561 mock_quic_data.AddWrite(
6562 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6563 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6564 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486565
Ryan Hamilton8d9ee76e2018-05-29 23:52:526566 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336567 mock_quic_data.AddRead(
6568 ASYNC,
6569 ConstructServerResponseHeadersPacket(
6570 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6571 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486572
Victor Vasiliev076657c2019-03-12 02:46:436573 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366574 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336575 ASYNC, ConstructServerDataPacket(
6576 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6577 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436578 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486579
6580 mock_quic_data.AddRead(ASYNC, 0); // EOF
6581
6582 CreateSession();
6583
6584 TestDelegate delegate;
6585 QuicURLRequestContext quic_url_request_context(std::move(session_),
6586 &socket_factory_);
6587
6588 mock_quic_data.AddSocketDataToFactory(
6589 &quic_url_request_context.socket_factory());
6590 TestNetworkDelegate network_delegate;
6591 quic_url_request_context.set_network_delegate(&network_delegate);
6592
6593 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296594 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6595 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486596 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6597 &ssl_data_);
6598
6599 request->Start();
Wez2a31b222018-06-07 22:07:156600 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486601
6602 EXPECT_LT(0, request->GetTotalSentBytes());
6603 EXPECT_LT(0, request->GetTotalReceivedBytes());
6604 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6605 request->GetTotalSentBytes());
6606 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6607 request->GetTotalReceivedBytes());
6608 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6609 request->raw_header_size());
Wez0e717112018-06-18 23:09:226610
6611 // Pump the message loop to allow all data to be consumed.
6612 base::RunLoop().RunUntilIdle();
6613
allada71b2efb2016-09-09 04:57:486614 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6615 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6616}
6617
6618TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416619 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486620 HostPortPair::FromString("mail.example.org:443"));
6621
6622 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526623 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236624 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436625 mock_quic_data.AddWrite(
6626 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6627 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136628 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486629 headers["user-agent"] = "";
6630 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436631 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336632 SYNCHRONOUS,
6633 ConstructClientRequestHeadersPacket(
6634 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6635 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486636
Ryan Hamilton8d9ee76e2018-05-29 23:52:526637 quic::QuicStreamOffset server_header_offset = 0;
6638 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486639
Zhongyi Shi32f2fd02018-04-16 18:23:436640 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336641 ASYNC, ConstructServerPushPromisePacket(
6642 1, GetNthClientInitiatedBidirectionalStreamId(0),
6643 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6644 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6645 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486646
Yixin Wangb470bc882018-02-15 18:43:576647 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566648 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336649 mock_quic_data.AddWrite(SYNCHRONOUS,
6650 ConstructClientPriorityPacket(
6651 client_packet_number++, false,
6652 GetNthServerInitiatedUnidirectionalStreamId(0),
6653 GetNthClientInitiatedBidirectionalStreamId(0),
6654 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576655 }
6656
allada71b2efb2016-09-09 04:57:486657 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436658 mock_quic_data.AddRead(
6659 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336660 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436661 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486662 expected_raw_header_response_size =
6663 server_header_offset - expected_raw_header_response_size;
6664
Yixin Wangb470bc882018-02-15 18:43:576665 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436666 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486667
ckrasicbf2f59c2017-05-04 23:54:366668 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436669 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336670 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6671 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436672 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436673 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336674 ASYNC, ConstructServerDataPacket(
6675 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416676 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486677
Yixin Wangb470bc882018-02-15 18:43:576678 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436679 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436680 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366681 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336682 ASYNC, ConstructServerDataPacket(
6683 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416684 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486685
Zhongyi Shi32f2fd02018-04-16 18:23:436686 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486687
6688 CreateSession();
6689
6690 TestDelegate delegate;
6691 QuicURLRequestContext quic_url_request_context(std::move(session_),
6692 &socket_factory_);
6693
6694 mock_quic_data.AddSocketDataToFactory(
6695 &quic_url_request_context.socket_factory());
6696 TestNetworkDelegate network_delegate;
6697 quic_url_request_context.set_network_delegate(&network_delegate);
6698
6699 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296700 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6701 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486702 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6703 &ssl_data_);
6704
6705 request->Start();
Wez2a31b222018-06-07 22:07:156706 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486707
6708 EXPECT_LT(0, request->GetTotalSentBytes());
6709 EXPECT_LT(0, request->GetTotalReceivedBytes());
6710 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6711 request->GetTotalSentBytes());
6712 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6713 request->GetTotalReceivedBytes());
6714 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6715 request->raw_header_size());
Wez0e717112018-06-18 23:09:226716
6717 // Pump the message loop to allow all data to be consumed.
6718 base::RunLoop().RunUntilIdle();
6719
allada71b2efb2016-09-09 04:57:486720 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6721 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6722}
6723
Yixin Wang10f477ed2017-11-21 04:20:206724TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6725 session_params_.quic_host_whitelist.insert("mail.example.org");
6726
6727 MockRead http_reads[] = {
6728 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6729 MockRead("hello world"),
6730 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6731 MockRead(ASYNC, OK)};
6732
Ryan Sleevib8d7ea02018-05-07 20:01:016733 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206734 socket_factory_.AddSocketDataProvider(&http_data);
6735 AddCertificate(&ssl_data_);
6736 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6737
6738 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526739 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206740 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436741 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6742 mock_quic_data.AddWrite(
6743 SYNCHRONOUS,
6744 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336745 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436746 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436747 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336748 ASYNC, ConstructServerResponseHeadersPacket(
6749 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6750 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436751 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336752 mock_quic_data.AddRead(
6753 ASYNC, ConstructServerDataPacket(
6754 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416755 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436756 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206757 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6758 mock_quic_data.AddRead(ASYNC, 0); // EOF
6759
6760 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6761
6762 AddHangingNonAlternateProtocolSocketData();
6763 CreateSession();
6764
6765 SendRequestAndExpectHttpResponse("hello world");
6766 SendRequestAndExpectQuicResponse("hello!");
6767}
6768
6769TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6770 session_params_.quic_host_whitelist.insert("mail.example.com");
6771
6772 MockRead http_reads[] = {
6773 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6774 MockRead("hello world"),
6775 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6776 MockRead(ASYNC, OK)};
6777
Ryan Sleevib8d7ea02018-05-07 20:01:016778 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206779 socket_factory_.AddSocketDataProvider(&http_data);
6780 AddCertificate(&ssl_data_);
6781 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6782 socket_factory_.AddSocketDataProvider(&http_data);
6783 AddCertificate(&ssl_data_);
6784 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6785
6786 AddHangingNonAlternateProtocolSocketData();
6787 CreateSession();
6788
6789 SendRequestAndExpectHttpResponse("hello world");
6790 SendRequestAndExpectHttpResponse("hello world");
6791}
6792
bnc359ed2a2016-04-29 20:43:456793class QuicNetworkTransactionWithDestinationTest
6794 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016795 public ::testing::WithParamInterface<PoolingTestParams>,
6796 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456797 protected:
6798 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556799 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056800 client_headers_include_h2_stream_dependency_(
6801 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:566802 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456803 destination_type_(GetParam().destination_type),
6804 cert_transparency_verifier_(new MultiLogCTVerifier()),
6805 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596806 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116807 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456808 random_generator_(0),
6809 ssl_data_(ASYNC, OK) {}
6810
6811 void SetUp() override {
6812 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556813 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456814
mmenke6ddfbea2017-05-31 21:48:416815 HttpNetworkSession::Params session_params;
6816 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346817 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446818 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056819 session_params.quic_headers_include_h2_stream_dependency =
6820 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416821
6822 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456823
Ryan Hamilton8d9ee76e2018-05-29 23:52:526824 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416825 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456826
6827 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276828 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416829 session_context.quic_crypto_client_stream_factory =
6830 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456831
mmenke6ddfbea2017-05-31 21:48:416832 session_context.quic_random = &random_generator_;
6833 session_context.client_socket_factory = &socket_factory_;
6834 session_context.host_resolver = &host_resolver_;
6835 session_context.cert_verifier = &cert_verifier_;
6836 session_context.transport_security_state = &transport_security_state_;
6837 session_context.cert_transparency_verifier =
6838 cert_transparency_verifier_.get();
6839 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6840 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456841 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416842 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596843 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416844 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6845 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456846
mmenke6ddfbea2017-05-31 21:48:416847 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456848 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456849 }
6850
6851 void TearDown() override {
6852 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6853 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556854 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456855 PlatformTest::TearDown();
6856 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556857 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406858 session_.reset();
bnc359ed2a2016-04-29 20:43:456859 }
6860
zhongyie537a002017-06-27 16:48:216861 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456862 HostPortPair destination;
6863 switch (destination_type_) {
6864 case SAME_AS_FIRST:
6865 destination = HostPortPair(origin1_, 443);
6866 break;
6867 case SAME_AS_SECOND:
6868 destination = HostPortPair(origin2_, 443);
6869 break;
6870 case DIFFERENT:
6871 destination = HostPortPair(kDifferentHostname, 443);
6872 break;
6873 }
bnc3472afd2016-11-17 15:27:216874 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456875 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216876 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456877 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446878 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456879 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526880 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236881 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526882 quic::QuicStreamId stream_id,
6883 bool should_include_version,
6884 quic::QuicStreamOffset* offset,
6885 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486886 return ConstructClientRequestHeadersPacket(
6887 packet_number, stream_id, should_include_version, 0, offset, maker);
6888 }
bnc359ed2a2016-04-29 20:43:456889
Ryan Hamilton8d9ee76e2018-05-29 23:52:526890 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236891 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526892 quic::QuicStreamId stream_id,
6893 bool should_include_version,
6894 quic::QuicStreamId parent_stream_id,
6895 quic::QuicStreamOffset* offset,
6896 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136897 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456898 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136899 spdy::SpdyHeaderBlock headers(
6900 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456901 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6902 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486903 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456904 }
6905
Ryan Hamilton8d9ee76e2018-05-29 23:52:526906 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236907 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526908 quic::QuicStreamId stream_id,
6909 bool should_include_version,
6910 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586911 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456912 packet_number, stream_id, should_include_version, nullptr, maker);
6913 }
6914
Ryan Hamilton8d9ee76e2018-05-29 23:52:526915 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236916 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526917 quic::QuicStreamId stream_id,
6918 quic::QuicStreamOffset* offset,
6919 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136920 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456921 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266922 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456923 }
6924
Ryan Hamilton8d9ee76e2018-05-29 23:52:526925 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236926 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526927 quic::QuicStreamId stream_id,
6928 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586929 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6930 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456931 }
6932
Ryan Hamilton8d9ee76e2018-05-29 23:52:526933 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236934 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526935 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456936 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436937 std::string header = "";
Nick Harper23290b82019-05-02 00:02:566938 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416939 quic::HttpEncoder encoder;
6940 std::unique_ptr<char[]> buffer;
6941 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436942 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416943 }
bnc359ed2a2016-04-29 20:43:456944 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416945 header + "hello");
bnc359ed2a2016-04-29 20:43:456946 }
6947
Ryan Hamilton8d9ee76e2018-05-29 23:52:526948 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236949 uint64_t packet_number,
6950 uint64_t largest_received,
6951 uint64_t smallest_received,
6952 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456953 QuicTestPacketMaker* maker) {
6954 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496955 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456956 }
6957
Ryan Hamilton8d9ee76e2018-05-29 23:52:526958 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236959 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526960 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376961 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366962 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376963 }
6964
bnc359ed2a2016-04-29 20:43:456965 void AddRefusedSocketData() {
6966 std::unique_ptr<StaticSocketDataProvider> refused_data(
6967 new StaticSocketDataProvider());
6968 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6969 refused_data->set_connect_data(refused_connect);
6970 socket_factory_.AddSocketDataProvider(refused_data.get());
6971 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6972 }
6973
6974 void AddHangingSocketData() {
6975 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6976 new StaticSocketDataProvider());
6977 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6978 hanging_data->set_connect_data(hanging_connect);
6979 socket_factory_.AddSocketDataProvider(hanging_data.get());
6980 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6981 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6982 }
6983
6984 bool AllDataConsumed() {
6985 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6986 if (!socket_data_ptr->AllReadDataConsumed() ||
6987 !socket_data_ptr->AllWriteDataConsumed()) {
6988 return false;
6989 }
6990 }
6991 return true;
6992 }
6993
6994 void SendRequestAndExpectQuicResponse(const std::string& host) {
6995 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6996 HttpRequestInfo request;
6997 std::string url("https://");
6998 url.append(host);
6999 request.url = GURL(url);
7000 request.load_flags = 0;
7001 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107002 request.traffic_annotation =
7003 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457004 TestCompletionCallback callback;
7005 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017006 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457007
7008 std::string response_data;
robpercival214763f2016-07-01 23:27:017009 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457010 EXPECT_EQ("hello", response_data);
7011
7012 const HttpResponseInfo* response = trans.GetResponseInfo();
7013 ASSERT_TRUE(response != nullptr);
7014 ASSERT_TRUE(response->headers.get() != nullptr);
7015 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7016 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527017 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:567018 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
7019 version_.transport_version),
bnc359ed2a2016-04-29 20:43:457020 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377021 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457022 }
7023
Fan Yang32c5a112018-12-10 20:06:337024 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567025 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7026 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367027 }
7028
Ryan Hamilton8d9ee76e2018-05-29 23:52:527029 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:567030 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057031 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567032 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457033 DestinationType destination_type_;
7034 std::string origin1_;
7035 std::string origin2_;
7036 std::unique_ptr<HttpNetworkSession> session_;
7037 MockClientSocketFactory socket_factory_;
7038 MockHostResolver host_resolver_;
7039 MockCertVerifier cert_verifier_;
7040 TransportSecurityState transport_security_state_;
7041 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237042 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457043 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077044 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597045 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457046 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527047 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457048 HttpServerPropertiesImpl http_server_properties_;
7049 BoundTestNetLog net_log_;
7050 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7051 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7052 static_socket_data_provider_vector_;
7053 SSLSocketDataProvider ssl_data_;
7054};
7055
Victor Costane635086f2019-01-27 05:20:307056INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7057 QuicNetworkTransactionWithDestinationTest,
7058 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457059
7060// A single QUIC request fails because the certificate does not match the origin
7061// hostname, regardless of whether it matches the alternative service hostname.
7062TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7063 if (destination_type_ == DIFFERENT)
7064 return;
7065
7066 GURL url("https://mail.example.com/");
7067 origin1_ = url.host();
7068
7069 // Not used for requests, but this provides a test case where the certificate
7070 // is valid for the hostname of the alternative service.
7071 origin2_ = "mail.example.org";
7072
zhongyie537a002017-06-27 16:48:217073 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457074
7075 scoped_refptr<X509Certificate> cert(
7076 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247077 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7078 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457079
7080 ProofVerifyDetailsChromium verify_details;
7081 verify_details.cert_verify_result.verified_cert = cert;
7082 verify_details.cert_verify_result.is_issued_by_known_root = true;
7083 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7084
7085 MockQuicData mock_quic_data;
7086 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7087 mock_quic_data.AddRead(ASYNC, 0);
7088
7089 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7090
7091 AddRefusedSocketData();
7092
7093 HttpRequestInfo request;
7094 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107095 request.traffic_annotation =
7096 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457097
7098 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7099 TestCompletionCallback callback;
7100 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017101 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457102
7103 EXPECT_TRUE(AllDataConsumed());
7104}
7105
7106// First request opens QUIC session to alternative service. Second request
7107// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527108// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457109TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7110 origin1_ = "mail.example.org";
7111 origin2_ = "news.example.org";
7112
zhongyie537a002017-06-27 16:48:217113 SetQuicAlternativeService(origin1_);
7114 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457115
7116 scoped_refptr<X509Certificate> cert(
7117 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247118 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7119 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7120 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457121
7122 ProofVerifyDetailsChromium verify_details;
7123 verify_details.cert_verify_result.verified_cert = cert;
7124 verify_details.cert_verify_result.is_issued_by_known_root = true;
7125 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7126
Yixin Wang079ad542018-01-11 04:06:057127 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177128 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7129 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057130 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177131 QuicTestPacketMaker server_maker(
7132 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7133 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457134
Ryan Hamilton8d9ee76e2018-05-29 23:52:527135 quic::QuicStreamOffset request_header_offset(0);
7136 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457137
7138 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057139 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437140 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057141 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337142 mock_quic_data.AddWrite(
7143 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7144 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7145 &request_header_offset, &client_maker));
7146 mock_quic_data.AddRead(ASYNC,
7147 ConstructServerResponseHeadersPacket(
7148 1, GetNthClientInitiatedBidirectionalStreamId(0),
7149 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437150 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337151 ASYNC,
7152 ConstructServerDataPacket(
7153 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437154 mock_quic_data.AddWrite(SYNCHRONOUS,
7155 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457156
Yixin Wang079ad542018-01-11 04:06:057157 client_maker.set_hostname(origin2_);
7158 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457159
Zhongyi Shi32f2fd02018-04-16 18:23:437160 mock_quic_data.AddWrite(
7161 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337162 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7163 GetNthClientInitiatedBidirectionalStreamId(0),
7164 &request_header_offset, &client_maker));
7165 mock_quic_data.AddRead(ASYNC,
7166 ConstructServerResponseHeadersPacket(
7167 3, GetNthClientInitiatedBidirectionalStreamId(1),
7168 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437169 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337170 ASYNC,
7171 ConstructServerDataPacket(
7172 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437173 mock_quic_data.AddWrite(SYNCHRONOUS,
7174 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457175 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7176 mock_quic_data.AddRead(ASYNC, 0); // EOF
7177
7178 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7179
7180 AddHangingSocketData();
7181 AddHangingSocketData();
7182
Fan Yangc9e00dc2018-10-09 14:17:567183 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7184 QuicStreamFactoryPeer::SetAlarmFactory(
7185 session_->quic_stream_factory(),
7186 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7187 &clock_));
7188
bnc359ed2a2016-04-29 20:43:457189 SendRequestAndExpectQuicResponse(origin1_);
7190 SendRequestAndExpectQuicResponse(origin2_);
7191
7192 EXPECT_TRUE(AllDataConsumed());
7193}
7194
7195// First request opens QUIC session to alternative service. Second request does
7196// not pool to it, even though destination matches, because certificate is not
7197// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527198// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457199TEST_P(QuicNetworkTransactionWithDestinationTest,
7200 DoNotPoolIfCertificateInvalid) {
7201 origin1_ = "news.example.org";
7202 origin2_ = "mail.example.com";
7203
zhongyie537a002017-06-27 16:48:217204 SetQuicAlternativeService(origin1_);
7205 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457206
7207 scoped_refptr<X509Certificate> cert1(
7208 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247209 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7210 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7211 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457212
7213 scoped_refptr<X509Certificate> cert2(
7214 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247215 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7216 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457217
7218 ProofVerifyDetailsChromium verify_details1;
7219 verify_details1.cert_verify_result.verified_cert = cert1;
7220 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7221 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7222
7223 ProofVerifyDetailsChromium verify_details2;
7224 verify_details2.cert_verify_result.verified_cert = cert2;
7225 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7226 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7227
Yixin Wang079ad542018-01-11 04:06:057228 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177229 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7230 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057231 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177232 QuicTestPacketMaker server_maker1(
7233 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7234 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457235
7236 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527237 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457238 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437239 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7240 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337241 mock_quic_data1.AddWrite(
7242 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7243 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7244 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437245 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337246 ASYNC,
7247 ConstructServerResponseHeadersPacket(
7248 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437249 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337250 ASYNC,
7251 ConstructServerDataPacket(
7252 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437253 mock_quic_data1.AddWrite(
7254 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457255 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7256 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7257
7258 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7259
Yixin Wang079ad542018-01-11 04:06:057260 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177261 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7262 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057263 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177264 QuicTestPacketMaker server_maker2(
7265 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7266 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457267
7268 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527269 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457270 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437271 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7272 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337273 mock_quic_data2.AddWrite(
7274 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7275 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7276 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437277 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337278 ASYNC,
7279 ConstructServerResponseHeadersPacket(
7280 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437281 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337282 ASYNC,
7283 ConstructServerDataPacket(
7284 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437285 mock_quic_data2.AddWrite(
7286 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457287 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7288 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7289
7290 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7291
bnc359ed2a2016-04-29 20:43:457292 SendRequestAndExpectQuicResponse(origin1_);
7293 SendRequestAndExpectQuicResponse(origin2_);
7294
7295 EXPECT_TRUE(AllDataConsumed());
7296}
7297
ckrasicdee37572017-04-06 22:42:277298// crbug.com/705109 - this confirms that matching request with a body
7299// triggers a crash (pre-fix).
7300TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417301 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277302 HostPortPair::FromString("mail.example.org:443"));
7303
7304 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527305 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237306 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437307 mock_quic_data.AddWrite(
7308 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7309 &header_stream_offset));
7310 mock_quic_data.AddWrite(
7311 SYNCHRONOUS,
7312 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337313 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7314 true, true, GetRequestHeaders("GET", "https", "/"),
7315 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527316 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437317 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337318 ASYNC, ConstructServerPushPromisePacket(
7319 1, GetNthClientInitiatedBidirectionalStreamId(0),
7320 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7321 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7322 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577323 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:567324 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337325 mock_quic_data.AddWrite(SYNCHRONOUS,
7326 ConstructClientPriorityPacket(
7327 client_packet_number++, false,
7328 GetNthServerInitiatedUnidirectionalStreamId(0),
7329 GetNthClientInitiatedBidirectionalStreamId(0),
7330 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577331 }
Zhongyi Shi32f2fd02018-04-16 18:23:437332 mock_quic_data.AddRead(
7333 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337334 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437335 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577336 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437337 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7338 mock_quic_data.AddRead(
7339 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337340 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7341 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437342 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437343 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337344 ASYNC, ConstructServerDataPacket(
7345 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417346 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577347 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437348 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417349
Victor Vasiliev076657c2019-03-12 02:46:437350 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437351 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337352 ASYNC, ConstructServerDataPacket(
7353 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417354 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277355
7356 // Because the matching request has a body, we will see the push
7357 // stream get cancelled, and the matching request go out on the
7358 // wire.
Fan Yang32c5a112018-12-10 20:06:337359 mock_quic_data.AddWrite(SYNCHRONOUS,
7360 ConstructClientAckAndRstPacket(
7361 client_packet_number++,
7362 GetNthServerInitiatedUnidirectionalStreamId(0),
7363 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277364 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437365 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567366 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417367 mock_quic_data.AddWrite(
7368 SYNCHRONOUS,
7369 ConstructClientRequestHeadersAndDataFramesPacket(
7370 client_packet_number++,
7371 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7372 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7373 GetNthServerInitiatedUnidirectionalStreamId(0),
7374 &header_stream_offset, nullptr, {kBody}));
7375 } else {
7376 mock_quic_data.AddWrite(
7377 SYNCHRONOUS,
7378 ConstructClientRequestHeadersAndDataFramesPacket(
7379 client_packet_number++,
7380 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7381 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7382 GetNthServerInitiatedUnidirectionalStreamId(0),
7383 &header_stream_offset, nullptr, {header3, kBody}));
7384 }
ckrasicdee37572017-04-06 22:42:277385
7386 // We see the same response as for the earlier pushed and cancelled
7387 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437388 mock_quic_data.AddRead(
7389 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337390 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437391 GetResponseHeaders("200 OK"), &server_header_offset));
7392 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337393 ASYNC, ConstructServerDataPacket(
7394 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417395 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277396
Yixin Wangb470bc882018-02-15 18:43:577397 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437398 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277399 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7400 mock_quic_data.AddRead(ASYNC, 0); // EOF
7401 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7402
7403 // The non-alternate protocol job needs to hang in order to guarantee that
7404 // the alternate-protocol job will "win".
7405 AddHangingNonAlternateProtocolSocketData();
7406
7407 CreateSession();
7408
7409 // PUSH_PROMISE handling in the http layer gets exercised here.
7410 SendRequestAndExpectQuicResponse("hello!");
7411
7412 request_.url = GURL("https://mail.example.org/pushed.jpg");
7413 ChunkedUploadDataStream upload_data(0);
7414 upload_data.AppendData("1", 1, true);
7415 request_.upload_data_stream = &upload_data;
7416 SendRequestAndExpectQuicResponse("and hello!");
7417}
7418
Bence Béky7538a952018-02-01 16:59:527419// Regression test for https://crbug.com/797825: If pushed headers describe a
7420// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7421// not be called (otherwise a DCHECK fails).
7422TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137423 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527424 pushed_request_headers[":authority"] = "";
7425 pushed_request_headers[":method"] = "GET";
7426 pushed_request_headers[":path"] = "/";
7427 pushed_request_headers[":scheme"] = "nosuchscheme";
7428
7429 session_params_.origins_to_force_quic_on.insert(
7430 HostPortPair::FromString("mail.example.org:443"));
7431
7432 MockQuicData mock_quic_data;
7433
Ryan Hamilton8d9ee76e2018-05-29 23:52:527434 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527435 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437436 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7437 mock_quic_data.AddWrite(
7438 SYNCHRONOUS,
7439 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337440 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437441 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527442
Ryan Hamilton8d9ee76e2018-05-29 23:52:527443 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337444 mock_quic_data.AddRead(
7445 ASYNC, ConstructServerPushPromisePacket(
7446 1, GetNthClientInitiatedBidirectionalStreamId(0),
7447 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7448 std::move(pushed_request_headers), &server_header_offset,
7449 &server_maker_));
7450 mock_quic_data.AddWrite(SYNCHRONOUS,
7451 ConstructClientRstPacket(
7452 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7453 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527454
Zhongyi Shi32f2fd02018-04-16 18:23:437455 mock_quic_data.AddRead(
7456 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337457 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437458 GetResponseHeaders("200 OK"), &server_header_offset));
7459 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527460
Zhongyi Shi32f2fd02018-04-16 18:23:437461 mock_quic_data.AddRead(
7462 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337463 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7464 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437465 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437466 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337467 ASYNC, ConstructServerDataPacket(
7468 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417469 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437470 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527471
7472 mock_quic_data.AddRead(ASYNC, 0);
7473 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7474
7475 // The non-alternate protocol job needs to hang in order to guarantee that
7476 // the alternate-protocol job will "win".
7477 AddHangingNonAlternateProtocolSocketData();
7478
7479 CreateSession();
7480
7481 // PUSH_PROMISE handling in the http layer gets exercised here.
7482 SendRequestAndExpectQuicResponse("hello!");
7483
7484 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7485 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7486}
7487
Yixin Wang46a273ec302018-01-23 17:59:567488// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147489TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567490 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147491 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567492 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497493 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567494
7495 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527496 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567497 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357498 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337499 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357500 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7501 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047502 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7503 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357504 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337505 mock_quic_data.AddRead(
7506 ASYNC, ConstructServerResponseHeadersPacket(
7507 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7508 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567509
7510 const char get_request[] =
7511 "GET / HTTP/1.1\r\n"
7512 "Host: mail.example.org\r\n"
7513 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437514 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567515 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417516 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357517 SYNCHRONOUS,
7518 ConstructClientAckAndDataPacket(
7519 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7520 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417521 } else {
7522 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417523 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357524 ConstructClientAckAndMultipleDataFramesPacket(
7525 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437526 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417527 }
7528
Yixin Wang46a273ec302018-01-23 17:59:567529 const char get_response[] =
7530 "HTTP/1.1 200 OK\r\n"
7531 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437532 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437533 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337534 ASYNC, ConstructServerDataPacket(
7535 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437536 0, header2 + std::string(get_response)));
7537 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337538 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417539 SYNCHRONOUS, ConstructServerDataPacket(
7540 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7541 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437542 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357543 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567544 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7545
7546 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417547 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357548 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7549 quic::QUIC_STREAM_CANCELLED,
7550 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567551
7552 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7553
7554 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7555
7556 CreateSession();
7557
7558 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097559 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7561 HeadersHandler headers_handler;
7562 trans.SetBeforeHeadersSentCallback(
7563 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7564 base::Unretained(&headers_handler)));
7565 RunTransaction(&trans);
7566 CheckWasHttpResponse(&trans);
7567 CheckResponsePort(&trans, 70);
7568 CheckResponseData(&trans, "0123456789");
7569 EXPECT_TRUE(headers_handler.was_proxied());
7570 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7571
7572 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7573 // proxy socket to disconnect.
7574 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7575
7576 base::RunLoop().RunUntilIdle();
7577 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7578 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7579}
7580
7581// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147582TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567583 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147584 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567585 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497586 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567587
7588 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527589 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567590 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357591 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337592 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357593 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7594 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047595 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7596 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357597 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337598 mock_quic_data.AddRead(
7599 ASYNC, ConstructServerResponseHeadersPacket(
7600 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7601 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567602
7603 SpdyTestUtil spdy_util;
7604
Ryan Hamilton0239aac2018-05-19 00:03:137605 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567606 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437607 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567608 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417609 mock_quic_data.AddWrite(
7610 SYNCHRONOUS,
7611 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357612 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7613 false, 0,
Renjief49758b2019-01-11 23:32:417614 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7615 } else {
7616 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417617 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357618 ConstructClientAckAndMultipleDataFramesPacket(
7619 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7620 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437621 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417622 }
Ryan Hamilton0239aac2018-05-19 00:03:137623 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567624 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437625 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437626 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337627 ASYNC,
7628 ConstructServerDataPacket(
7629 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437630 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567631
Ryan Hamilton0239aac2018-05-19 00:03:137632 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197633 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437634 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437635 mock_quic_data.AddRead(
7636 SYNCHRONOUS,
7637 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337638 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417639 resp_frame.size() + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437640 header3 + std::string(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357641 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567642 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7643
7644 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437645 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357646 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7647 quic::QUIC_STREAM_CANCELLED,
7648 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567649
7650 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7651
7652 SSLSocketDataProvider ssl_data(ASYNC, OK);
7653 ssl_data.next_proto = kProtoHTTP2;
7654 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7655
7656 CreateSession();
7657
7658 request_.url = GURL("https://mail.example.org/");
7659 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7660 HeadersHandler headers_handler;
7661 trans.SetBeforeHeadersSentCallback(
7662 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7663 base::Unretained(&headers_handler)));
7664 RunTransaction(&trans);
7665 CheckWasSpdyResponse(&trans);
7666 CheckResponsePort(&trans, 70);
7667 CheckResponseData(&trans, "0123456789");
7668 EXPECT_TRUE(headers_handler.was_proxied());
7669 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7670
Wez0e717112018-06-18 23:09:227671 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7672 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567673 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7674
7675 base::RunLoop().RunUntilIdle();
7676 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7677 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7678}
7679
7680// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7681// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147682TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567683 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147684 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567685 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497686 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567687
7688 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527689 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417690 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567691 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417692 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7693 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337694 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417695 SYNCHRONOUS,
7696 ConstructClientRequestHeadersPacket(
7697 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047698 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7699 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjief49758b2019-01-11 23:32:417700 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337701 mock_quic_data.AddRead(
7702 ASYNC, ConstructServerResponseHeadersPacket(
7703 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7704 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567705
Ryan Hamilton8d9ee76e2018-05-29 23:52:527706 quic::QuicStreamOffset client_data_offset = 0;
7707 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567708 const char get_request_1[] =
7709 "GET / HTTP/1.1\r\n"
7710 "Host: mail.example.org\r\n"
7711 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437712 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567713 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417714 mock_quic_data.AddWrite(
7715 SYNCHRONOUS,
7716 ConstructClientAckAndDataPacket(
7717 write_packet_index++, false,
7718 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7719 client_data_offset, quic::QuicStringPiece(get_request_1)));
7720 } else {
7721 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417722 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357723 ConstructClientAckAndMultipleDataFramesPacket(
7724 write_packet_index++, false,
7725 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
Victor Vasiliev076657c2019-03-12 02:46:437726 client_data_offset, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417727 }
7728
7729 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567730
7731 const char get_response_1[] =
7732 "HTTP/1.1 200 OK\r\n"
7733 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437734 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437735 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437736 ASYNC, ConstructServerDataPacket(
7737 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7738 server_data_offset, header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417739 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567740
Victor Vasiliev076657c2019-03-12 02:46:437741 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337742 mock_quic_data.AddRead(
7743 SYNCHRONOUS,
7744 ConstructServerDataPacket(
7745 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437746 server_data_offset, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417747 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567748
Renjief49758b2019-01-11 23:32:417749 mock_quic_data.AddWrite(
7750 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567751
7752 const char get_request_2[] =
7753 "GET /2 HTTP/1.1\r\n"
7754 "Host: mail.example.org\r\n"
7755 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437756 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:567757 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417758 mock_quic_data.AddWrite(
7759 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357760 ConstructClientMultipleDataFramesPacket(
7761 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7762 false, false, client_data_offset,
Victor Vasiliev076657c2019-03-12 02:46:437763 {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357764 client_data_offset += header4.length() + strlen(get_request_2);
7765 } else {
7766 mock_quic_data.AddWrite(
7767 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417768 ConstructClientDataPacket(write_packet_index++,
7769 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357770 false, false, client_data_offset,
7771 quic::QuicStringPiece(get_request_2)));
7772 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417773 }
Yixin Wang46a273ec302018-01-23 17:59:567774
7775 const char get_response_2[] =
7776 "HTTP/1.1 200 OK\r\n"
7777 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437778 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437779 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437780 ASYNC, ConstructServerDataPacket(
7781 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7782 server_data_offset, header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417783 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567784
Victor Vasiliev076657c2019-03-12 02:46:437785 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527786 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337787 SYNCHRONOUS,
7788 ConstructServerDataPacket(
7789 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437790 server_data_offset, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417791 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567792
Renjief49758b2019-01-11 23:32:417793 mock_quic_data.AddWrite(
7794 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567795 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7796
Renjief49758b2019-01-11 23:32:417797 mock_quic_data.AddWrite(
7798 SYNCHRONOUS,
7799 ConstructClientRstPacket(
7800 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7801 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567802
7803 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7804
7805 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7806
7807 CreateSession();
7808
7809 request_.url = GURL("https://mail.example.org/");
7810 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7811 HeadersHandler headers_handler_1;
7812 trans_1.SetBeforeHeadersSentCallback(
7813 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7814 base::Unretained(&headers_handler_1)));
7815 RunTransaction(&trans_1);
7816 CheckWasHttpResponse(&trans_1);
7817 CheckResponsePort(&trans_1, 70);
7818 CheckResponseData(&trans_1, "0123456789");
7819 EXPECT_TRUE(headers_handler_1.was_proxied());
7820 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7821
7822 request_.url = GURL("https://mail.example.org/2");
7823 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7824 HeadersHandler headers_handler_2;
7825 trans_2.SetBeforeHeadersSentCallback(
7826 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7827 base::Unretained(&headers_handler_2)));
7828 RunTransaction(&trans_2);
7829 CheckWasHttpResponse(&trans_2);
7830 CheckResponsePort(&trans_2, 70);
7831 CheckResponseData(&trans_2, "0123456");
7832 EXPECT_TRUE(headers_handler_2.was_proxied());
7833 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7834
7835 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7836 // proxy socket to disconnect.
7837 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7838
7839 base::RunLoop().RunUntilIdle();
7840 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7841 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7842}
7843
7844// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7845// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7846// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147847TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567848 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147849 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567850 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497851 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567852
7853 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527854 quic::QuicStreamOffset client_header_stream_offset = 0;
7855 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357856 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7857 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567858
7859 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337860 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357861 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7862 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047863 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7864 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357865 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437866 mock_quic_data.AddRead(
7867 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337868 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437869 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567870
7871 // GET request, response, and data over QUIC tunnel for first request
7872 const char get_request[] =
7873 "GET / HTTP/1.1\r\n"
7874 "Host: mail.example.org\r\n"
7875 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437876 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567877 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417878 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357879 SYNCHRONOUS,
7880 ConstructClientAckAndDataPacket(
7881 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7882 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417883 } else {
7884 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417885 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357886 ConstructClientAckAndMultipleDataFramesPacket(
7887 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437888 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417889 }
7890
Yixin Wang46a273ec302018-01-23 17:59:567891 const char get_response[] =
7892 "HTTP/1.1 200 OK\r\n"
7893 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437894 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567895 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337896 ASYNC, ConstructServerDataPacket(
7897 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437898 0, header2 + std::string(get_response)));
7899 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337900 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417901 SYNCHRONOUS, ConstructServerDataPacket(
7902 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7903 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437904 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357905 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567906
7907 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437908 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047909 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7910 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
7911 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7912 ConnectRequestHeaders("different.example.org:443"),
7913 GetNthClientInitiatedBidirectionalStreamId(0),
7914 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437915 mock_quic_data.AddRead(
7916 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337917 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437918 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567919
7920 // GET request, response, and data over QUIC tunnel for second request
7921 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137922 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567923 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437924 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567925 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417926 mock_quic_data.AddWrite(
7927 SYNCHRONOUS,
7928 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357929 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7930 false, 0,
Renjief49758b2019-01-11 23:32:417931 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7932 } else {
7933 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417934 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357935 ConstructClientAckAndMultipleDataFramesPacket(
7936 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7937 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437938 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417939 }
Yixin Wang46a273ec302018-01-23 17:59:567940
Ryan Hamilton0239aac2018-05-19 00:03:137941 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567942 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437943 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437944 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337945 ASYNC,
7946 ConstructServerDataPacket(
7947 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437948 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567949
Ryan Hamilton0239aac2018-05-19 00:03:137950 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197951 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437952 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437953 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437954 ASYNC, ConstructServerDataPacket(
7955 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7956 resp_frame.size() + header5.length(),
7957 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567958
Renjied172e812019-01-16 05:12:357959 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567960 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7961
7962 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417963 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357964 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7965 quic::QUIC_STREAM_CANCELLED,
7966 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567967 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437968 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357969 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7970 quic::QUIC_STREAM_CANCELLED,
7971 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567972
7973 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7974
7975 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7976
7977 SSLSocketDataProvider ssl_data(ASYNC, OK);
7978 ssl_data.next_proto = kProtoHTTP2;
7979 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7980
7981 CreateSession();
7982
7983 request_.url = GURL("https://mail.example.org/");
7984 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7985 HeadersHandler headers_handler_1;
7986 trans_1.SetBeforeHeadersSentCallback(
7987 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7988 base::Unretained(&headers_handler_1)));
7989 RunTransaction(&trans_1);
7990 CheckWasHttpResponse(&trans_1);
7991 CheckResponsePort(&trans_1, 70);
7992 CheckResponseData(&trans_1, "0123456789");
7993 EXPECT_TRUE(headers_handler_1.was_proxied());
7994 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7995
7996 request_.url = GURL("https://different.example.org/");
7997 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7998 HeadersHandler headers_handler_2;
7999 trans_2.SetBeforeHeadersSentCallback(
8000 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8001 base::Unretained(&headers_handler_2)));
8002 RunTransaction(&trans_2);
8003 CheckWasSpdyResponse(&trans_2);
8004 CheckResponsePort(&trans_2, 70);
8005 CheckResponseData(&trans_2, "0123456");
8006 EXPECT_TRUE(headers_handler_2.was_proxied());
8007 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8008
8009 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8010 // proxy socket to disconnect.
8011 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8012
8013 base::RunLoop().RunUntilIdle();
8014 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8015 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8016}
8017
8018// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148019TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568020 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148021 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568022 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498023 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568024
8025 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528026 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568027 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438028 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528029 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338030 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8031 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048032 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8033 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338034 &header_stream_offset));
8035 mock_quic_data.AddRead(
8036 ASYNC, ConstructServerResponseHeadersPacket(
8037 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8038 GetResponseHeaders("500")));
8039 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8040 mock_quic_data.AddWrite(SYNCHRONOUS,
8041 ConstructClientAckAndRstPacket(
8042 3, GetNthClientInitiatedBidirectionalStreamId(0),
8043 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568044
8045 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8046
8047 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8048
8049 CreateSession();
8050
8051 request_.url = GURL("https://mail.example.org/");
8052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8053 HeadersHandler headers_handler;
8054 trans.SetBeforeHeadersSentCallback(
8055 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8056 base::Unretained(&headers_handler)));
8057 TestCompletionCallback callback;
8058 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8059 EXPECT_EQ(ERR_IO_PENDING, rv);
8060 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8061 EXPECT_EQ(false, headers_handler.was_proxied());
8062
8063 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8064 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8065}
8066
8067// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148068TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568069 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148070 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568071 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498072 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568073
8074 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528075 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568076 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438077 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338078 mock_quic_data.AddWrite(
8079 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8080 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048081 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8082 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338083 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568084 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8085
8086 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8087
8088 CreateSession();
8089
8090 request_.url = GURL("https://mail.example.org/");
8091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8092 HeadersHandler headers_handler;
8093 trans.SetBeforeHeadersSentCallback(
8094 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8095 base::Unretained(&headers_handler)));
8096 TestCompletionCallback callback;
8097 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8098 EXPECT_EQ(ERR_IO_PENDING, rv);
8099 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8100
8101 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8102 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8103}
8104
8105// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8106// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148107TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568108 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148109 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568110 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498111 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568112
8113 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528114 quic::QuicStreamOffset client_header_stream_offset = 0;
8115 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358116 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8117 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338118 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358119 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8120 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048121 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8122 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:358123 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438124 mock_quic_data.AddRead(
8125 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438127 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358128 mock_quic_data.AddWrite(SYNCHRONOUS,
8129 ConstructClientAckAndRstPacket(
8130 3, GetNthClientInitiatedBidirectionalStreamId(0),
8131 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568132
Zhongyi Shi32f2fd02018-04-16 18:23:438133 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358134 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8135 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Matt Menke6e879bd2019-03-18 17:26:048136 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8137 ConnectRequestHeaders("mail.example.org:443"),
Renjied172e812019-01-16 05:12:358138 GetNthClientInitiatedBidirectionalStreamId(0),
8139 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438140 mock_quic_data.AddRead(
8141 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338142 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438143 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568144
8145 const char get_request[] =
8146 "GET / HTTP/1.1\r\n"
8147 "Host: mail.example.org\r\n"
8148 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438149 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568150 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418151 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358152 SYNCHRONOUS,
8153 ConstructClientAckAndDataPacket(
8154 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8155 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418156 } else {
8157 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418158 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358159 ConstructClientAckAndMultipleDataFramesPacket(
8160 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Victor Vasiliev076657c2019-03-12 02:46:438161 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418162 }
Yixin Wang46a273ec302018-01-23 17:59:568163 const char get_response[] =
8164 "HTTP/1.1 200 OK\r\n"
8165 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438166 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438167 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338168 ASYNC, ConstructServerDataPacket(
8169 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438170 0, header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528171
Victor Vasiliev076657c2019-03-12 02:46:438172 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338173 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418174 SYNCHRONOUS, ConstructServerDataPacket(
8175 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8176 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:438177 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:358178 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568179 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8180
8181 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418182 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358183 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8184 quic::QUIC_STREAM_CANCELLED,
8185 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568186
8187 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8188
8189 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8190 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8191
8192 SSLSocketDataProvider ssl_data(ASYNC, OK);
8193 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8194
8195 CreateSession();
8196
8197 request_.url = GURL("https://mail.example.org/");
8198 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8199 HeadersHandler headers_handler;
8200 trans.SetBeforeHeadersSentCallback(
8201 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8202 base::Unretained(&headers_handler)));
8203 TestCompletionCallback callback;
8204 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8205 EXPECT_EQ(ERR_IO_PENDING, rv);
8206 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8207
8208 rv = trans.RestartIgnoringLastError(callback.callback());
8209 EXPECT_EQ(ERR_IO_PENDING, rv);
8210 EXPECT_EQ(OK, callback.WaitForResult());
8211
8212 CheckWasHttpResponse(&trans);
8213 CheckResponsePort(&trans, 70);
8214 CheckResponseData(&trans, "0123456789");
8215 EXPECT_EQ(true, headers_handler.was_proxied());
8216 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8217
8218 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8219 // proxy socket to disconnect.
8220 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8221
8222 base::RunLoop().RunUntilIdle();
8223 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8224 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8225}
8226
8227// Checks if a request's specified "user-agent" header shows up correctly in the
8228// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148229TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008230 const char kConfiguredUserAgent[] = "Configured User-Agent";
8231 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568232 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148233 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568234 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498235 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568236
8237 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528238 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568239 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438240 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568241
Ryan Hamilton0239aac2018-05-19 00:03:138242 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008243 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338244 mock_quic_data.AddWrite(
8245 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8246 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048247 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8248 std::move(headers), 0, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568249 // Return an error, so the transaction stops here (this test isn't interested
8250 // in the rest).
8251 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8252
8253 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8254
Matt Menked732ea42019-03-08 12:05:008255 StaticHttpUserAgentSettings http_user_agent_settings(
8256 std::string() /* accept_language */, kConfiguredUserAgent);
8257 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568258 CreateSession();
8259
8260 request_.url = GURL("https://mail.example.org/");
8261 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008262 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568263 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8264 HeadersHandler headers_handler;
8265 trans.SetBeforeHeadersSentCallback(
8266 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8267 base::Unretained(&headers_handler)));
8268 TestCompletionCallback callback;
8269 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8270 EXPECT_EQ(ERR_IO_PENDING, rv);
8271 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8272
8273 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8274 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8275}
8276
Yixin Wang00fc44c2018-01-23 21:12:208277// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8278// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148279TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208280 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148281 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208282 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498283 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208284
8285 const RequestPriority request_priority = MEDIUM;
8286
8287 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528288 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208289 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438290 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8291 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048292 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8293 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8294 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8295 ConnectRequestHeaders("mail.example.org:443"), 0,
8296 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208297 // Return an error, so the transaction stops here (this test isn't interested
8298 // in the rest).
8299 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8300
8301 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8302
8303 CreateSession();
8304
8305 request_.url = GURL("https://mail.example.org/");
8306 HttpNetworkTransaction trans(request_priority, session_.get());
8307 TestCompletionCallback callback;
8308 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8309 EXPECT_EQ(ERR_IO_PENDING, rv);
8310 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8311
8312 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8313 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8314}
8315
Matt Menkeedaf3b82019-03-14 21:39:448316// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8317// HTTP/2 stream dependency and weights given the request priority.
8318TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8319 session_params_.enable_quic = true;
8320 session_params_.enable_quic_proxies_for_https_urls = true;
8321 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8322 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8323
8324 const RequestPriority kRequestPriority = MEDIUM;
8325 const RequestPriority kRequestPriority2 = LOWEST;
8326
8327 MockQuicData mock_quic_data;
8328 quic::QuicStreamOffset header_stream_offset = 0;
8329 mock_quic_data.AddWrite(
8330 ASYNC, ConstructInitialSettingsPacket(1, &header_stream_offset));
8331 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8332 // This should never be reached.
8333 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8334 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8335
8336 // Second connection attempt just fails - result doesn't really matter.
8337 MockQuicData mock_quic_data2;
8338 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8339 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8340
8341 int original_max_sockets_per_group =
8342 ClientSocketPoolManager::max_sockets_per_group(
8343 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8344 ClientSocketPoolManager::set_max_sockets_per_group(
8345 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8346 int original_max_sockets_per_pool =
8347 ClientSocketPoolManager::max_sockets_per_pool(
8348 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8349 ClientSocketPoolManager::set_max_sockets_per_pool(
8350 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8351 CreateSession();
8352
8353 request_.url = GURL("https://mail.example.org/");
8354 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8355 TestCompletionCallback callback;
8356 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8357 EXPECT_EQ(ERR_IO_PENDING, rv);
8358
8359 HttpRequestInfo request2;
8360 request2.url = GURL("https://mail.example.org/some/other/path/");
8361 request2.traffic_annotation =
8362 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8363
8364 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8365 TestCompletionCallback callback2;
8366 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8367 EXPECT_EQ(ERR_IO_PENDING, rv2);
8368
8369 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8370 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8371
8372 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8373
8374 ClientSocketPoolManager::set_max_sockets_per_pool(
8375 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8376 original_max_sockets_per_pool);
8377 ClientSocketPoolManager::set_max_sockets_per_group(
8378 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8379 original_max_sockets_per_group);
8380}
8381
Yixin Wang46a273ec302018-01-23 17:59:568382// Test the request-challenge-retry sequence for basic auth, over a QUIC
8383// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148384TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568385 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8386 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568387
8388 std::unique_ptr<QuicTestPacketMaker> client_maker;
8389 std::unique_ptr<QuicTestPacketMaker> server_maker;
8390
8391 // On the second pass, the body read of the auth challenge is synchronous, so
8392 // IsConnectedAndIdle returns false. The socket should still be drained and
8393 // reused. See http://crbug.com/544255.
8394 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338395 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178396 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8397 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338398 client_headers_include_h2_stream_dependency_));
8399 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178400 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8401 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568402
8403 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148404 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568405 proxy_resolution_service_ =
8406 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498407 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568408
8409 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528410 quic::QuicStreamOffset client_header_stream_offset = 0;
8411 quic::QuicStreamOffset server_header_stream_offset = 0;
8412 quic::QuicStreamOffset client_data_offset = 0;
8413 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568414
Zhongyi Shi32f2fd02018-04-16 18:23:438415 mock_quic_data.AddWrite(SYNCHRONOUS,
8416 client_maker->MakeInitialSettingsPacket(
8417 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568418
8419 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438420 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568421 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338422 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
Matt Menke6e879bd2019-03-18 17:26:048423 ConvertRequestPriorityToQuicPriority(
8424 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568425 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8426 &client_header_stream_offset));
8427
Ryan Hamilton0239aac2018-05-19 00:03:138428 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568429 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8430 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8431 headers["content-length"] = "10";
8432 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438433 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338434 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8435 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568436
8437 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438438 mock_quic_data.AddRead(
8439 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338440 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8441 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568442 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438443 mock_quic_data.AddRead(
8444 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338445 2, GetNthClientInitiatedBidirectionalStreamId(0),
8446 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568447 }
8448 server_data_offset += 10;
8449
Zhongyi Shi32f2fd02018-04-16 18:23:438450 mock_quic_data.AddWrite(SYNCHRONOUS,
8451 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568452
8453 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338454 SYNCHRONOUS,
8455 client_maker->MakeRstPacket(
8456 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188457 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8458 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568459
8460 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8461 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8462 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048463 SYNCHRONOUS,
8464 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8465 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8466 ConvertRequestPriorityToQuicPriority(
8467 HttpProxyConnectJob::kH2QuicTunnelPriority),
8468 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
8469 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568470
8471 // Response to wrong password
8472 headers =
8473 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8474 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8475 headers["content-length"] = "10";
8476 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438477 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338478 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8479 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568480 mock_quic_data.AddRead(SYNCHRONOUS,
8481 ERR_IO_PENDING); // No more data to read
8482
Fan Yang32c5a112018-12-10 20:06:338483 mock_quic_data.AddWrite(
8484 SYNCHRONOUS,
8485 client_maker->MakeAckAndRstPacket(
8486 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8487 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568488
8489 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8490 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8491
8492 CreateSession();
8493
8494 request_.url = GURL("https://mail.example.org/");
8495 // Ensure that proxy authentication is attempted even
8496 // when the no authentication data flag is set.
8497 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8498 {
8499 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8500 HeadersHandler headers_handler;
8501 trans.SetBeforeHeadersSentCallback(
8502 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8503 base::Unretained(&headers_handler)));
8504 RunTransaction(&trans);
8505
8506 const HttpResponseInfo* response = trans.GetResponseInfo();
8507 ASSERT_TRUE(response != nullptr);
8508 ASSERT_TRUE(response->headers.get() != nullptr);
8509 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8510 response->headers->GetStatusLine());
8511 EXPECT_TRUE(response->headers->IsKeepAlive());
8512 EXPECT_EQ(407, response->headers->response_code());
8513 EXPECT_EQ(10, response->headers->GetContentLength());
8514 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588515 base::Optional<AuthChallengeInfo> auth_challenge =
8516 response->auth_challenge;
8517 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568518 EXPECT_TRUE(auth_challenge->is_proxy);
8519 EXPECT_EQ("https://proxy.example.org:70",
8520 auth_challenge->challenger.Serialize());
8521 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8522 EXPECT_EQ("basic", auth_challenge->scheme);
8523
8524 TestCompletionCallback callback;
8525 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8526 callback.callback());
8527 EXPECT_EQ(ERR_IO_PENDING, rv);
8528 EXPECT_EQ(OK, callback.WaitForResult());
8529
8530 response = trans.GetResponseInfo();
8531 ASSERT_TRUE(response != nullptr);
8532 ASSERT_TRUE(response->headers.get() != nullptr);
8533 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8534 response->headers->GetStatusLine());
8535 EXPECT_TRUE(response->headers->IsKeepAlive());
8536 EXPECT_EQ(407, response->headers->response_code());
8537 EXPECT_EQ(10, response->headers->GetContentLength());
8538 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588539 auth_challenge = response->auth_challenge;
8540 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568541 EXPECT_TRUE(auth_challenge->is_proxy);
8542 EXPECT_EQ("https://proxy.example.org:70",
8543 auth_challenge->challenger.Serialize());
8544 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8545 EXPECT_EQ("basic", auth_challenge->scheme);
8546 }
8547 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8548 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8549 // reused because it's not connected).
8550 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8551 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8552 }
8553}
8554
Yixin Wang385652a2018-02-16 02:37:238555TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8556 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8557 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568558 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238559 !client_headers_include_h2_stream_dependency_) {
8560 return;
8561 }
8562
8563 session_params_.origins_to_force_quic_on.insert(
8564 HostPortPair::FromString("mail.example.org:443"));
8565
Fan Yang32c5a112018-12-10 20:06:338566 const quic::QuicStreamId client_stream_0 =
8567 GetNthClientInitiatedBidirectionalStreamId(0);
8568 const quic::QuicStreamId client_stream_1 =
8569 GetNthClientInitiatedBidirectionalStreamId(1);
8570 const quic::QuicStreamId client_stream_2 =
8571 GetNthClientInitiatedBidirectionalStreamId(2);
8572 const quic::QuicStreamId push_stream_0 =
8573 GetNthServerInitiatedUnidirectionalStreamId(0);
8574 const quic::QuicStreamId push_stream_1 =
8575 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238576
8577 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528578 quic::QuicStreamOffset header_stream_offset = 0;
8579 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238580 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438581 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238582
8583 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438584 mock_quic_data.AddWrite(SYNCHRONOUS,
8585 ConstructClientRequestHeadersPacket(
8586 2, client_stream_0, true, true, HIGHEST,
8587 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8588 &header_stream_offset));
8589 mock_quic_data.AddWrite(SYNCHRONOUS,
8590 ConstructClientRequestHeadersPacket(
8591 3, client_stream_1, true, true, MEDIUM,
8592 GetRequestHeaders("GET", "https", "/1.jpg"),
8593 client_stream_0, &header_stream_offset));
8594 mock_quic_data.AddWrite(SYNCHRONOUS,
8595 ConstructClientRequestHeadersPacket(
8596 4, client_stream_2, true, true, MEDIUM,
8597 GetRequestHeaders("GET", "https", "/2.jpg"),
8598 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238599
8600 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438601 mock_quic_data.AddRead(
8602 ASYNC, ConstructServerResponseHeadersPacket(
8603 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8604 &server_header_offset));
8605 mock_quic_data.AddRead(
8606 ASYNC, ConstructServerResponseHeadersPacket(
8607 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8608 &server_header_offset));
8609 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8610 mock_quic_data.AddRead(
8611 ASYNC, ConstructServerResponseHeadersPacket(
8612 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8613 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238614
8615 // Server sends two push promises associated with |client_stream_0|; client
8616 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8617 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438618 mock_quic_data.AddRead(ASYNC,
8619 ConstructServerPushPromisePacket(
8620 4, client_stream_0, push_stream_0, false,
8621 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8622 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238623 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438624 SYNCHRONOUS,
8625 ConstructClientAckAndPriorityFramesPacket(
8626 6, false, 4, 3, 1,
8627 {{push_stream_0, client_stream_2,
8628 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8629 &header_stream_offset));
8630 mock_quic_data.AddRead(ASYNC,
8631 ConstructServerPushPromisePacket(
8632 5, client_stream_0, push_stream_1, false,
8633 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8634 &server_header_offset, &server_maker_));
8635 mock_quic_data.AddWrite(
8636 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238637 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8638 DEFAULT_PRIORITY, &header_stream_offset));
8639
8640 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438641 mock_quic_data.AddRead(
8642 ASYNC, ConstructServerResponseHeadersPacket(
8643 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8644 &server_header_offset));
8645 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8646 mock_quic_data.AddRead(
8647 ASYNC, ConstructServerResponseHeadersPacket(
8648 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8649 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238650
8651 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8652 // priority updates to match the request's priority. Client sends PRIORITY
8653 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438654 mock_quic_data.AddWrite(
8655 SYNCHRONOUS,
8656 ConstructClientAckAndPriorityFramesPacket(
8657 9, false, 7, 7, 1,
8658 {{push_stream_1, client_stream_2,
8659 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8660 {push_stream_0, client_stream_0,
8661 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8662 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238663
8664 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438665 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438666 mock_quic_data.AddRead(
8667 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418668 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438669 mock_quic_data.AddRead(
8670 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418671 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438672 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8673 mock_quic_data.AddRead(
8674 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418675 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438676 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438677 mock_quic_data.AddRead(
8678 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418679 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438680 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8681 mock_quic_data.AddRead(
8682 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418683 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238684
Yixin Wang385652a2018-02-16 02:37:238685 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8686 mock_quic_data.AddRead(ASYNC, 0); // EOF
8687 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8688
8689 // The non-alternate protocol job needs to hang in order to guarantee that
8690 // the alternate-protocol job will "win".
8691 AddHangingNonAlternateProtocolSocketData();
8692
8693 CreateSession();
8694
8695 request_.url = GURL("https://mail.example.org/0.jpg");
8696 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8697 TestCompletionCallback callback_0;
8698 EXPECT_EQ(ERR_IO_PENDING,
8699 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8700 base::RunLoop().RunUntilIdle();
8701
8702 request_.url = GURL("https://mail.example.org/1.jpg");
8703 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8704 TestCompletionCallback callback_1;
8705 EXPECT_EQ(ERR_IO_PENDING,
8706 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8707 base::RunLoop().RunUntilIdle();
8708
8709 request_.url = GURL("https://mail.example.org/2.jpg");
8710 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8711 TestCompletionCallback callback_2;
8712 EXPECT_EQ(ERR_IO_PENDING,
8713 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8714 base::RunLoop().RunUntilIdle();
8715
8716 // Client makes request that matches resource pushed in |pushed_stream_0|.
8717 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8718 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8719 TestCompletionCallback callback_3;
8720 EXPECT_EQ(ERR_IO_PENDING,
8721 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8722 base::RunLoop().RunUntilIdle();
8723
8724 EXPECT_TRUE(callback_0.have_result());
8725 EXPECT_EQ(OK, callback_0.WaitForResult());
8726 EXPECT_TRUE(callback_1.have_result());
8727 EXPECT_EQ(OK, callback_1.WaitForResult());
8728 EXPECT_TRUE(callback_2.have_result());
8729 EXPECT_EQ(OK, callback_2.WaitForResult());
8730
8731 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8732 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8733 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8734 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8735
8736 mock_quic_data.Resume();
8737 base::RunLoop().RunUntilIdle();
8738 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8739 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8740}
8741
[email protected]61a527782013-02-21 03:58:008742} // namespace test
8743} // namespace net