blob: 40c5d9d88781b2220bc4b9816708cee6e42af439 [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 =
Victor Vasiliev5d6cdc22019-05-28 20:37:43160 quic::AllVersionsExcept99();
Nick Harper23290b82019-05-02 00:02:56161 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),
Nick Harpereb483e12019-05-14 00:18:09281 quic_task_runner_(new TestTaskRunner(&clock_)),
rtenneti052774e2015-11-24 21:00:12282 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43283 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59284 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11285 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
rchf114d982015-10-21 01:34:56286 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19287 request_.method = "GET";
rchf114d982015-10-21 01:34:56288 std::string url("https://");
bncb07c05532015-05-14 19:07:20289 url.append(kDefaultServerHostName);
290 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19291 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10292 request_.traffic_annotation =
293 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52294 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56295
296 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29297 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56298 verify_details_.cert_verify_result.verified_cert = cert;
299 verify_details_.cert_verify_result.is_issued_by_known_root = true;
300 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43301 }
[email protected]61a527782013-02-21 03:58:00302
dcheng67be2b1f2014-10-27 21:47:29303 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00304 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55305 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00306 }
307
dcheng67be2b1f2014-10-27 21:47:29308 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00309 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
310 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55311 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00312 PlatformTest::TearDown();
313 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55314 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40315 session_.reset();
[email protected]61a527782013-02-21 03:58:00316 }
317
Ryan Hamilton8d9ee76e2018-05-29 23:52:52318 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23319 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03320 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52321 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30322 }
323
Ryan Hamilton8d9ee76e2018-05-29 23:52:52324 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23325 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03326 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52327 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58328 }
329
Ryan Hamilton8d9ee76e2018-05-29 23:52:52330 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23331 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52332 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20333 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58334 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20335 }
336
Ryan Hamilton8d9ee76e2018-05-29 23:52:52337 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23338 uint64_t packet_number,
339 uint64_t largest_received,
340 uint64_t smallest_received,
341 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37342 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49343 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37344 }
345
Ryan Hamilton8d9ee76e2018-05-29 23:52:52346 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23347 uint64_t packet_number,
348 uint64_t largest_received,
349 uint64_t smallest_received,
350 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52351 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23352 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49353 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23354 ack_delay_time);
355 }
356
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23358 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52359 quic::QuicStreamId stream_id,
360 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23361 uint64_t largest_received,
362 uint64_t smallest_received,
363 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58364 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49365 num, false, stream_id, error_code, largest_received, smallest_received,
366 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20367 }
368
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23370 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52371 quic::QuicStreamId stream_id,
372 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56373 size_t bytes_written) {
374 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18375 bytes_written,
376 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56377 }
378
Ryan Hamilton8d9ee76e2018-05-29 23:52:52379 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23380 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
381 uint64_t largest_received,
382 uint64_t smallest_received,
383 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58384 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49385 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20386 }
[email protected]61a527782013-02-21 03:58:00387
Ryan Hamilton8d9ee76e2018-05-29 23:52:52388 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58389 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23390 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52391 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23392 uint64_t largest_received,
393 uint64_t smallest_received,
394 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52395 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50396 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58397 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12398 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49399 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12400 }
401
Ryan Hamilton8d9ee76e2018-05-29 23:52:52402 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23403 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12404 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 quic::QuicStreamId stream_id,
406 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58407 return server_maker_.MakeRstPacket(num, include_version, stream_id,
408 error_code);
zhongyica364fbb2015-12-12 03:39:12409 }
410
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23412 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52413 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36414 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37415 }
416
Ryan Hamilton8d9ee76e2018-05-29 23:52:52417 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23418 uint64_t packet_number,
419 uint64_t largest_received,
420 uint64_t smallest_received,
421 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37422 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49423 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37424 }
425
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23427 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57428 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 quic::QuicStreamId id,
430 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57431 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57433 return client_maker_.MakePriorityPacket(
434 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23435 ConvertRequestPriorityToQuicPriority(request_priority), offset);
436 }
437
Ryan Hamilton8d9ee76e2018-05-29 23:52:52438 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25439 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23440 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23441 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23442 uint64_t largest_received,
443 uint64_t smallest_received,
444 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25445 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
446 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52447 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25448 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23449 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25450 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57451 }
452
zhongyi32569c62016-01-08 02:54:30453 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13454 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
455 const std::string& scheme,
456 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58457 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30458 }
459
460 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13461 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
462 const std::string& scheme,
463 const std::string& path,
464 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50465 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00466 }
467
Ryan Hamilton0239aac2018-05-19 00:03:13468 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56469 return client_maker_.ConnectRequestHeaders(host_port);
470 }
471
Ryan Hamilton0239aac2018-05-19 00:03:13472 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58473 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00474 }
475
zhongyi32569c62016-01-08 02:54:30476 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13477 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
478 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58479 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30480 }
481
Ryan Hamilton8d9ee76e2018-05-29 23:52:52482 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23483 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52484 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05485 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00486 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52487 quic::QuicStreamOffset offset,
488 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58489 return server_maker_.MakeDataPacket(
490 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00491 }
492
Ryan Hamilton8d9ee76e2018-05-29 23:52:52493 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23494 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52495 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36496 bool should_include_version,
497 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 quic::QuicStreamOffset offset,
499 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36500 return client_maker_.MakeDataPacket(
501 packet_number, stream_id, should_include_version, fin, offset, data);
502 }
503
Renjied172e812019-01-16 05:12:35504 std::unique_ptr<quic::QuicEncryptedPacket>
505 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23506 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35507 quic::QuicStreamId stream_id,
508 bool should_include_version,
509 bool fin,
510 quic::QuicStreamOffset offset,
511 const std::vector<std::string> data_writes) {
512 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
513 should_include_version,
514 fin, offset, data_writes);
515 }
516
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23518 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56519 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23521 uint64_t largest_received,
522 uint64_t smallest_received,
523 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56524 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52525 quic::QuicStreamOffset offset,
526 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56527 return client_maker_.MakeAckAndDataPacket(
528 packet_number, include_version, stream_id, largest_received,
529 smallest_received, least_unacked, fin, offset, data);
530 }
531
Renjied172e812019-01-16 05:12:35532 std::unique_ptr<quic::QuicEncryptedPacket>
533 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23534 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35535 bool include_version,
536 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23537 uint64_t largest_received,
538 uint64_t smallest_received,
539 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35540 bool fin,
541 quic::QuicStreamOffset offset,
542 const std::vector<std::string> data_writes) {
543 return client_maker_.MakeAckAndMultipleDataFramesPacket(
544 packet_number, include_version, stream_id, largest_received,
545 smallest_received, least_unacked, fin, offset, data_writes);
546 }
547
Ryan Hamilton8d9ee76e2018-05-29 23:52:52548 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23549 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36551 bool should_include_version,
552 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52553 quic::QuicStreamOffset* offset,
554 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36555 return client_maker_.MakeForceHolDataPacket(
556 packet_number, stream_id, should_include_version, fin, offset, data);
557 }
558
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23560 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52561 quic::QuicStreamId stream_id,
562 bool should_include_version,
563 bool fin,
564 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56565 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
566 should_include_version, fin,
567 std::move(headers), nullptr);
568 }
569
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23571 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52572 quic::QuicStreamId stream_id,
573 bool should_include_version,
574 bool fin,
575 spdy::SpdyHeaderBlock headers,
576 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48577 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
578 should_include_version, fin,
579 std::move(headers), 0, offset);
580 }
581
Ryan Hamilton8d9ee76e2018-05-29 23:52:52582 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23583 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 quic::QuicStreamId stream_id,
585 bool should_include_version,
586 bool fin,
587 spdy::SpdyHeaderBlock headers,
588 quic::QuicStreamId parent_stream_id,
589 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56590 return ConstructClientRequestHeadersPacket(
591 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48592 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30593 }
594
Ryan Hamilton8d9ee76e2018-05-29 23:52:52595 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23596 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52597 quic::QuicStreamId stream_id,
598 bool should_include_version,
599 bool fin,
600 RequestPriority request_priority,
601 spdy::SpdyHeaderBlock headers,
602 quic::QuicStreamId parent_stream_id,
603 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13604 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56605 ConvertRequestPriorityToQuicPriority(request_priority);
606 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
607 packet_number, stream_id, should_include_version, fin, priority,
608 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00609 }
610
Ryan Hamilton8d9ee76e2018-05-29 23:52:52611 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25612 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23613 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52614 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25615 bool should_include_version,
616 bool fin,
617 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13618 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52619 quic::QuicStreamId parent_stream_id,
620 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25621 size_t* spdy_headers_frame_length,
622 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13623 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25624 ConvertRequestPriorityToQuicPriority(request_priority);
625 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
626 packet_number, stream_id, should_include_version, fin, priority,
627 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
628 data_writes);
629 }
630
Ryan Hamilton8d9ee76e2018-05-29 23:52:52631 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23632 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52633 quic::QuicStreamId stream_id,
634 bool should_include_version,
635 bool fin,
636 const std::vector<std::string>& data,
637 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27638 return client_maker_.MakeMultipleDataFramesPacket(
639 packet_number, stream_id, should_include_version, fin, offset, data);
640 }
641
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23643 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52644 quic::QuicStreamId stream_id,
645 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13646 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13647 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52648 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13649 QuicTestPacketMaker* maker) {
650 return maker->MakePushPromisePacket(
651 packet_number, stream_id, promised_stream_id, should_include_version,
652 false, std::move(headers), nullptr, offset);
653 }
654
Ryan Hamilton8d9ee76e2018-05-29 23:52:52655 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23656 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52657 quic::QuicStreamId stream_id,
658 bool should_include_version,
659 bool fin,
660 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27661 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
662 should_include_version, fin,
663 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30664 }
665
Ryan Hamilton8d9ee76e2018-05-29 23:52:52666 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23667 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52668 quic::QuicStreamId stream_id,
669 bool should_include_version,
670 bool fin,
671 spdy::SpdyHeaderBlock headers,
672 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58673 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25674 packet_number, stream_id, should_include_version, fin,
675 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30676 }
677
Victor Vasiliev076657c2019-03-12 02:46:43678 std::string ConstructDataHeader(size_t body_len) {
Nick Harper23290b82019-05-02 00:02:56679 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:41680 return "";
681 }
682 quic::HttpEncoder encoder;
683 std::unique_ptr<char[]> buffer;
684 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43685 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41686 }
687
Nick Harper23290b82019-05-02 00:02:56688 void CreateSession(const quic::ParsedQuicVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41689 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21690 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05691 session_params_.quic_headers_include_h2_stream_dependency =
692 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00693
mmenke6ddfbea2017-05-31 21:48:41694 session_context_.quic_clock = &clock_;
695 session_context_.quic_random = &random_generator_;
696 session_context_.client_socket_factory = &socket_factory_;
697 session_context_.quic_crypto_client_stream_factory =
698 &crypto_client_stream_factory_;
699 session_context_.host_resolver = &host_resolver_;
700 session_context_.cert_verifier = &cert_verifier_;
701 session_context_.transport_security_state = &transport_security_state_;
702 session_context_.cert_transparency_verifier =
703 cert_transparency_verifier_.get();
704 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
705 session_context_.socket_performance_watcher_factory =
706 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59707 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41708 session_context_.ssl_config_service = ssl_config_service_.get();
709 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
710 session_context_.http_server_properties = &http_server_properties_;
711 session_context_.net_log = net_log_.bound().net_log();
712
713 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12714 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56715 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
716 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00717 }
718
zhongyi86838d52017-06-30 01:19:44719 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21720
bnc691fda62016-08-12 00:43:16721 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19722 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42723 ASSERT_TRUE(response != nullptr);
724 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19725 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
726 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52727 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:56728 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
729 version_.transport_version),
[email protected]aa9b14d2013-05-10 23:45:19730 response->connection_info);
731 }
732
bnc691fda62016-08-12 00:43:16733 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41734 const HttpResponseInfo* response = trans->GetResponseInfo();
735 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37736 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41737 }
738
bnc691fda62016-08-12 00:43:16739 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19740 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42741 ASSERT_TRUE(response != nullptr);
742 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19743 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
744 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52745 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52746 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19747 response->connection_info);
748 }
749
Yixin Wang46a273ec302018-01-23 17:59:56750 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
751 const HttpResponseInfo* response = trans->GetResponseInfo();
752 ASSERT_TRUE(response != nullptr);
753 ASSERT_TRUE(response->headers.get() != nullptr);
754 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
755 EXPECT_TRUE(response->was_fetched_via_spdy);
756 EXPECT_TRUE(response->was_alpn_negotiated);
757 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
758 response->connection_info);
759 }
760
bnc691fda62016-08-12 00:43:16761 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19762 const std::string& expected) {
763 std::string response_data;
bnc691fda62016-08-12 00:43:16764 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19765 EXPECT_EQ(expected, response_data);
766 }
767
bnc691fda62016-08-12 00:43:16768 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19769 TestCompletionCallback callback;
770 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01771 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
772 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19773 }
774
775 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
777 RunTransaction(&trans);
778 CheckWasHttpResponse(&trans);
779 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19780 }
781
tbansalc3308d72016-08-27 10:25:04782 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
783 bool used_proxy,
784 uint16_t port) {
785 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
786 HeadersHandler headers_handler;
787 trans.SetBeforeHeadersSentCallback(
788 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
789 base::Unretained(&headers_handler)));
790 RunTransaction(&trans);
791 CheckWasHttpResponse(&trans);
792 CheckResponsePort(&trans, port);
793 CheckResponseData(&trans, expected);
794 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47795 if (used_proxy) {
796 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
797 } else {
798 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
799 }
tbansalc3308d72016-08-27 10:25:04800 }
801
[email protected]aa9b14d2013-05-10 23:45:19802 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56803 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12804 }
805
bnc62a44f022015-04-02 15:59:41806 void SendRequestAndExpectQuicResponseFromProxyOnPort(
807 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46808 uint16_t port) {
bnc62a44f022015-04-02 15:59:41809 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19810 }
811
812 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27813 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19814 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46815 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21816 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12817 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21818 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44819 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19820 }
821
rchbe69cb902016-02-11 01:10:48822 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27823 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48824 const HostPortPair& alternative) {
825 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46826 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21827 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48828 alternative.port());
829 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21830 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44831 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48832 }
833
[email protected]aa9b14d2013-05-10 23:45:19834 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46835 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34836 const AlternativeServiceInfoVector alternative_service_info_vector =
837 http_server_properties_.GetAlternativeServiceInfos(server);
838 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07839 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54840 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19841 }
842
[email protected]4d590c9c2014-05-02 05:14:33843 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46844 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34845 const AlternativeServiceInfoVector alternative_service_info_vector =
846 http_server_properties_.GetAlternativeServiceInfos(server);
847 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54848 EXPECT_EQ(
849 kProtoQUIC,
850 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23851 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54852 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33853 }
854
[email protected]aa9b14d2013-05-10 23:45:19855 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42856 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30857 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30858 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30859 hanging_data->set_connect_data(hanging_connect);
860 hanging_data_.push_back(std::move(hanging_data));
861 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56862 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19863 }
864
Zhongyi Shia6b68d112018-09-24 07:49:03865 void SetUpTestForRetryConnectionOnAlternateNetwork() {
866 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
867 session_params_.quic_migrate_sessions_early_v2 = true;
868 session_params_.quic_retry_on_alternate_network_before_handshake = true;
869 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
870 MockNetworkChangeNotifier* mock_ncn =
871 scoped_mock_change_notifier_->mock_network_change_notifier();
872 mock_ncn->ForceNetworkHandlesSupported();
873 mock_ncn->SetConnectedNetworksList(
874 {kDefaultNetworkForTests, kNewNetworkForTests});
875 }
876
tbansalc3308d72016-08-27 10:25:04877 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
878 // alternative proxy. Verifies that if the alternative proxy job returns
879 // |error_code|, the request is fetched successfully by the main job.
880 void TestAlternativeProxy(int error_code) {
881 // Use a non-cryptographic scheme for the request URL since this request
882 // will be fetched via proxy with QUIC as the alternative service.
883 request_.url = GURL("http://example.org/");
884 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27885 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04886 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27887 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04888 };
889
Ryan Sleevib8d7ea02018-05-07 20:01:01890 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04891 socket_factory_.AddSocketDataProvider(&quic_data);
892
893 // Main job succeeds and the alternative job fails.
894 // Add data for two requests that will be read by the main job.
895 MockRead http_reads_1[] = {
896 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
897 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
898 MockRead(ASYNC, OK)};
899
900 MockRead http_reads_2[] = {
901 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
902 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
903 MockRead(ASYNC, OK)};
904
Ryan Sleevib8d7ea02018-05-07 20:01:01905 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
906 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04907 socket_factory_.AddSocketDataProvider(&http_data_1);
908 socket_factory_.AddSocketDataProvider(&http_data_2);
909 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
910 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
911
912 TestProxyDelegate test_proxy_delegate;
913 // Proxy URL is different from the request URL.
914 test_proxy_delegate.set_alternative_proxy_server(
915 ProxyServer::FromPacString("QUIC myproxy.org:443"));
916
Lily Houghton8c2f97d2018-01-22 05:06:59917 proxy_resolution_service_ =
918 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49919 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52920 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04921
922 CreateSession();
923 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
924
925 // The first request should be fetched via the HTTPS proxy.
926 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
927
Reilly Grant89a7e512018-01-20 01:57:16928 // Since the main job succeeded only the alternative proxy server should be
929 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59930 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16931 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04932
933 // Verify that the second request completes successfully, and the
934 // alternative proxy server job is not started.
935 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
936 }
937
Fan Yang32c5a112018-12-10 20:06:33938 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56939 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
940 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36941 }
942
Fan Yang32c5a112018-12-10 20:06:33943 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56944 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
945 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36946 }
947
Bence Béky230ac612017-08-30 19:17:08948 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49949 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08950 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49951 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08952 }
953
Nick Harper23290b82019-05-02 00:02:56954 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:05955 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:56956 quic::ParsedQuicVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01957 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52958 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17959 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58960 QuicTestPacketMaker client_maker_;
961 QuicTestPacketMaker server_maker_;
Nick Harpereb483e12019-05-14 00:18:09962 scoped_refptr<TestTaskRunner> quic_task_runner_;
danakjad1777e2016-04-16 00:56:42963 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00964 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56965 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05966 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43967 MockHostResolver host_resolver_;
968 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11969 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42970 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23971 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38972 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07973 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59974 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42975 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07976 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41977 HttpNetworkSession::Params session_params_;
978 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19979 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51980 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42981 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56982 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03983 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12984
985 private:
986 void SendRequestAndExpectQuicResponseMaybeFromProxy(
987 const std::string& expected,
bnc62a44f022015-04-02 15:59:41988 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46989 uint16_t port) {
bnc691fda62016-08-12 00:43:16990 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09991 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16992 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09993 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
994 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16995 RunTransaction(&trans);
996 CheckWasQuicResponse(&trans);
997 CheckResponsePort(&trans, port);
998 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09999 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:471000 if (used_proxy) {
1001 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
1002 } else {
1003 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
1004 }
tbansal7cec3812015-02-05 21:25:121005 }
[email protected]61a527782013-02-21 03:58:001006};
1007
Victor Costane635086f2019-01-27 05:20:301008INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231009 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051010 QuicNetworkTransactionTest,
Victor Vasiliev5d6cdc22019-05-28 20:37:431011 ::testing::Combine(::testing::ValuesIn(quic::AllVersionsExcept99()),
Nick Harper23290b82019-05-02 00:02:561012 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201013
Ryan Hamiltona64a5bcf2017-11-30 07:35:281014TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481015 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281016 base::HistogramTester histograms;
1017 session_params_.origins_to_force_quic_on.insert(
1018 HostPortPair::FromString("mail.example.org:443"));
1019 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271020 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281021
1022 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521023 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281024 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431025 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281026 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1027 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1028 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1029
1030 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1031
1032 CreateSession();
1033
1034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1035 TestCompletionCallback callback;
1036 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1038 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1039
1040 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1041 -ERR_INTERNET_DISCONNECTED, 1);
1042 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1043 -ERR_INTERNET_DISCONNECTED, 1);
1044}
1045
1046TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481047 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281048 base::HistogramTester histograms;
1049 session_params_.origins_to_force_quic_on.insert(
1050 HostPortPair::FromString("mail.example.org:443"));
1051 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271052 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281053
1054 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521055 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281056 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431057 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281058 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1059 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1060 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1061
1062 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1063
1064 CreateSession();
1065
1066 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1067 TestCompletionCallback callback;
1068 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1070 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1071
1072 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1073 -ERR_INTERNET_DISCONNECTED, 1);
1074 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1075 -ERR_INTERNET_DISCONNECTED, 1);
1076}
1077
tbansal180587c2017-02-16 15:13:231078TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411079 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231080 HostPortPair::FromString("mail.example.org:443"));
1081
1082 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521083 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361084 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431085 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1086 mock_quic_data.AddWrite(
1087 SYNCHRONOUS,
1088 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331089 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431090 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431091 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331092 ASYNC, ConstructServerResponseHeadersPacket(
1093 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1094 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431095 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331096 mock_quic_data.AddRead(
1097 ASYNC, ConstructServerDataPacket(
1098 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411099 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431100 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231101 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1102
1103 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1104
1105 CreateSession();
1106 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1107
1108 EXPECT_FALSE(
1109 test_socket_performance_watcher_factory_.rtt_notification_received());
1110 SendRequestAndExpectQuicResponse("hello!");
1111 EXPECT_TRUE(
1112 test_socket_performance_watcher_factory_.rtt_notification_received());
1113}
1114
1115TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411116 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231117 HostPortPair::FromString("mail.example.org:443"));
1118
1119 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521120 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361121 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431122 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1123 mock_quic_data.AddWrite(
1124 SYNCHRONOUS,
1125 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331126 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431127 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431128 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331129 ASYNC, ConstructServerResponseHeadersPacket(
1130 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1131 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431132 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331133 mock_quic_data.AddRead(
1134 ASYNC, ConstructServerDataPacket(
1135 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411136 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431137 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231138 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1139
1140 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1141
1142 CreateSession();
1143 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1144
1145 EXPECT_FALSE(
1146 test_socket_performance_watcher_factory_.rtt_notification_received());
1147 SendRequestAndExpectQuicResponse("hello!");
1148 EXPECT_FALSE(
1149 test_socket_performance_watcher_factory_.rtt_notification_received());
1150}
1151
[email protected]1e960032013-12-20 19:00:201152TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411153 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571154 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471155
[email protected]1e960032013-12-20 19:00:201156 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521157 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361158 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431159 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1160 mock_quic_data.AddWrite(
1161 SYNCHRONOUS,
1162 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331163 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431164 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431165 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331166 ASYNC, ConstructServerResponseHeadersPacket(
1167 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1168 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431169 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331170 mock_quic_data.AddRead(
1171 ASYNC, ConstructServerDataPacket(
1172 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411173 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431174 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591175 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471176
rcha5399e02015-04-21 19:32:041177 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471178
[email protected]4dca587c2013-03-07 16:54:471179 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471180
[email protected]aa9b14d2013-05-10 23:45:191181 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471182
[email protected]98b20ce2013-05-10 05:55:261183 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461184 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191185 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261186 EXPECT_LT(0u, entries.size());
1187
1188 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291189 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001190 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1191 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261192 EXPECT_LT(0, pos);
1193
rchfd527212015-08-25 00:41:261194 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291195 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261196 entries, 0,
mikecirone8b85c432016-09-08 19:11:001197 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1198 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261199 EXPECT_LT(0, pos);
1200
Eric Romanaefc98c2018-12-18 21:38:011201 int packet_number;
1202 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1203 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261204
rchfd527212015-08-25 00:41:261205 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1206 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001207 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1208 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261209 EXPECT_LT(0, pos);
1210
[email protected]98b20ce2013-05-10 05:55:261211 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291212 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001213 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1214 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261215 EXPECT_LT(0, pos);
1216
1217 int log_stream_id;
1218 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Nick Harper23290b82019-05-02 00:02:561219 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
Fan Yang7c68f632018-11-06 03:05:381220 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471221}
1222
rchbd089ab2017-05-26 23:05:041223TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411224 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041225 HostPortPair::FromString("mail.example.org:443"));
1226
1227 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521228 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041229 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431230 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1231 mock_quic_data.AddWrite(
1232 SYNCHRONOUS,
1233 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331234 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431235 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131236 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041237 response_headers["key1"] = std::string(30000, 'A');
1238 response_headers["key2"] = std::string(30000, 'A');
1239 response_headers["key3"] = std::string(30000, 'A');
1240 response_headers["key4"] = std::string(30000, 'A');
1241 response_headers["key5"] = std::string(30000, 'A');
1242 response_headers["key6"] = std::string(30000, 'A');
1243 response_headers["key7"] = std::string(30000, 'A');
1244 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331245 spdy::SpdyHeadersIR headers_frame(
1246 GetNthClientInitiatedBidirectionalStreamId(0),
1247 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131248 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1249 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041250 response_framer.SerializeFrame(headers_frame);
1251
Fan Yangac867502019-01-28 21:10:231252 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041253 size_t chunk_size = 1200;
1254 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1255 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431256 mock_quic_data.AddRead(
Nick Harper23290b82019-05-02 00:02:561257 ASYNC,
1258 ConstructServerDataPacket(
1259 packet_number++,
1260 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1261 false, false, offset,
1262 base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041263 }
1264
Victor Vasiliev076657c2019-03-12 02:46:431265 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041266 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331267 ASYNC, ConstructServerDataPacket(
1268 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411269 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041270 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431271 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1272 mock_quic_data.AddWrite(ASYNC,
1273 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041274
1275 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1276
1277 CreateSession();
1278
1279 SendRequestAndExpectQuicResponse("hello!");
Zhongyi Shi99d0cdd2019-05-21 01:18:421280 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1281 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
rchbd089ab2017-05-26 23:05:041282}
1283
1284TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481285 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411286 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041287 HostPortPair::FromString("mail.example.org:443"));
1288
1289 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521290 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041291 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431292 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1293 mock_quic_data.AddWrite(
1294 SYNCHRONOUS,
1295 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331296 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431297 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131298 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041299 response_headers["key1"] = std::string(30000, 'A');
1300 response_headers["key2"] = std::string(30000, 'A');
1301 response_headers["key3"] = std::string(30000, 'A');
1302 response_headers["key4"] = std::string(30000, 'A');
1303 response_headers["key5"] = std::string(30000, 'A');
1304 response_headers["key6"] = std::string(30000, 'A');
1305 response_headers["key7"] = std::string(30000, 'A');
1306 response_headers["key8"] = std::string(30000, 'A');
1307 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331308 spdy::SpdyHeadersIR headers_frame(
1309 GetNthClientInitiatedBidirectionalStreamId(0),
1310 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131311 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1312 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041313 response_framer.SerializeFrame(headers_frame);
1314
Fan Yangac867502019-01-28 21:10:231315 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041316 size_t chunk_size = 1200;
1317 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1318 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431319 mock_quic_data.AddRead(
Nick Harper23290b82019-05-02 00:02:561320 ASYNC,
1321 ConstructServerDataPacket(
1322 packet_number++,
1323 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
1324 false, false, offset,
1325 base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041326 }
1327
Victor Vasiliev076657c2019-03-12 02:46:431328 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411329
rchbd089ab2017-05-26 23:05:041330 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331331 ASYNC, ConstructServerDataPacket(
1332 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411333 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041334 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431335 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1336 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331337 ASYNC, ConstructClientAckAndRstPacket(
1338 4, GetNthClientInitiatedBidirectionalStreamId(0),
1339 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041340
1341 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1342
1343 CreateSession();
1344
1345 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1346 TestCompletionCallback callback;
1347 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1349 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1350}
1351
rcha2bd44b2016-07-02 00:42:551352TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411353 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551354
Ryan Hamilton9835e662018-08-02 05:36:271355 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551356
1357 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521358 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361359 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431360 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1361 mock_quic_data.AddWrite(
1362 SYNCHRONOUS,
1363 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331364 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431365 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431366 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331367 ASYNC, ConstructServerResponseHeadersPacket(
1368 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1369 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431370 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331371 mock_quic_data.AddRead(
1372 ASYNC, ConstructServerDataPacket(
1373 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411374 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431375 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551376 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1377
1378 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1379
1380 CreateSession();
1381
1382 SendRequestAndExpectQuicResponse("hello!");
1383 EXPECT_TRUE(
1384 test_socket_performance_watcher_factory_.rtt_notification_received());
1385}
1386
[email protected]cf3e3cd62014-02-05 16:16:161387TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411388 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591389 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491390 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161391
[email protected]cf3e3cd62014-02-05 16:16:161392 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521393 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361394 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431395 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1396 mock_quic_data.AddWrite(
1397 SYNCHRONOUS,
1398 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331399 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431400 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431401 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331402 ASYNC, ConstructServerResponseHeadersPacket(
1403 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1404 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431405 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331406 mock_quic_data.AddRead(
1407 ASYNC, ConstructServerDataPacket(
1408 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411409 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431410 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501411 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591412 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161413
rcha5399e02015-04-21 19:32:041414 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161415
tbansal0f56a39a2016-04-07 22:03:381416 EXPECT_FALSE(
1417 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161418 // There is no need to set up an alternate protocol job, because
1419 // no attempt will be made to speak to the proxy over TCP.
1420
rch9ae5b3b2016-02-11 00:36:291421 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161422 CreateSession();
1423
bnc62a44f022015-04-02 15:59:411424 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381425 EXPECT_TRUE(
1426 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161427}
1428
bnc313ba9c2015-06-11 15:42:311429// Regression test for https://crbug.com/492458. Test that for an HTTP
1430// connection through a QUIC proxy, the certificate exhibited by the proxy is
1431// checked against the proxy hostname, not the origin hostname.
1432TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291433 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311434 const std::string proxy_host = "www.example.org";
1435
mmenke6ddfbea2017-05-31 21:48:411436 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591437 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491438 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311439
alyssar2adf3ac2016-05-03 17:12:581440 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311441 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521442 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361443 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431444 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1445 mock_quic_data.AddWrite(
1446 SYNCHRONOUS,
1447 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331448 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431449 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431450 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331451 ASYNC, ConstructServerResponseHeadersPacket(
1452 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1453 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431454 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331455 mock_quic_data.AddRead(
1456 ASYNC, ConstructServerDataPacket(
1457 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411458 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431459 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501460 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591461 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311462 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1463
1464 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291465 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311466 ASSERT_TRUE(cert.get());
1467 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241468 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1469 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311470 ProofVerifyDetailsChromium verify_details;
1471 verify_details.cert_verify_result.verified_cert = cert;
1472 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561473 ProofVerifyDetailsChromium verify_details2;
1474 verify_details2.cert_verify_result.verified_cert = cert;
1475 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311476
1477 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091478 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321479 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271480 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311481 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1482}
1483
rchbe69cb902016-02-11 01:10:481484TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341485 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481486 HostPortPair origin("www.example.org", 443);
1487 HostPortPair alternative("mail.example.org", 443);
1488
1489 base::FilePath certs_dir = GetTestCertsDirectory();
1490 scoped_refptr<X509Certificate> cert(
1491 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1492 ASSERT_TRUE(cert.get());
1493 // TODO(rch): the connection should be "to" the origin, so if the cert is
1494 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241495 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1496 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481497 ProofVerifyDetailsChromium verify_details;
1498 verify_details.cert_verify_result.verified_cert = cert;
1499 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1500
alyssar2adf3ac2016-05-03 17:12:581501 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481502 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521503 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361504 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431505 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1506 mock_quic_data.AddWrite(
1507 SYNCHRONOUS,
1508 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331509 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431510 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431511 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331512 ASYNC, ConstructServerResponseHeadersPacket(
1513 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1514 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431515 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331516 mock_quic_data.AddRead(
1517 ASYNC, ConstructServerDataPacket(
1518 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411519 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431520 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481521 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1522 mock_quic_data.AddRead(ASYNC, 0);
1523 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1524
1525 request_.url = GURL("https://" + origin.host());
1526 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271527 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091528 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321529 CreateSession();
rchbe69cb902016-02-11 01:10:481530
1531 SendRequestAndExpectQuicResponse("hello!");
1532}
1533
zhongyief3f4ce52017-07-05 23:53:281534TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:561535 quic::ParsedQuicVersion unsupported_version = quic::UnsupportedQuicVersion();
zhongyief3f4ce52017-07-05 23:53:281536 // Add support for another QUIC version besides |version_|. Also find a
1537 // unsupported version.
Nick Harper23290b82019-05-02 00:02:561538 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyief3f4ce52017-07-05 23:53:281539 if (version == version_)
1540 continue;
1541 if (supported_versions_.size() != 2) {
1542 supported_versions_.push_back(version);
1543 continue;
1544 }
1545 unsupported_version = version;
1546 break;
1547 }
Nick Harper23290b82019-05-02 00:02:561548 DCHECK_NE(unsupported_version, quic::UnsupportedQuicVersion());
zhongyief3f4ce52017-07-05 23:53:281549
1550 // Set up alternative service to use QUIC with a version that is not
1551 // supported.
1552 url::SchemeHostPort server(request_.url);
1553 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1554 443);
1555 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1556 http_server_properties_.SetQuicAlternativeService(
1557 server, alternative_service, expiration, {unsupported_version});
1558
1559 AlternativeServiceInfoVector alt_svc_info_vector =
1560 http_server_properties_.GetAlternativeServiceInfos(server);
1561 EXPECT_EQ(1u, alt_svc_info_vector.size());
1562 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1563 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1564 EXPECT_EQ(unsupported_version,
1565 alt_svc_info_vector[0].advertised_versions()[0]);
1566
1567 // First request should still be sent via TCP as the QUIC version advertised
1568 // in the stored AlternativeService is not supported by the client. However,
1569 // the response from the server will advertise new Alt-Svc with supported
1570 // versions.
Ryan Hamilton8380c652019-06-04 02:25:061571 quic::ParsedQuicVersionVector versions;
1572 for (quic::QuicTransportVersion version :
1573 quic::AllSupportedTransportVersions()) {
1574 versions.push_back(
1575 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
1576 }
zhongyief3f4ce52017-07-05 23:53:281577 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:061578 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyief3f4ce52017-07-05 23:53:281579 std::string altsvc_header =
1580 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1581 advertised_versions_list_str.c_str());
1582 MockRead http_reads[] = {
1583 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1584 MockRead("hello world"),
1585 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1586 MockRead(ASYNC, OK)};
1587
Ryan Sleevib8d7ea02018-05-07 20:01:011588 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281589 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081590 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281591 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1592
1593 // Second request should be sent via QUIC as a new list of verions supported
1594 // by the client has been advertised by the server.
1595 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521596 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281597 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431598 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1599 mock_quic_data.AddWrite(
1600 SYNCHRONOUS,
1601 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331602 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431603 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431604 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331605 ASYNC, ConstructServerResponseHeadersPacket(
1606 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1607 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431608 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331609 mock_quic_data.AddRead(
1610 ASYNC, ConstructServerDataPacket(
1611 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411612 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431613 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281614 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1615 mock_quic_data.AddRead(ASYNC, 0); // EOF
1616
1617 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1618
1619 AddHangingNonAlternateProtocolSocketData();
1620
1621 CreateSession(supported_versions_);
1622
1623 SendRequestAndExpectHttpResponse("hello world");
1624 SendRequestAndExpectQuicResponse("hello!");
1625
1626 // Check alternative service list is updated with new versions.
1627 alt_svc_info_vector =
1628 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1629 EXPECT_EQ(1u, alt_svc_info_vector.size());
1630 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1631 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1632 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561633 std::sort(
1634 supported_versions_.begin(), supported_versions_.end(),
1635 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1636 return a.transport_version < b.transport_version;
1637 });
zhongyief3f4ce52017-07-05 23:53:281638 EXPECT_EQ(supported_versions_[0],
1639 alt_svc_info_vector[0].advertised_versions()[0]);
1640 EXPECT_EQ(supported_versions_[1],
1641 alt_svc_info_vector[0].advertised_versions()[1]);
1642}
1643
bncaccd4962017-04-06 21:00:261644// Regression test for https://crbug.com/546991.
1645// The server might not be able to serve a request on an alternative connection,
1646// and might send a 421 Misdirected Request response status to indicate this.
1647// HttpNetworkTransaction should reset the request and retry without using
1648// alternative services.
1649TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1650 // Set up alternative service to use QUIC.
1651 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1652 // that overrides |enable_alternative_services|.
1653 url::SchemeHostPort server(request_.url);
1654 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1655 443);
1656 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211657 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441658 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261659
davidbena4449722017-05-05 23:30:531660 // First try: The alternative job uses QUIC and reports an HTTP 421
1661 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1662 // paused at Connect(), so it will never exit the socket pool. This ensures
1663 // that the alternate job always wins the race and keeps whether the
1664 // |http_data| exits the socket pool before the main job is aborted
1665 // deterministic. The first main job gets aborted without the socket pool ever
1666 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261667 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521668 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361669 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431670 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1671 mock_quic_data.AddWrite(
1672 SYNCHRONOUS,
1673 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331674 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431675 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331676 mock_quic_data.AddRead(
1677 ASYNC, ConstructServerResponseHeadersPacket(
1678 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1679 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261680 mock_quic_data.AddRead(ASYNC, OK);
1681 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1682
davidbena4449722017-05-05 23:30:531683 // Second try: The main job uses TCP, and there is no alternate job. Once the
1684 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1685 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261686 // Note that if there was an alternative QUIC Job created for the second try,
1687 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1688 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531689 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1690 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1691 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1692 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1693 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1694 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011695 reads, writes);
bncaccd4962017-04-06 21:00:261696 socket_factory_.AddSocketDataProvider(&http_data);
1697 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1698
bncaccd4962017-04-06 21:00:261699 CreateSession();
1700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531701
1702 // Run until |mock_quic_data| has failed and |http_data| has paused.
1703 TestCompletionCallback callback;
1704 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1706 base::RunLoop().RunUntilIdle();
1707
1708 // |mock_quic_data| must have run to completion.
1709 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1710 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1711
1712 // Now that the QUIC data has been consumed, unblock |http_data|.
1713 http_data.socket()->OnConnectComplete(MockConnect());
1714
1715 // The retry logic must hide the 421 status. The transaction succeeds on
1716 // |http_data|.
1717 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261718 CheckWasHttpResponse(&trans);
1719 CheckResponsePort(&trans, 443);
1720 CheckResponseData(&trans, "hello!");
1721}
1722
[email protected]1e960032013-12-20 19:00:201723TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411724 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571725 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301726
tbansalfdf5665b2015-09-21 22:46:401727 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521728 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361729 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431730 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401731 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401732 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371733 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361734 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431735 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301736 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401737 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431738 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401739
1740 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1741 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301742
1743 CreateSession();
1744
tbansal0f56a39a2016-04-07 22:03:381745 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401746 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401748 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161749 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011750 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1751 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381752 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531753
1754 NetErrorDetails details;
1755 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521756 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401757 }
[email protected]cebe3282013-05-22 23:49:301758}
1759
tbansalc8a94ea2015-11-02 23:58:511760TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1761 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411762 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571763 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511764
1765 MockRead http_reads[] = {
1766 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1767 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1768 MockRead(ASYNC, OK)};
1769
Ryan Sleevib8d7ea02018-05-07 20:01:011770 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511771 socket_factory_.AddSocketDataProvider(&data);
1772 SSLSocketDataProvider ssl(ASYNC, OK);
1773 socket_factory_.AddSSLSocketDataProvider(&ssl);
1774
1775 CreateSession();
1776
1777 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381778 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511779}
1780
bncc958faa2015-07-31 18:14:521781TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521782 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561783 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1784 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521785 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1786 MockRead(ASYNC, OK)};
1787
Ryan Sleevib8d7ea02018-05-07 20:01:011788 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521789 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081790 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561791 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521792
1793 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521794 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361795 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431796 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1797 mock_quic_data.AddWrite(
1798 SYNCHRONOUS,
1799 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331800 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431801 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431802 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331803 ASYNC, ConstructServerResponseHeadersPacket(
1804 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1805 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431806 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331807 mock_quic_data.AddRead(
1808 ASYNC, ConstructServerDataPacket(
1809 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411810 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431811 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521812 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591813 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521814
1815 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1816
rtennetib8e80fb2016-05-16 00:12:091817 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321818 CreateSession();
bncc958faa2015-07-31 18:14:521819
1820 SendRequestAndExpectHttpResponse("hello world");
1821 SendRequestAndExpectQuicResponse("hello!");
1822}
1823
zhongyia00ca012017-07-06 23:36:391824TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1825 // Both server advertises and client supports two QUIC versions.
1826 // Only |version_| is advertised and supported.
1827 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1828 // PacketMakers are using |version_|.
1829
1830 // Add support for another QUIC version besides |version_| on the client side.
1831 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:561832 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
1833 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391834 if (version == version_)
1835 continue;
1836 if (supported_versions_.size() != 2) {
1837 supported_versions_.push_back(version);
1838 continue;
1839 }
1840 advertised_version_2 = version;
1841 break;
1842 }
Nick Harper23290b82019-05-02 00:02:561843 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391844
Nick Harper23290b82019-05-02 00:02:561845 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1846 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1847 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391848
1849 MockRead http_reads[] = {
1850 MockRead("HTTP/1.1 200 OK\r\n"),
1851 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1852 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1853 MockRead(ASYNC, OK)};
1854
Ryan Sleevib8d7ea02018-05-07 20:01:011855 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391856 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081857 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391858 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1859
1860 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521861 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391862 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431863 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1864 mock_quic_data.AddWrite(
1865 SYNCHRONOUS,
1866 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331867 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431868 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431869 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331870 ASYNC, ConstructServerResponseHeadersPacket(
1871 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1872 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431873 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331874 mock_quic_data.AddRead(
1875 ASYNC, ConstructServerDataPacket(
1876 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411877 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431878 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391879 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1880 mock_quic_data.AddRead(ASYNC, 0); // EOF
1881
1882 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1883
1884 AddHangingNonAlternateProtocolSocketData();
1885 CreateSession(supported_versions_);
1886
1887 SendRequestAndExpectHttpResponse("hello world");
1888 SendRequestAndExpectQuicResponse("hello!");
1889}
1890
1891TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1892 // Client and server mutually support more than one QUIC_VERSION.
1893 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1894 // which is verified as the PacketMakers are using |version_|.
1895
Nick Harper23290b82019-05-02 00:02:561896 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
1897 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391898 if (version == version_)
1899 continue;
1900 common_version_2 = version;
1901 break;
1902 }
Nick Harper23290b82019-05-02 00:02:561903 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391904
1905 supported_versions_.push_back(
1906 common_version_2); // Supported but unpreferred.
1907
1908 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:561909 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1910 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391911
1912 MockRead http_reads[] = {
1913 MockRead("HTTP/1.1 200 OK\r\n"),
1914 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1915 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1916 MockRead(ASYNC, OK)};
1917
Ryan Sleevib8d7ea02018-05-07 20:01:011918 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391919 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081920 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391921 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1922
1923 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521924 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391925 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431926 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1927 mock_quic_data.AddWrite(
1928 SYNCHRONOUS,
1929 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331930 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431931 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431932 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331933 ASYNC, ConstructServerResponseHeadersPacket(
1934 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1935 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431936 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331937 mock_quic_data.AddRead(
1938 ASYNC, ConstructServerDataPacket(
1939 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411940 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431941 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391942 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1943 mock_quic_data.AddRead(ASYNC, 0); // EOF
1944
1945 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1946
1947 AddHangingNonAlternateProtocolSocketData();
1948 CreateSession(supported_versions_);
1949
1950 SendRequestAndExpectHttpResponse("hello world");
1951 SendRequestAndExpectQuicResponse("hello!");
1952}
1953
rchf47265dc2016-03-21 21:33:121954TEST_P(QuicNetworkTransactionTest,
1955 UseAlternativeServiceWithProbabilityForQuic) {
1956 MockRead http_reads[] = {
1957 MockRead("HTTP/1.1 200 OK\r\n"),
1958 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1959 MockRead("hello world"),
1960 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1961 MockRead(ASYNC, OK)};
1962
Ryan Sleevib8d7ea02018-05-07 20:01:011963 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121964 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081965 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121966 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1967
1968 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521969 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361970 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431971 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1972 mock_quic_data.AddWrite(
1973 SYNCHRONOUS,
1974 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331975 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431976 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431977 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331978 ASYNC, ConstructServerResponseHeadersPacket(
1979 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1980 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431981 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331982 mock_quic_data.AddRead(
1983 ASYNC, ConstructServerDataPacket(
1984 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411985 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431986 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121987 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1988 mock_quic_data.AddRead(ASYNC, 0); // EOF
1989
1990 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1991
rtennetib8e80fb2016-05-16 00:12:091992 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121993 CreateSession();
1994
1995 SendRequestAndExpectHttpResponse("hello world");
1996 SendRequestAndExpectQuicResponse("hello!");
1997}
1998
zhongyi3d4a55e72016-04-22 20:36:461999TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
2000 MockRead http_reads[] = {
2001 MockRead("HTTP/1.1 200 OK\r\n"),
2002 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2003 MockRead("hello world"),
2004 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2005 MockRead(ASYNC, OK)};
2006
Ryan Sleevib8d7ea02018-05-07 20:01:012007 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462008 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082009 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462010 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2011
2012 CreateSession();
bncb26024382016-06-29 02:39:452013 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462014 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452015 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462016 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402017 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462018 session_->http_server_properties();
2019 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2020 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2021 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462022 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342023 2u,
2024 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452025 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342026 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462027}
2028
2029TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2030 MockRead http_reads[] = {
2031 MockRead("HTTP/1.1 200 OK\r\n"),
2032 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2033 MockRead("hello world"),
2034 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2035 MockRead(ASYNC, OK)};
2036
Ryan Sleevib8d7ea02018-05-07 20:01:012037 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082038 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462039
2040 socket_factory_.AddSocketDataProvider(&http_data);
2041 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2042 socket_factory_.AddSocketDataProvider(&http_data);
2043 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2044
2045 CreateSession();
2046
2047 // Send https request and set alternative services if response header
2048 // advertises alternative service for mail.example.org.
2049 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402050 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462051 session_->http_server_properties();
2052
2053 const url::SchemeHostPort https_server(request_.url);
2054 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342055 EXPECT_EQ(
2056 2u,
2057 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462058
2059 // Send http request to the same origin but with diffrent scheme, should not
2060 // use QUIC.
2061 request_.url = GURL("http://mail.example.org:443");
2062 SendRequestAndExpectHttpResponse("hello world");
2063}
2064
zhongyie537a002017-06-27 16:48:212065TEST_P(QuicNetworkTransactionTest,
2066 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442067 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562068 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442069 if (version == version_)
2070 continue;
2071 supported_versions_.push_back(version);
2072 break;
2073 }
2074
Ryan Hamilton8380c652019-06-04 02:25:062075 quic::ParsedQuicVersionVector versions;
2076 for (quic::QuicTransportVersion version :
2077 quic::AllSupportedTransportVersions()) {
2078 versions.push_back(
2079 quic::ParsedQuicVersion(quic::PROTOCOL_QUIC_CRYPTO, version));
2080 }
zhongyie537a002017-06-27 16:48:212081 std::string advertised_versions_list_str =
Ryan Hamilton8380c652019-06-04 02:25:062082 GenerateQuicVersionsListForAltSvcHeader(versions);
zhongyie537a002017-06-27 16:48:212083 std::string altsvc_header =
2084 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2085 advertised_versions_list_str.c_str());
2086 MockRead http_reads[] = {
2087 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2088 MockRead("hello world"),
2089 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2090 MockRead(ASYNC, OK)};
2091
Ryan Sleevib8d7ea02018-05-07 20:01:012092 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212093 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082094 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212095 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2096
2097 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522098 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212099 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432100 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2101 mock_quic_data.AddWrite(
2102 SYNCHRONOUS,
2103 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332104 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432105 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432106 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332107 ASYNC, ConstructServerResponseHeadersPacket(
2108 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2109 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432110 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332111 mock_quic_data.AddRead(
2112 ASYNC, ConstructServerDataPacket(
2113 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412114 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432115 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212116 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2117 mock_quic_data.AddRead(ASYNC, 0); // EOF
2118
2119 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2120
2121 AddHangingNonAlternateProtocolSocketData();
2122
zhongyi86838d52017-06-30 01:19:442123 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212124
2125 SendRequestAndExpectHttpResponse("hello world");
2126 SendRequestAndExpectQuicResponse("hello!");
2127
2128 // Check alternative service is set with only mutually supported versions.
2129 const url::SchemeHostPort https_server(request_.url);
2130 const AlternativeServiceInfoVector alt_svc_info_vector =
2131 session_->http_server_properties()->GetAlternativeServiceInfos(
2132 https_server);
2133 EXPECT_EQ(1u, alt_svc_info_vector.size());
2134 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2135 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2136 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562137 std::sort(
2138 supported_versions_.begin(), supported_versions_.end(),
2139 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2140 return a.transport_version < b.transport_version;
2141 });
zhongyi86838d52017-06-30 01:19:442142 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212143 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442144 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212145 alt_svc_info_vector[0].advertised_versions()[1]);
2146}
2147
danzh3134c2562016-08-12 14:07:522148TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562149 std::string altsvc_header = base::StringPrintf(
2150 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072151 MockRead http_reads[] = {
2152 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2153 MockRead("hello world"),
2154 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2155 MockRead(ASYNC, OK)};
2156
Ryan Sleevib8d7ea02018-05-07 20:01:012157 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072158 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082159 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072160 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2161
2162 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522163 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362164 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432165 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2166 mock_quic_data.AddWrite(
2167 SYNCHRONOUS,
2168 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332169 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432170 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432171 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332172 ASYNC, ConstructServerResponseHeadersPacket(
2173 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2174 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432175 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332176 mock_quic_data.AddRead(
2177 ASYNC, ConstructServerDataPacket(
2178 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412179 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432180 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072181 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592182 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072183
2184 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2185
rtennetib8e80fb2016-05-16 00:12:092186 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322187 CreateSession();
bnc8be55ebb2015-10-30 14:12:072188
2189 SendRequestAndExpectHttpResponse("hello world");
2190 SendRequestAndExpectQuicResponse("hello!");
2191}
2192
zhongyi6b5a3892016-03-12 04:46:202193TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562194 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092195 // Not available under version 99
2196 return;
2197 }
zhongyi6b5a3892016-03-12 04:46:202198 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522199 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362200 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432201 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2202 mock_quic_data.AddWrite(
2203 SYNCHRONOUS,
2204 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332205 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432206 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332207 mock_quic_data.AddRead(
2208 ASYNC, ConstructServerResponseHeadersPacket(
2209 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2210 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202211 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522212 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432213 mock_quic_data.AddRead(SYNCHRONOUS,
2214 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522215 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432216 "connection migration with port change only"));
2217 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432218 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332219 mock_quic_data.AddRead(
2220 SYNCHRONOUS, ConstructServerDataPacket(
2221 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412222 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332223 mock_quic_data.AddWrite(SYNCHRONOUS,
2224 ConstructClientAckAndRstPacket(
2225 4, GetNthClientInitiatedBidirectionalStreamId(0),
2226 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202227 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2228 mock_quic_data.AddRead(ASYNC, 0); // EOF
2229
2230 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2231
2232 // The non-alternate protocol job needs to hang in order to guarantee that
2233 // the alternate-protocol job will "win".
2234 AddHangingNonAlternateProtocolSocketData();
2235
2236 // In order for a new QUIC session to be established via alternate-protocol
2237 // without racing an HTTP connection, we need the host resolution to happen
2238 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2239 // connection to the the server, in this test we require confirmation
2240 // before encrypting so the HTTP job will still start.
2241 host_resolver_.set_synchronous_mode(true);
2242 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2243 "");
zhongyi6b5a3892016-03-12 04:46:202244
2245 CreateSession();
2246 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272247 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202248
bnc691fda62016-08-12 00:43:162249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202250 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362251 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202253
2254 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522255 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012256 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202257
2258 // Check whether this transaction is correctly marked as received a go-away
2259 // because of migrating port.
2260 NetErrorDetails details;
2261 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162262 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202263 EXPECT_TRUE(details.quic_port_migration_detected);
2264}
2265
Zhongyi Shia6b68d112018-09-24 07:49:032266// This test verifies that a new QUIC connection will be attempted on the
2267// alternate network if the original QUIC connection fails with idle timeout
2268// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2269// alternate network as well, QUIC is marked as broken and the brokenness will
2270// not expire when default network changes.
2271TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2272 SetUpTestForRetryConnectionOnAlternateNetwork();
2273
2274 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032275 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032276
2277 // The request will initially go out over QUIC.
2278 MockQuicData quic_data;
2279 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2280 int packet_num = 1;
2281 quic_data.AddWrite(SYNCHRONOUS,
2282 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2283 // Retranmit the handshake messages.
2284 quic_data.AddWrite(SYNCHRONOUS,
2285 client_maker_.MakeDummyCHLOPacket(packet_num++));
2286 quic_data.AddWrite(SYNCHRONOUS,
2287 client_maker_.MakeDummyCHLOPacket(packet_num++));
2288 quic_data.AddWrite(SYNCHRONOUS,
2289 client_maker_.MakeDummyCHLOPacket(packet_num++));
2290 quic_data.AddWrite(SYNCHRONOUS,
2291 client_maker_.MakeDummyCHLOPacket(packet_num++));
2292 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562293 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032294 quic_data.AddWrite(SYNCHRONOUS,
2295 client_maker_.MakeDummyCHLOPacket(packet_num++));
2296 }
2297 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2298 quic_data.AddWrite(SYNCHRONOUS,
2299 client_maker_.MakeConnectionClosePacket(
2300 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2301 "No recent network activity."));
2302 quic_data.AddSocketDataToFactory(&socket_factory_);
2303
2304 // Add successful TCP data so that TCP job will succeed.
2305 MockWrite http_writes[] = {
2306 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2307 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2308 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2309
2310 MockRead http_reads[] = {
2311 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2312 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2313 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2314 SequencedSocketData http_data(http_reads, http_writes);
2315 socket_factory_.AddSocketDataProvider(&http_data);
2316 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2317
2318 // Add data for the second QUIC connection to fail.
2319 MockQuicData quic_data2;
2320 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2321 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2322 quic_data2.AddSocketDataToFactory(&socket_factory_);
2323
2324 // Resolve the host resolution synchronously.
2325 host_resolver_.set_synchronous_mode(true);
2326 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2327 "");
Zhongyi Shia6b68d112018-09-24 07:49:032328
2329 CreateSession();
2330 session_->quic_stream_factory()->set_require_confirmation(true);
2331 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032332 QuicStreamFactoryPeer::SetAlarmFactory(
2333 session_->quic_stream_factory(),
2334 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2335 &clock_));
2336 // Add alternate protocol mapping to race QUIC and TCP.
2337 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2338 // peer.
2339 AddQuicAlternateProtocolMapping(
2340 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2341
2342 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2343 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362344 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2346
2347 // Pump the message loop to get the request started.
2348 // Request will be served with TCP job.
2349 base::RunLoop().RunUntilIdle();
2350 EXPECT_THAT(callback.WaitForResult(), IsOk());
2351 CheckResponseData(&trans, "TCP succeeds");
2352
2353 // Fire the retransmission alarm, from this point, connection will idle
2354 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062355 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182356 quic_fix_time_of_first_packet_sent_after_receiving)) {
2357 quic_task_runner_->RunNextTask();
2358 }
Zhongyi Shia6b68d112018-09-24 07:49:032359 // Fast forward to idle timeout the original connection. A new connection will
2360 // be kicked off on the alternate network.
2361 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2362 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2363 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2364
2365 // Run the message loop to execute posted tasks, which will report job status.
2366 base::RunLoop().RunUntilIdle();
2367
2368 // Verify that QUIC is marked as broken.
2369 ExpectBrokenAlternateProtocolMapping();
2370
2371 // Deliver a message to notify the new network becomes default, the brokenness
2372 // will not expire as QUIC is broken on both networks.
2373 scoped_mock_change_notifier_->mock_network_change_notifier()
2374 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2375 ExpectBrokenAlternateProtocolMapping();
2376
2377 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2378 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2379}
2380
2381// This test verifies that a new QUIC connection will be attempted on the
2382// alternate network if the original QUIC connection fails with idle timeout
2383// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2384// alternate network, QUIC is marked as broken. The brokenness will expire when
2385// the default network changes.
2386TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2387 SetUpTestForRetryConnectionOnAlternateNetwork();
2388
2389 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032390 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032391
2392 // The request will initially go out over QUIC.
2393 MockQuicData quic_data;
2394 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2395 int packet_num = 1;
2396 quic_data.AddWrite(SYNCHRONOUS,
2397 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2398 // Retranmit the handshake messages.
2399 quic_data.AddWrite(SYNCHRONOUS,
2400 client_maker_.MakeDummyCHLOPacket(packet_num++));
2401 quic_data.AddWrite(SYNCHRONOUS,
2402 client_maker_.MakeDummyCHLOPacket(packet_num++));
2403 quic_data.AddWrite(SYNCHRONOUS,
2404 client_maker_.MakeDummyCHLOPacket(packet_num++));
2405 quic_data.AddWrite(SYNCHRONOUS,
2406 client_maker_.MakeDummyCHLOPacket(packet_num++));
2407 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562408 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032409 quic_data.AddWrite(SYNCHRONOUS,
2410 client_maker_.MakeDummyCHLOPacket(packet_num++));
2411 }
2412 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2413 quic_data.AddWrite(SYNCHRONOUS,
2414 client_maker_.MakeConnectionClosePacket(
2415 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2416 "No recent network activity."));
2417 quic_data.AddSocketDataToFactory(&socket_factory_);
2418
2419 // Add successful TCP data so that TCP job will succeed.
2420 MockWrite http_writes[] = {
2421 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2422 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2423 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2424
2425 MockRead http_reads[] = {
2426 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2427 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2428 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2429 SequencedSocketData http_data(http_reads, http_writes);
2430 socket_factory_.AddSocketDataProvider(&http_data);
2431 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2432
2433 // Quic connection will be retried on the alternate network after the initial
2434 // one fails on the default network.
2435 MockQuicData quic_data2;
2436 quic::QuicStreamOffset header_stream_offset = 0;
2437 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2438 quic_data2.AddWrite(SYNCHRONOUS,
2439 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2440
2441 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2442 quic_data2.AddWrite(SYNCHRONOUS,
2443 ConstructInitialSettingsPacket(2, &header_stream_offset));
2444 quic_data2.AddSocketDataToFactory(&socket_factory_);
2445
2446 // Resolve the host resolution synchronously.
2447 host_resolver_.set_synchronous_mode(true);
2448 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2449 "");
Zhongyi Shia6b68d112018-09-24 07:49:032450
2451 CreateSession();
2452 session_->quic_stream_factory()->set_require_confirmation(true);
2453 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032454 QuicStreamFactoryPeer::SetAlarmFactory(
2455 session_->quic_stream_factory(),
2456 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2457 &clock_));
2458 // Add alternate protocol mapping to race QUIC and TCP.
2459 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2460 // peer.
2461 AddQuicAlternateProtocolMapping(
2462 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2463
2464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2465 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362466 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2468
2469 // Pump the message loop to get the request started.
2470 // Request will be served with TCP job.
2471 base::RunLoop().RunUntilIdle();
2472 EXPECT_THAT(callback.WaitForResult(), IsOk());
2473 CheckResponseData(&trans, "TCP succeeds");
2474
2475 // Fire the retransmission alarm, after which connection will idle
2476 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062477 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182478 quic_fix_time_of_first_packet_sent_after_receiving)) {
2479 quic_task_runner_->RunNextTask();
2480 }
Zhongyi Shia6b68d112018-09-24 07:49:032481 // Fast forward to idle timeout the original connection. A new connection will
2482 // be kicked off on the alternate network.
2483 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2484 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2485 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2486
2487 // The second connection hasn't finish handshake, verify that QUIC is not
2488 // marked as broken.
2489 ExpectQuicAlternateProtocolMapping();
2490 // Explicitly confirm the handshake on the second connection.
2491 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2492 quic::QuicSession::HANDSHAKE_CONFIRMED);
2493 // Run message loop to execute posted tasks, which will notify JoController
2494 // about the orphaned job status.
2495 base::RunLoop().RunUntilIdle();
2496
2497 // Verify that QUIC is marked as broken.
2498 ExpectBrokenAlternateProtocolMapping();
2499
2500 // Deliver a message to notify the new network becomes default, the previous
2501 // brokenness will be clear as the brokenness is bond with old default
2502 // network.
2503 scoped_mock_change_notifier_->mock_network_change_notifier()
2504 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2505 ExpectQuicAlternateProtocolMapping();
2506
2507 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2508 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2509}
2510
2511// This test verifies that a new QUIC connection will be attempted on the
2512// alternate network if the original QUIC connection fails with idle timeout
2513// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2514// alternative network succeeds, QUIC is not marked as broken.
2515TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2516 SetUpTestForRetryConnectionOnAlternateNetwork();
2517
2518 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032519 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032520
2521 // The request will initially go out over QUIC.
2522 MockQuicData quic_data;
2523 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2524 int packet_num = 1;
2525 quic_data.AddWrite(SYNCHRONOUS,
2526 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2527 // Retranmit the handshake messages.
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 quic_data.AddWrite(SYNCHRONOUS,
2535 client_maker_.MakeDummyCHLOPacket(packet_num++));
2536 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2537 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562538 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032539 quic_data.AddWrite(SYNCHRONOUS,
2540 client_maker_.MakeDummyCHLOPacket(packet_num++));
2541 }
2542 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2543 quic_data.AddWrite(SYNCHRONOUS,
2544 client_maker_.MakeConnectionClosePacket(
2545 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2546 "No recent network activity."));
2547 quic_data.AddSocketDataToFactory(&socket_factory_);
2548
2549 // Add hanging TCP data so that TCP job will never succeeded.
2550 AddHangingNonAlternateProtocolSocketData();
2551
2552 // Quic connection will then be retried on the alternate network.
2553 MockQuicData quic_data2;
2554 quic::QuicStreamOffset header_stream_offset = 0;
2555 quic_data2.AddWrite(SYNCHRONOUS,
2556 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2557
Victor Vasiliev076657c2019-03-12 02:46:432558 const std::string body = "hello!";
2559 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412560
Zhongyi Shia6b68d112018-09-24 07:49:032561 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2562 quic_data2.AddWrite(SYNCHRONOUS,
2563 ConstructInitialSettingsPacket(2, &header_stream_offset));
2564 quic_data2.AddWrite(
2565 SYNCHRONOUS,
2566 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332567 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032568 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032569 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332570 ASYNC, ConstructServerResponseHeadersPacket(
2571 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2572 GetResponseHeaders("200 OK")));
2573 quic_data2.AddRead(
2574 ASYNC, ConstructServerDataPacket(
2575 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412576 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032577 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2578 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2579 quic_data2.AddSocketDataToFactory(&socket_factory_);
2580
2581 // Resolve the host resolution synchronously.
2582 host_resolver_.set_synchronous_mode(true);
2583 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2584 "");
Zhongyi Shia6b68d112018-09-24 07:49:032585
2586 CreateSession();
2587 session_->quic_stream_factory()->set_require_confirmation(true);
2588 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032589 QuicStreamFactoryPeer::SetAlarmFactory(
2590 session_->quic_stream_factory(),
2591 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2592 &clock_));
2593 // Add alternate protocol mapping to race QUIC and TCP.
2594 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2595 // peer.
2596 AddQuicAlternateProtocolMapping(
2597 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2598
2599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2600 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362601 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2603
2604 // Pump the message loop to get the request started.
2605 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062606 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182607 quic_fix_time_of_first_packet_sent_after_receiving)) {
2608 quic_task_runner_->RunNextTask();
2609 }
Zhongyi Shia6b68d112018-09-24 07:49:032610
2611 // Fast forward to idle timeout the original connection. A new connection will
2612 // be kicked off on the alternate network.
2613 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2614 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2615 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2616
2617 // Verify that QUIC is not marked as broken.
2618 ExpectQuicAlternateProtocolMapping();
2619 // Explicitly confirm the handshake on the second connection.
2620 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2621 quic::QuicSession::HANDSHAKE_CONFIRMED);
2622
2623 // Read the response.
2624 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412625 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032626 // Verify that QUIC is not marked as broken.
2627 ExpectQuicAlternateProtocolMapping();
2628
2629 // Deliver a message to notify the new network becomes default.
2630 scoped_mock_change_notifier_->mock_network_change_notifier()
2631 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2632 ExpectQuicAlternateProtocolMapping();
2633 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2634 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2635}
2636
rch9ecde09b2017-04-08 00:18:232637// Verify that if a QUIC connection times out, the QuicHttpStream will
2638// return QUIC_PROTOCOL_ERROR.
2639TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482640 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412641 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232642
2643 // The request will initially go out over QUIC.
2644 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522645 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132646 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232647 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2648
2649 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032650 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432651 quic_data.AddWrite(SYNCHRONOUS,
2652 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332653 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2654 true, priority, GetRequestHeaders("GET", "https", "/"),
2655 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232656
2657 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522658 quic::QuicStreamOffset settings_offset = header_stream_offset;
2659 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432660 quic_data.AddWrite(SYNCHRONOUS,
2661 client_maker_.MakeInitialSettingsPacketAndSaveData(
2662 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232663 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522664 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562665 SYNCHRONOUS,
2666 client_maker_.MakeDataPacket(
2667 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2668 true, false, 0, request_data));
2669 // TLP 2
2670 quic_data.AddWrite(
2671 SYNCHRONOUS,
2672 client_maker_.MakeDataPacket(
2673 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2674 true, false, settings_offset, settings_data));
2675 // RTO 1
2676 quic_data.AddWrite(
2677 SYNCHRONOUS,
2678 client_maker_.MakeDataPacket(
2679 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2680 true, false, 0, request_data));
2681 quic_data.AddWrite(
2682 SYNCHRONOUS,
2683 client_maker_.MakeDataPacket(
2684 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2685 true, false, settings_offset, settings_data));
2686 // RTO 2
2687 quic_data.AddWrite(
2688 SYNCHRONOUS,
2689 client_maker_.MakeDataPacket(
2690 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2691 true, false, 0, request_data));
2692 quic_data.AddWrite(
2693 SYNCHRONOUS,
2694 client_maker_.MakeDataPacket(
2695 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2696 true, false, settings_offset, settings_data));
2697 // RTO 3
2698 quic_data.AddWrite(
2699 SYNCHRONOUS,
2700 client_maker_.MakeDataPacket(
2701 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2702 true, false, 0, request_data));
2703 quic_data.AddWrite(
2704 SYNCHRONOUS,
2705 client_maker_.MakeDataPacket(
2706 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2707 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232708
Zhongyi Shi32f2fd02018-04-16 18:23:432709 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522710 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432711 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222712
rch9ecde09b2017-04-08 00:18:232713 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2714 quic_data.AddRead(ASYNC, OK);
2715 quic_data.AddSocketDataToFactory(&socket_factory_);
2716
2717 // In order for a new QUIC session to be established via alternate-protocol
2718 // without racing an HTTP connection, we need the host resolution to happen
2719 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2720 // connection to the the server, in this test we require confirmation
2721 // before encrypting so the HTTP job will still start.
2722 host_resolver_.set_synchronous_mode(true);
2723 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2724 "");
rch9ecde09b2017-04-08 00:18:232725
2726 CreateSession();
2727 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
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.
rch9ecde09b2017-04-08 00:18:232855 QuicStreamFactoryPeer::SetAlarmFactory(
2856 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192857 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552858 &clock_));
rch9ecde09b2017-04-08 00:18:232859
Ryan Hamilton9835e662018-08-02 05:36:272860 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232861
2862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2863 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362864 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2866
2867 // Pump the message loop to get the request started.
2868 base::RunLoop().RunUntilIdle();
2869 // Explicitly confirm the handshake.
2870 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522871 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232872
2873 // Run the QUIC session to completion.
2874 quic_task_runner_->RunUntilIdle();
2875
2876 ExpectQuicAlternateProtocolMapping();
2877 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2878 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2879}
2880
2881// Verify that if a QUIC connection RTOs, while there are no active streams
2882// QUIC will not be marked as broken.
2883TEST_P(QuicNetworkTransactionTest,
2884 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522885 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232886
2887 // The request will initially go out over QUIC.
2888 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522889 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132890 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232891 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2892
2893 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032894 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432895 quic_data.AddWrite(SYNCHRONOUS,
2896 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332897 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2898 true, priority, GetRequestHeaders("GET", "https", "/"),
2899 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232900
2901 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522902 quic::QuicStreamOffset settings_offset = header_stream_offset;
2903 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432904 quic_data.AddWrite(SYNCHRONOUS,
2905 client_maker_.MakeInitialSettingsPacketAndSaveData(
2906 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232907
Fan Yang32c5a112018-12-10 20:06:332908 quic_data.AddWrite(SYNCHRONOUS,
2909 client_maker_.MakeRstPacket(
2910 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2911 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232912 // TLP 1
Nick Harper23290b82019-05-02 00:02:562913 quic_data.AddWrite(
2914 SYNCHRONOUS,
2915 client_maker_.MakeDataPacket(
2916 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2917 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232918 // TLP 2
Nick Harper23290b82019-05-02 00:02:562919 quic_data.AddWrite(
2920 SYNCHRONOUS,
2921 client_maker_.MakeDataPacket(
2922 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2923 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232924 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332925 quic_data.AddWrite(SYNCHRONOUS,
2926 client_maker_.MakeRstPacket(
2927 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2928 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:562929 quic_data.AddWrite(
2930 SYNCHRONOUS,
2931 client_maker_.MakeDataPacket(
2932 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2933 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232934 // RTO 2
Nick Harper23290b82019-05-02 00:02:562935 quic_data.AddWrite(
2936 SYNCHRONOUS,
2937 client_maker_.MakeDataPacket(
2938 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2939 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332940 quic_data.AddWrite(SYNCHRONOUS,
2941 client_maker_.MakeRstPacket(
2942 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2943 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232944 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522945 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562946 SYNCHRONOUS,
2947 client_maker_.MakeDataPacket(
2948 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2949 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:092950 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562951 SYNCHRONOUS,
2952 client_maker_.MakeDataPacket(
2953 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2954 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232955 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432956 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332957 SYNCHRONOUS, client_maker_.MakeRstPacket(
2958 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2959 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522960 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562961 SYNCHRONOUS,
2962 client_maker_.MakeDataPacket(
2963 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2964 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232965 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432966 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522967 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432968 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232969
2970 quic_data.AddRead(ASYNC, OK);
2971 quic_data.AddSocketDataToFactory(&socket_factory_);
2972
2973 // In order for a new QUIC session to be established via alternate-protocol
2974 // without racing an HTTP connection, we need the host resolution to happen
2975 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2976 // connection to the the server, in this test we require confirmation
2977 // before encrypting so the HTTP job will still start.
2978 host_resolver_.set_synchronous_mode(true);
2979 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2980 "");
rch9ecde09b2017-04-08 00:18:232981
2982 CreateSession();
2983 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232984 QuicStreamFactoryPeer::SetAlarmFactory(
2985 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192986 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552987 &clock_));
rch9ecde09b2017-04-08 00:18:232988
Ryan Hamilton9835e662018-08-02 05:36:272989 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232990
Jeremy Roman0579ed62017-08-29 15:56:192991 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232992 session_.get());
2993 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362994 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2996
2997 // Pump the message loop to get the request started.
2998 base::RunLoop().RunUntilIdle();
2999 // Explicitly confirm the handshake.
3000 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523001 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233002
3003 // Now cancel the request.
3004 trans.reset();
3005
3006 // Run the QUIC session to completion.
3007 quic_task_runner_->RunUntilIdle();
3008
3009 ExpectQuicAlternateProtocolMapping();
3010
3011 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3012}
3013
rch2f2991c2017-04-13 19:28:173014// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3015// the request fails with QUIC_PROTOCOL_ERROR.
3016TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:483017 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173018 // The request will initially go out over QUIC.
3019 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523020 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033021 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433022 quic_data.AddWrite(
3023 SYNCHRONOUS,
3024 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333025 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433026 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523027 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433028 quic_data.AddWrite(SYNCHRONOUS,
3029 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173030 // Peer sending data from an non-existing stream causes this end to raise
3031 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333032 quic_data.AddRead(
3033 ASYNC, ConstructServerRstPacket(
3034 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3035 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173036 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433037 quic_data.AddWrite(SYNCHRONOUS,
3038 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523039 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3040 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173041 quic_data.AddSocketDataToFactory(&socket_factory_);
3042
3043 // In order for a new QUIC session to be established via alternate-protocol
3044 // without racing an HTTP connection, we need the host resolution to happen
3045 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3046 // connection to the the server, in this test we require confirmation
3047 // before encrypting so the HTTP job will still start.
3048 host_resolver_.set_synchronous_mode(true);
3049 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3050 "");
rch2f2991c2017-04-13 19:28:173051
3052 CreateSession();
3053
Ryan Hamilton9835e662018-08-02 05:36:273054 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173055
3056 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3057 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363058 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3060
3061 // Pump the message loop to get the request started.
3062 base::RunLoop().RunUntilIdle();
3063 // Explicitly confirm the handshake.
3064 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523065 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173066
3067 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3068
3069 // Run the QUIC session to completion.
3070 base::RunLoop().RunUntilIdle();
3071 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3072 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3073
3074 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3075 ExpectQuicAlternateProtocolMapping();
3076 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3077}
3078
rch9ecde09b2017-04-08 00:18:233079// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3080// connection times out, then QUIC will be marked as broken and the request
3081// retried over TCP.
3082TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413083 session_params_.mark_quic_broken_when_network_blackholes = true;
3084 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233085
3086 // The request will initially go out over QUIC.
3087 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523088 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133089 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233090 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3091
3092 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033093 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433094 quic_data.AddWrite(SYNCHRONOUS,
3095 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333096 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3097 true, priority, GetRequestHeaders("GET", "https", "/"),
3098 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233099
3100 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523101 quic::QuicStreamOffset settings_offset = header_stream_offset;
3102 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433103 quic_data.AddWrite(SYNCHRONOUS,
3104 client_maker_.MakeInitialSettingsPacketAndSaveData(
3105 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233106 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523107 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563108 SYNCHRONOUS,
3109 client_maker_.MakeDataPacket(
3110 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3111 true, false, 0, request_data));
3112 // TLP 2
3113 quic_data.AddWrite(
3114 SYNCHRONOUS,
3115 client_maker_.MakeDataPacket(
3116 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3117 true, false, settings_offset, settings_data));
3118 // RTO 1
3119 quic_data.AddWrite(
3120 SYNCHRONOUS,
3121 client_maker_.MakeDataPacket(
3122 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3123 true, false, 0, request_data));
3124 quic_data.AddWrite(
3125 SYNCHRONOUS,
3126 client_maker_.MakeDataPacket(
3127 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3128 true, false, settings_offset, settings_data));
3129 // RTO 2
3130 quic_data.AddWrite(
3131 SYNCHRONOUS,
3132 client_maker_.MakeDataPacket(
3133 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3134 true, false, 0, request_data));
3135 quic_data.AddWrite(
3136 SYNCHRONOUS,
3137 client_maker_.MakeDataPacket(
3138 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3139 true, false, settings_offset, settings_data));
3140 // RTO 3
3141 quic_data.AddWrite(
3142 SYNCHRONOUS,
3143 client_maker_.MakeDataPacket(
3144 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3145 true, false, 0, request_data));
3146 quic_data.AddWrite(
3147 SYNCHRONOUS,
3148 client_maker_.MakeDataPacket(
3149 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3150 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233151
Zhongyi Shi32f2fd02018-04-16 18:23:433152 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523153 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433154 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223155
rch9ecde09b2017-04-08 00:18:233156 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3157 quic_data.AddRead(ASYNC, OK);
3158 quic_data.AddSocketDataToFactory(&socket_factory_);
3159
3160 // After that fails, it will be resent via TCP.
3161 MockWrite http_writes[] = {
3162 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3163 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3164 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3165
3166 MockRead http_reads[] = {
3167 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3168 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3169 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013170 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233171 socket_factory_.AddSocketDataProvider(&http_data);
3172 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3173
3174 // In order for a new QUIC session to be established via alternate-protocol
3175 // without racing an HTTP connection, we need the host resolution to happen
3176 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3177 // connection to the the server, in this test we require confirmation
3178 // before encrypting so the HTTP job will still start.
3179 host_resolver_.set_synchronous_mode(true);
3180 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3181 "");
rch9ecde09b2017-04-08 00:18:233182
3183 CreateSession();
3184 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233185 QuicStreamFactoryPeer::SetAlarmFactory(
3186 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193187 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553188 &clock_));
rch9ecde09b2017-04-08 00:18:233189
Ryan Hamilton9835e662018-08-02 05:36:273190 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233191
3192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3193 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363194 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3196
3197 // Pump the message loop to get the request started.
3198 base::RunLoop().RunUntilIdle();
3199 // Explicitly confirm the handshake.
3200 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523201 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233202
3203 // Run the QUIC session to completion.
3204 quic_task_runner_->RunUntilIdle();
3205 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3206
3207 // Let the transaction proceed which will result in QUIC being marked
3208 // as broken and the request falling back to TCP.
3209 EXPECT_THAT(callback.WaitForResult(), IsOk());
3210
3211 ExpectBrokenAlternateProtocolMapping();
3212 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3213 ASSERT_FALSE(http_data.AllReadDataConsumed());
3214
3215 // Read the response body over TCP.
3216 CheckResponseData(&trans, "hello world");
3217 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3218 ASSERT_TRUE(http_data.AllReadDataConsumed());
3219}
3220
rch2f2991c2017-04-13 19:28:173221// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3222// connection times out, then QUIC will be marked as broken and the request
3223// retried over TCP.
3224TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413225 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173226
3227 // The request will initially go out over QUIC.
3228 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523229 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133230 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173231 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3232
3233 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033234 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433235 quic_data.AddWrite(SYNCHRONOUS,
3236 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333237 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3238 true, priority, GetRequestHeaders("GET", "https", "/"),
3239 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173240
3241 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523242 quic::QuicStreamOffset settings_offset = header_stream_offset;
3243 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433244 quic_data.AddWrite(SYNCHRONOUS,
3245 client_maker_.MakeInitialSettingsPacketAndSaveData(
3246 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173247 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523248 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563249 SYNCHRONOUS,
3250 client_maker_.MakeDataPacket(
3251 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3252 true, false, 0, request_data));
3253 // TLP 2
3254 quic_data.AddWrite(
3255 SYNCHRONOUS,
3256 client_maker_.MakeDataPacket(
3257 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3258 true, false, settings_offset, settings_data));
3259 // RTO 1
3260 quic_data.AddWrite(
3261 SYNCHRONOUS,
3262 client_maker_.MakeDataPacket(
3263 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3264 true, false, 0, request_data));
3265 quic_data.AddWrite(
3266 SYNCHRONOUS,
3267 client_maker_.MakeDataPacket(
3268 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3269 true, false, settings_offset, settings_data));
3270 // RTO 2
3271 quic_data.AddWrite(
3272 SYNCHRONOUS,
3273 client_maker_.MakeDataPacket(
3274 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3275 true, false, 0, request_data));
3276 quic_data.AddWrite(
3277 SYNCHRONOUS,
3278 client_maker_.MakeDataPacket(
3279 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3280 true, false, settings_offset, settings_data));
3281 // RTO 3
3282 quic_data.AddWrite(
3283 SYNCHRONOUS,
3284 client_maker_.MakeDataPacket(
3285 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3286 true, false, 0, request_data));
3287 quic_data.AddWrite(
3288 SYNCHRONOUS,
3289 client_maker_.MakeDataPacket(
3290 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3291 true, false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173292
Zhongyi Shi32f2fd02018-04-16 18:23:433293 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523294 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433295 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223296
rch2f2991c2017-04-13 19:28:173297 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3298 quic_data.AddRead(ASYNC, OK);
3299 quic_data.AddSocketDataToFactory(&socket_factory_);
3300
3301 // After that fails, it will be resent via TCP.
3302 MockWrite http_writes[] = {
3303 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3304 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3305 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3306
3307 MockRead http_reads[] = {
3308 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3309 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3310 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013311 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173312 socket_factory_.AddSocketDataProvider(&http_data);
3313 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3314
3315 // In order for a new QUIC session to be established via alternate-protocol
3316 // without racing an HTTP connection, we need the host resolution to happen
3317 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3318 // connection to the the server, in this test we require confirmation
3319 // before encrypting so the HTTP job will still start.
3320 host_resolver_.set_synchronous_mode(true);
3321 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3322 "");
rch2f2991c2017-04-13 19:28:173323
3324 CreateSession();
3325 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173326 QuicStreamFactoryPeer::SetAlarmFactory(
3327 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193328 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553329 &clock_));
rch2f2991c2017-04-13 19:28:173330
Ryan Hamilton9835e662018-08-02 05:36:273331 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173332
3333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3334 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363335 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173336 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3337
3338 // Pump the message loop to get the request started.
3339 base::RunLoop().RunUntilIdle();
3340 // Explicitly confirm the handshake.
3341 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523342 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173343
3344 // Run the QUIC session to completion.
3345 quic_task_runner_->RunUntilIdle();
3346 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3347
3348 ExpectQuicAlternateProtocolMapping();
3349
3350 // Let the transaction proceed which will result in QUIC being marked
3351 // as broken and the request falling back to TCP.
3352 EXPECT_THAT(callback.WaitForResult(), IsOk());
3353
3354 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3355 ASSERT_FALSE(http_data.AllReadDataConsumed());
3356
3357 // Read the response body over TCP.
3358 CheckResponseData(&trans, "hello world");
3359 ExpectBrokenAlternateProtocolMapping();
3360 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3361 ASSERT_TRUE(http_data.AllReadDataConsumed());
3362}
3363
rch9ecde09b2017-04-08 00:18:233364// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3365// connection times out, then QUIC will be marked as broken but the request
3366// will not be retried over TCP.
3367TEST_P(QuicNetworkTransactionTest,
3368 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413369 session_params_.mark_quic_broken_when_network_blackholes = true;
3370 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233371
3372 // The request will initially go out over QUIC.
3373 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523374 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133375 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233376 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3377
3378 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033379 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433380 quic_data.AddWrite(SYNCHRONOUS,
3381 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333382 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3383 true, priority, GetRequestHeaders("GET", "https", "/"),
3384 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233385
3386 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523387 quic::QuicStreamOffset settings_offset = header_stream_offset;
3388 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433389 quic_data.AddWrite(SYNCHRONOUS,
3390 client_maker_.MakeInitialSettingsPacketAndSaveData(
3391 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233392
Zhongyi Shi32f2fd02018-04-16 18:23:433393 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333394 1, GetNthClientInitiatedBidirectionalStreamId(0),
3395 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433396 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523397 quic_data.AddWrite(
3398 SYNCHRONOUS,
3399 ConstructClientAckPacket(3, 1, 1, 1,
3400 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233401
3402 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523403 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563404 SYNCHRONOUS,
3405 client_maker_.MakeDataPacket(
3406 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3407 false, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233408 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093409 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563410 SYNCHRONOUS,
3411 client_maker_.MakeDataPacket(
3412 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3413 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233414 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523415 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563416 SYNCHRONOUS,
3417 client_maker_.MakeDataPacket(
3418 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3419 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093420 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563421 SYNCHRONOUS,
3422 client_maker_.MakeDataPacket(
3423 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3424 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233425 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523426 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563427 SYNCHRONOUS,
3428 client_maker_.MakeDataPacket(
3429 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3430 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093431 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563432 SYNCHRONOUS,
3433 client_maker_.MakeDataPacket(
3434 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3435 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233436 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523437 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563438 SYNCHRONOUS,
3439 client_maker_.MakeDataPacket(
3440 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3441 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093442 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563443 SYNCHRONOUS,
3444 client_maker_.MakeDataPacket(
3445 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3446 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233447
Michael Warres112212822018-12-26 17:51:063448 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183449 quic_fix_time_of_first_packet_sent_after_receiving)) {
3450 quic_data.AddWrite(
3451 SYNCHRONOUS,
3452 client_maker_.MakeAckAndConnectionClosePacket(
3453 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3454 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3455
3456 } else {
3457 quic_data.AddWrite(
3458 SYNCHRONOUS,
3459 client_maker_.MakeAckAndConnectionClosePacket(
3460 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3461 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3462 }
Fan Yang928f1632017-12-14 18:55:223463
rch9ecde09b2017-04-08 00:18:233464 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3465 quic_data.AddRead(ASYNC, OK);
3466 quic_data.AddSocketDataToFactory(&socket_factory_);
3467
3468 // In order for a new QUIC session to be established via alternate-protocol
3469 // without racing an HTTP connection, we need the host resolution to happen
3470 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3471 // connection to the the server, in this test we require confirmation
3472 // before encrypting so the HTTP job will still start.
3473 host_resolver_.set_synchronous_mode(true);
3474 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3475 "");
rch9ecde09b2017-04-08 00:18:233476
3477 CreateSession();
3478 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233479 QuicStreamFactoryPeer::SetAlarmFactory(
3480 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193481 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553482 &clock_));
rch9ecde09b2017-04-08 00:18:233483
Ryan Hamilton9835e662018-08-02 05:36:273484 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233485
3486 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3487 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363488 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3490
3491 // Pump the message loop to get the request started.
3492 base::RunLoop().RunUntilIdle();
3493 // Explicitly confirm the handshake.
3494 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523495 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233496
3497 // Pump the message loop to get the request started.
3498 base::RunLoop().RunUntilIdle();
3499
3500 // Run the QUIC session to completion.
3501 quic_task_runner_->RunUntilIdle();
3502 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3503
3504 // Let the transaction proceed which will result in QUIC being marked
3505 // as broken and the request falling back to TCP.
3506 EXPECT_THAT(callback.WaitForResult(), IsOk());
3507
3508 ExpectBrokenAlternateProtocolMapping();
3509 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3510
3511 std::string response_data;
3512 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3513 IsError(ERR_QUIC_PROTOCOL_ERROR));
3514}
3515
3516// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3517// connection RTOs, then QUIC will be marked as broken and the request retried
3518// over TCP.
3519TEST_P(QuicNetworkTransactionTest,
3520 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413521 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523522 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233523
3524 // The request will initially go out over QUIC.
3525 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523526 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133527 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233528 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3529
3530 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033531 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433532 quic_data.AddWrite(SYNCHRONOUS,
3533 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333534 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3535 true, priority, GetRequestHeaders("GET", "https", "/"),
3536 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233537
3538 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523539 quic::QuicStreamOffset settings_offset = header_stream_offset;
3540 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433541 quic_data.AddWrite(SYNCHRONOUS,
3542 client_maker_.MakeInitialSettingsPacketAndSaveData(
3543 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233544 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523545 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563546 SYNCHRONOUS,
3547 client_maker_.MakeDataPacket(
3548 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3549 true, false, 0, request_data));
3550 // TLP 2
3551 quic_data.AddWrite(
3552 SYNCHRONOUS,
3553 client_maker_.MakeDataPacket(
3554 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3555 true, false, settings_offset, settings_data));
3556 // RTO 1
3557 quic_data.AddWrite(
3558 SYNCHRONOUS,
3559 client_maker_.MakeDataPacket(
3560 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3561 true, false, 0, request_data));
3562 quic_data.AddWrite(
3563 SYNCHRONOUS,
3564 client_maker_.MakeDataPacket(
3565 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3566 true, false, settings_offset, settings_data));
3567 // RTO 2
3568 quic_data.AddWrite(
3569 SYNCHRONOUS,
3570 client_maker_.MakeDataPacket(
3571 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3572 true, false, 0, request_data));
3573 quic_data.AddWrite(
3574 SYNCHRONOUS,
3575 client_maker_.MakeDataPacket(
3576 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3577 true, false, settings_offset, settings_data));
3578 // RTO 3
3579 quic_data.AddWrite(
3580 SYNCHRONOUS,
3581 client_maker_.MakeDataPacket(
3582 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3583 true, false, 0, request_data));
3584 quic_data.AddWrite(
3585 SYNCHRONOUS,
3586 client_maker_.MakeDataPacket(
3587 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3588 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233589 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523590 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563591 SYNCHRONOUS,
3592 client_maker_.MakeDataPacket(
3593 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3594 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093595 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563596 SYNCHRONOUS,
3597 client_maker_.MakeDataPacket(
3598 12, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3599 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233600
Zhongyi Shi32f2fd02018-04-16 18:23:433601 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523602 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433603 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233604
3605 quic_data.AddRead(ASYNC, OK);
3606 quic_data.AddSocketDataToFactory(&socket_factory_);
3607
3608 // After that fails, it will be resent via TCP.
3609 MockWrite http_writes[] = {
3610 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3611 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3612 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3613
3614 MockRead http_reads[] = {
3615 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3616 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3617 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013618 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233619 socket_factory_.AddSocketDataProvider(&http_data);
3620 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3621
3622 // In order for a new QUIC session to be established via alternate-protocol
3623 // without racing an HTTP connection, we need the host resolution to happen
3624 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3625 // connection to the the server, in this test we require confirmation
3626 // before encrypting so the HTTP job will still start.
3627 host_resolver_.set_synchronous_mode(true);
3628 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3629 "");
rch9ecde09b2017-04-08 00:18:233630
3631 CreateSession();
3632 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233633 QuicStreamFactoryPeer::SetAlarmFactory(
3634 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193635 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553636 &clock_));
rch9ecde09b2017-04-08 00:18:233637
Ryan Hamilton9835e662018-08-02 05:36:273638 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233639
3640 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3641 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363642 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233643 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3644
3645 // Pump the message loop to get the request started.
3646 base::RunLoop().RunUntilIdle();
3647 // Explicitly confirm the handshake.
3648 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523649 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233650
3651 // Run the QUIC session to completion.
3652 quic_task_runner_->RunUntilIdle();
3653 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3654
3655 // Let the transaction proceed which will result in QUIC being marked
3656 // as broken and the request falling back to TCP.
3657 EXPECT_THAT(callback.WaitForResult(), IsOk());
3658
3659 ExpectBrokenAlternateProtocolMapping();
3660 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3661 ASSERT_FALSE(http_data.AllReadDataConsumed());
3662
3663 // Read the response body over TCP.
3664 CheckResponseData(&trans, "hello world");
3665 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3666 ASSERT_TRUE(http_data.AllReadDataConsumed());
3667}
3668
3669// Verify that if a QUIC connection RTOs, while there are no active streams
3670// QUIC will be marked as broken.
3671TEST_P(QuicNetworkTransactionTest,
3672 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413673 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523674 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233675
3676 // The request will initially go out over QUIC.
3677 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523678 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133679 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233680 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3681
3682 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033683 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433684 quic_data.AddWrite(SYNCHRONOUS,
3685 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333686 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3687 true, priority, GetRequestHeaders("GET", "https", "/"),
3688 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233689
3690 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523691 quic::QuicStreamOffset settings_offset = header_stream_offset;
3692 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433693 quic_data.AddWrite(SYNCHRONOUS,
3694 client_maker_.MakeInitialSettingsPacketAndSaveData(
3695 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233696
Fan Yang32c5a112018-12-10 20:06:333697 quic_data.AddWrite(SYNCHRONOUS,
3698 client_maker_.MakeRstPacket(
3699 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3700 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233701 // TLP 1
Nick Harper23290b82019-05-02 00:02:563702 quic_data.AddWrite(
3703 SYNCHRONOUS,
3704 client_maker_.MakeDataPacket(
3705 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3706 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233707 // TLP 2
Nick Harper23290b82019-05-02 00:02:563708 quic_data.AddWrite(
3709 SYNCHRONOUS,
3710 client_maker_.MakeDataPacket(
3711 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3712 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233713 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333714 quic_data.AddWrite(SYNCHRONOUS,
3715 client_maker_.MakeRstPacket(
3716 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3717 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:563718 quic_data.AddWrite(
3719 SYNCHRONOUS,
3720 client_maker_.MakeDataPacket(
3721 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3722 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233723 // RTO 2
Nick Harper23290b82019-05-02 00:02:563724 quic_data.AddWrite(
3725 SYNCHRONOUS,
3726 client_maker_.MakeDataPacket(
3727 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3728 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333729 quic_data.AddWrite(SYNCHRONOUS,
3730 client_maker_.MakeRstPacket(
3731 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3732 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233733 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523734 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563735 SYNCHRONOUS,
3736 client_maker_.MakeDataPacket(
3737 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3738 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093739 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563740 SYNCHRONOUS,
3741 client_maker_.MakeDataPacket(
3742 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3743 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233744 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433745 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333746 SYNCHRONOUS, client_maker_.MakeRstPacket(
3747 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3748 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523749 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563750 SYNCHRONOUS,
3751 client_maker_.MakeDataPacket(
3752 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3753 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233754 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433755 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523756 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433757 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233758
3759 quic_data.AddRead(ASYNC, OK);
3760 quic_data.AddSocketDataToFactory(&socket_factory_);
3761
3762 // In order for a new QUIC session to be established via alternate-protocol
3763 // without racing an HTTP connection, we need the host resolution to happen
3764 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3765 // connection to the the server, in this test we require confirmation
3766 // before encrypting so the HTTP job will still start.
3767 host_resolver_.set_synchronous_mode(true);
3768 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3769 "");
rch9ecde09b2017-04-08 00:18:233770
3771 CreateSession();
3772 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233773 QuicStreamFactoryPeer::SetAlarmFactory(
3774 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193775 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553776 &clock_));
rch9ecde09b2017-04-08 00:18:233777
Ryan Hamilton9835e662018-08-02 05:36:273778 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233779
Jeremy Roman0579ed62017-08-29 15:56:193780 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233781 session_.get());
3782 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363783 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233784 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3785
3786 // Pump the message loop to get the request started.
3787 base::RunLoop().RunUntilIdle();
3788 // Explicitly confirm the handshake.
3789 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523790 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233791
3792 // Now cancel the request.
3793 trans.reset();
3794
3795 // Run the QUIC session to completion.
3796 quic_task_runner_->RunUntilIdle();
3797
3798 ExpectBrokenAlternateProtocolMapping();
3799
3800 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3801}
3802
rch2f2991c2017-04-13 19:28:173803// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3804// protocol error occurs after the handshake is confirmed, the request
3805// retried over TCP and the QUIC will be marked as broken.
3806TEST_P(QuicNetworkTransactionTest,
3807 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413808 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173809
3810 // The request will initially go out over QUIC.
3811 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523812 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033813 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433814 quic_data.AddWrite(
3815 SYNCHRONOUS,
3816 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333817 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433818 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523819 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433820 quic_data.AddWrite(SYNCHRONOUS,
3821 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173822 // Peer sending data from an non-existing stream causes this end to raise
3823 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333824 quic_data.AddRead(
3825 ASYNC, ConstructServerRstPacket(
3826 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3827 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173828 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433829 quic_data.AddWrite(SYNCHRONOUS,
3830 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523831 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3832 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173833 quic_data.AddSocketDataToFactory(&socket_factory_);
3834
3835 // After that fails, it will be resent via TCP.
3836 MockWrite http_writes[] = {
3837 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3838 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3839 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3840
3841 MockRead http_reads[] = {
3842 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3843 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3844 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013845 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173846 socket_factory_.AddSocketDataProvider(&http_data);
3847 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3848
3849 // In order for a new QUIC session to be established via alternate-protocol
3850 // without racing an HTTP connection, we need the host resolution to happen
3851 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3852 // connection to the the server, in this test we require confirmation
3853 // before encrypting so the HTTP job will still start.
3854 host_resolver_.set_synchronous_mode(true);
3855 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3856 "");
rch2f2991c2017-04-13 19:28:173857
3858 CreateSession();
3859
Ryan Hamilton9835e662018-08-02 05:36:273860 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173861
3862 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3863 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363864 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3866
3867 // Pump the message loop to get the request started.
3868 base::RunLoop().RunUntilIdle();
3869 // Explicitly confirm the handshake.
3870 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523871 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173872
3873 // Run the QUIC session to completion.
3874 base::RunLoop().RunUntilIdle();
3875 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3876
3877 ExpectQuicAlternateProtocolMapping();
3878
3879 // Let the transaction proceed which will result in QUIC being marked
3880 // as broken and the request falling back to TCP.
3881 EXPECT_THAT(callback.WaitForResult(), IsOk());
3882
3883 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3884 ASSERT_FALSE(http_data.AllReadDataConsumed());
3885
3886 // Read the response body over TCP.
3887 CheckResponseData(&trans, "hello world");
3888 ExpectBrokenAlternateProtocolMapping();
3889 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3890 ASSERT_TRUE(http_data.AllReadDataConsumed());
3891}
3892
rch30943ee2017-06-12 21:28:443893// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3894// request is reset from, then QUIC will be marked as broken and the request
3895// retried over TCP.
3896TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443897 // The request will initially go out over QUIC.
3898 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523899 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133900 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443901 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3902
3903 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033904 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433905 quic_data.AddWrite(SYNCHRONOUS,
3906 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333907 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3908 true, priority, GetRequestHeaders("GET", "https", "/"),
3909 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443910
3911 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523912 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3913 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433914 quic_data.AddWrite(SYNCHRONOUS,
3915 client_maker_.MakeInitialSettingsPacketAndSaveData(
3916 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443917
Fan Yang32c5a112018-12-10 20:06:333918 quic_data.AddRead(ASYNC,
3919 ConstructServerRstPacket(
3920 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3921 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443922
3923 quic_data.AddRead(ASYNC, OK);
3924 quic_data.AddSocketDataToFactory(&socket_factory_);
3925
3926 // After that fails, it will be resent via TCP.
3927 MockWrite http_writes[] = {
3928 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3929 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3930 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3931
3932 MockRead http_reads[] = {
3933 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3934 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3935 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013936 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443937 socket_factory_.AddSocketDataProvider(&http_data);
3938 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3939
3940 // In order for a new QUIC session to be established via alternate-protocol
3941 // without racing an HTTP connection, we need the host resolution to happen
3942 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3943 // connection to the the server, in this test we require confirmation
3944 // before encrypting so the HTTP job will still start.
3945 host_resolver_.set_synchronous_mode(true);
3946 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3947 "");
rch30943ee2017-06-12 21:28:443948
3949 CreateSession();
3950
Ryan Hamilton9835e662018-08-02 05:36:273951 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443952
3953 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3954 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363955 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443956 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3957
3958 // Pump the message loop to get the request started.
3959 base::RunLoop().RunUntilIdle();
3960 // Explicitly confirm the handshake.
3961 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523962 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443963
3964 // Run the QUIC session to completion.
3965 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3966
3967 ExpectQuicAlternateProtocolMapping();
3968
3969 // Let the transaction proceed which will result in QUIC being marked
3970 // as broken and the request falling back to TCP.
3971 EXPECT_THAT(callback.WaitForResult(), IsOk());
3972
3973 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3974 ASSERT_FALSE(http_data.AllReadDataConsumed());
3975
3976 // Read the response body over TCP.
3977 CheckResponseData(&trans, "hello world");
3978 ExpectBrokenAlternateProtocolMapping();
3979 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3980 ASSERT_TRUE(http_data.AllReadDataConsumed());
3981}
3982
Ryan Hamilton6c2a2a82017-12-15 02:06:283983// Verify that when an origin has two alt-svc advertisements, one local and one
3984// remote, that when the local is broken the request will go over QUIC via
3985// the remote Alt-Svc.
3986// This is a regression test for crbug/825646.
3987TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3988 session_params_.quic_allow_remote_alt_svc = true;
3989
3990 GURL origin1 = request_.url; // mail.example.org
3991 GURL origin2("https://www.example.org/");
3992 ASSERT_NE(origin1.host(), origin2.host());
3993
3994 scoped_refptr<X509Certificate> cert(
3995 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243996 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3997 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283998
3999 ProofVerifyDetailsChromium verify_details;
4000 verify_details.cert_verify_result.verified_cert = cert;
4001 verify_details.cert_verify_result.is_issued_by_known_root = true;
4002 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4003
4004 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524005 quic::QuicStreamOffset request_header_offset(0);
4006 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:284007 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434008 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4009 mock_quic_data.AddWrite(
4010 SYNCHRONOUS,
4011 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334012 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434013 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4014 mock_quic_data.AddRead(
4015 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334016 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434017 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434018 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434019 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334020 ASYNC, ConstructServerDataPacket(
4021 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414022 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434023 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284024 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4025 mock_quic_data.AddRead(ASYNC, 0); // EOF
4026
4027 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4028 MockQuicData mock_quic_data2;
4029 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4030 AddHangingNonAlternateProtocolSocketData();
4031
4032 CreateSession();
4033
4034 // Set up alternative service for |origin1|.
4035 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4036 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4037 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4038 AlternativeServiceInfoVector alternative_services;
4039 alternative_services.push_back(
4040 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4041 local_alternative, expiration,
4042 session_->params().quic_supported_versions));
4043 alternative_services.push_back(
4044 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4045 remote_alternative, expiration,
4046 session_->params().quic_supported_versions));
4047 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4048 alternative_services);
4049
4050 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4051
4052 SendRequestAndExpectQuicResponse("hello!");
4053}
4054
rch30943ee2017-06-12 21:28:444055// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4056// request is reset from, then QUIC will be marked as broken and the request
4057// retried over TCP. Then, subsequent requests will go over a new QUIC
4058// connection instead of going back to the broken QUIC connection.
4059// This is a regression tests for crbug/731303.
4060TEST_P(QuicNetworkTransactionTest,
4061 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344062 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444063
4064 GURL origin1 = request_.url;
4065 GURL origin2("https://www.example.org/");
4066 ASSERT_NE(origin1.host(), origin2.host());
4067
4068 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524069 quic::QuicStreamOffset request_header_offset(0);
4070 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444071
4072 scoped_refptr<X509Certificate> cert(
4073 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244074 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4075 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444076
4077 ProofVerifyDetailsChromium verify_details;
4078 verify_details.cert_verify_result.verified_cert = cert;
4079 verify_details.cert_verify_result.is_issued_by_known_root = true;
4080 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4081
4082 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434083 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444084 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434085 mock_quic_data.AddWrite(
4086 SYNCHRONOUS,
4087 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334088 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434089 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4090 mock_quic_data.AddRead(
4091 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334092 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434093 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434094 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434095 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334096 ASYNC, ConstructServerDataPacket(
4097 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414098 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434099 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444100
4101 // Second request will go over the pooled QUIC connection, but will be
4102 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054103 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174104 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4105 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054106 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174107 QuicTestPacketMaker server_maker2(
4108 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4109 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434110 mock_quic_data.AddWrite(
4111 SYNCHRONOUS,
4112 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334113 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434114 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334115 GetNthClientInitiatedBidirectionalStreamId(0),
4116 &request_header_offset));
4117 mock_quic_data.AddRead(
4118 ASYNC, ConstructServerRstPacket(
4119 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4120 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444121 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4122 mock_quic_data.AddRead(ASYNC, 0); // EOF
4123
4124 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4125
4126 // After that fails, it will be resent via TCP.
4127 MockWrite http_writes[] = {
4128 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4129 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4130 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4131
4132 MockRead http_reads[] = {
4133 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4134 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4135 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014136 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444137 socket_factory_.AddSocketDataProvider(&http_data);
4138 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4139
Ryan Hamilton6c2a2a82017-12-15 02:06:284140 // Then the next request to the second origin will be sent over TCP.
4141 socket_factory_.AddSocketDataProvider(&http_data);
4142 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444143
4144 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564145 QuicStreamFactoryPeer::SetAlarmFactory(
4146 session_->quic_stream_factory(),
4147 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4148 &clock_));
rch30943ee2017-06-12 21:28:444149
4150 // Set up alternative service for |origin1|.
4151 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244152 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214153 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244154 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444155 supported_versions_);
rch30943ee2017-06-12 21:28:444156
4157 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244158 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214159 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244160 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444161 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344162
rch30943ee2017-06-12 21:28:444163 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524164 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444165 SendRequestAndExpectQuicResponse("hello!");
4166
4167 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524168 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444169 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4170 request_.url = origin2;
4171 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284172 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244173 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284174 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244175 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444176
4177 // The third request should use a new QUIC connection, not the broken
4178 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284179 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444180}
4181
bnc8be55ebb2015-10-30 14:12:074182TEST_P(QuicNetworkTransactionTest,
4183 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564184 std::string altsvc_header =
4185 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4186 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074187 MockRead http_reads[] = {
4188 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4189 MockRead("hello world"),
4190 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4191 MockRead(ASYNC, OK)};
4192
Ryan Sleevib8d7ea02018-05-07 20:01:014193 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074194 socket_factory_.AddSocketDataProvider(&http_data);
4195 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4196 socket_factory_.AddSocketDataProvider(&http_data);
4197 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4198
rch3f4b8452016-02-23 16:59:324199 CreateSession();
bnc8be55ebb2015-10-30 14:12:074200
4201 SendRequestAndExpectHttpResponse("hello world");
4202 SendRequestAndExpectHttpResponse("hello world");
4203}
4204
Xida Chen9bfe0b62018-04-24 19:52:214205// When multiple alternative services are advertised, HttpStreamFactory should
4206// select the alternative service which uses existing QUIC session if available.
4207// If no existing QUIC session can be used, use the first alternative service
4208// from the list.
zhongyi32569c62016-01-08 02:54:304209TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344210 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524211 MockRead http_reads[] = {
4212 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294213 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524214 MockRead("hello world"),
4215 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4216 MockRead(ASYNC, OK)};
4217
Ryan Sleevib8d7ea02018-05-07 20:01:014218 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524219 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084220 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564221 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524222
Ryan Hamilton8d9ee76e2018-05-29 23:52:524223 quic::QuicStreamOffset request_header_offset = 0;
4224 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304225 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294226 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304227 // alternative service list.
bncc958faa2015-07-31 18:14:524228 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364229 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434230 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4231 mock_quic_data.AddWrite(
4232 SYNCHRONOUS,
4233 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334234 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434235 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304236
4237 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294238 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4239 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434240 mock_quic_data.AddRead(
4241 ASYNC,
4242 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334243 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434244 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434245 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434246 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334247 ASYNC, ConstructServerDataPacket(
4248 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414249 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434250 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304251
4252 // Second QUIC request data.
4253 // Connection pooling, using existing session, no need to include version
4254 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584255 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334256 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4257 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4258 true, GetRequestHeaders("GET", "https", "/"),
4259 GetNthClientInitiatedBidirectionalStreamId(0),
4260 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434261 mock_quic_data.AddRead(
4262 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334263 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434264 GetResponseHeaders("200 OK"), &response_header_offset));
4265 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334266 ASYNC, ConstructServerDataPacket(
4267 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414268 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434269 mock_quic_data.AddWrite(
4270 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524271 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594272 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524273
4274 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4275
rtennetib8e80fb2016-05-16 00:12:094276 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324277 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564278 QuicStreamFactoryPeer::SetAlarmFactory(
4279 session_->quic_stream_factory(),
4280 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4281 &clock_));
bncc958faa2015-07-31 18:14:524282
4283 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304284
bnc359ed2a2016-04-29 20:43:454285 SendRequestAndExpectQuicResponse("hello!");
4286 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304287}
4288
tbansal6490783c2016-09-20 17:55:274289// Check that an existing QUIC connection to an alternative proxy server is
4290// used.
4291TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4292 base::HistogramTester histogram_tester;
4293
Ryan Hamilton8d9ee76e2018-05-29 23:52:524294 quic::QuicStreamOffset request_header_offset = 0;
4295 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274296 // First QUIC request data.
4297 // Open a session to foo.example.org:443 using the first entry of the
4298 // alternative service list.
4299 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364300 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434301 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4302 mock_quic_data.AddWrite(
4303 SYNCHRONOUS,
4304 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334305 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434306 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274307
4308 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434309 mock_quic_data.AddRead(
4310 ASYNC,
4311 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334312 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434313 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434314 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434315 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334316 ASYNC, ConstructServerDataPacket(
4317 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414318 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434319 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274320
4321 // Second QUIC request data.
4322 // Connection pooling, using existing session, no need to include version
4323 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274324 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334325 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4326 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4327 true, GetRequestHeaders("GET", "http", "/"),
4328 GetNthClientInitiatedBidirectionalStreamId(0),
4329 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434330 mock_quic_data.AddRead(
4331 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334332 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434333 GetResponseHeaders("200 OK"), &response_header_offset));
4334 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334335 ASYNC, ConstructServerDataPacket(
4336 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414337 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434338 mock_quic_data.AddWrite(
4339 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274340 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4341 mock_quic_data.AddRead(ASYNC, 0); // EOF
4342
4343 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4344
4345 AddHangingNonAlternateProtocolSocketData();
4346
4347 TestProxyDelegate test_proxy_delegate;
4348
Lily Houghton8c2f97d2018-01-22 05:06:594349 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494350 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274351
4352 test_proxy_delegate.set_alternative_proxy_server(
4353 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524354 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274355
4356 request_.url = GURL("http://mail.example.org/");
4357
4358 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564359 QuicStreamFactoryPeer::SetAlarmFactory(
4360 session_->quic_stream_factory(),
4361 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4362 &clock_));
tbansal6490783c2016-09-20 17:55:274363
4364 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4365 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4366 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4367 1);
4368
4369 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4370 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4371 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4372 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4373 1);
4374}
4375
Ryan Hamilton8d9ee76e2018-05-29 23:52:524376// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454377// even if alternative service destination is different.
4378TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344379 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304380 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524381 quic::QuicStreamOffset request_header_offset(0);
4382 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454383
rch5cb522462017-04-25 20:18:364384 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434385 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454386 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434387 mock_quic_data.AddWrite(
4388 SYNCHRONOUS,
4389 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334390 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434391 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4392 mock_quic_data.AddRead(
4393 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334394 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434395 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434396 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434397 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334398 ASYNC, ConstructServerDataPacket(
4399 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414400 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434401 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304402
bnc359ed2a2016-04-29 20:43:454403 // Second request.
alyssar2adf3ac2016-05-03 17:12:584404 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334405 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4406 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4407 true, GetRequestHeaders("GET", "https", "/"),
4408 GetNthClientInitiatedBidirectionalStreamId(0),
4409 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434410 mock_quic_data.AddRead(
4411 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334412 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434413 GetResponseHeaders("200 OK"), &response_header_offset));
4414 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334415 ASYNC, ConstructServerDataPacket(
4416 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414417 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434418 mock_quic_data.AddWrite(
4419 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304420 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4421 mock_quic_data.AddRead(ASYNC, 0); // EOF
4422
4423 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454424
4425 AddHangingNonAlternateProtocolSocketData();
4426 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304427
rch3f4b8452016-02-23 16:59:324428 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564429 QuicStreamFactoryPeer::SetAlarmFactory(
4430 session_->quic_stream_factory(),
4431 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4432 &clock_));
zhongyi32569c62016-01-08 02:54:304433
bnc359ed2a2016-04-29 20:43:454434 const char destination1[] = "first.example.com";
4435 const char destination2[] = "second.example.com";
4436
4437 // Set up alternative service entry to destination1.
4438 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214439 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454440 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214441 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444442 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454443 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524444 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454445 SendRequestAndExpectQuicResponse("hello!");
4446
4447 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214448 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214449 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444450 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524451 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454452 // even though alternative service destination is different.
4453 SendRequestAndExpectQuicResponse("hello!");
4454}
4455
4456// Pool to existing session with matching destination and matching certificate
4457// even if origin is different, and even if the alternative service with
4458// matching destination is not the first one on the list.
4459TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344460 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454461 GURL origin1 = request_.url;
4462 GURL origin2("https://www.example.org/");
4463 ASSERT_NE(origin1.host(), origin2.host());
4464
4465 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524466 quic::QuicStreamOffset request_header_offset(0);
4467 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454468
rch5cb522462017-04-25 20:18:364469 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434470 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454471 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434472 mock_quic_data.AddWrite(
4473 SYNCHRONOUS,
4474 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334475 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434476 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4477 mock_quic_data.AddRead(
4478 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334479 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434480 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434481 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434482 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334483 ASYNC, ConstructServerDataPacket(
4484 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414485 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434486 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454487
4488 // Second request.
Yixin Wang079ad542018-01-11 04:06:054489 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174490 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4491 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054492 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174493 QuicTestPacketMaker server_maker2(
4494 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4495 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584496 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434497 SYNCHRONOUS,
4498 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334499 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434500 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334501 GetNthClientInitiatedBidirectionalStreamId(0),
4502 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434503 mock_quic_data.AddRead(
4504 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334505 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434506 GetResponseHeaders("200 OK"), &response_header_offset));
4507 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334508 ASYNC, ConstructServerDataPacket(
4509 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414510 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434511 mock_quic_data.AddWrite(
4512 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454513 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4514 mock_quic_data.AddRead(ASYNC, 0); // EOF
4515
4516 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4517
4518 AddHangingNonAlternateProtocolSocketData();
4519 AddHangingNonAlternateProtocolSocketData();
4520
4521 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564522 QuicStreamFactoryPeer::SetAlarmFactory(
4523 session_->quic_stream_factory(),
4524 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4525 &clock_));
bnc359ed2a2016-04-29 20:43:454526
4527 const char destination1[] = "first.example.com";
4528 const char destination2[] = "second.example.com";
4529
4530 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214531 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454532 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214533 http_server_properties_.SetQuicAlternativeService(
4534 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444535 supported_versions_);
bnc359ed2a2016-04-29 20:43:454536
4537 // Set up multiple alternative service entries for |origin2|,
4538 // the first one with a different destination as for |origin1|,
4539 // the second one with the same. The second one should be used,
4540 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214541 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454542 AlternativeServiceInfoVector alternative_services;
4543 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214544 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4545 alternative_service2, expiration,
4546 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454547 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214548 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4549 alternative_service1, expiration,
4550 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454551 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4552 alternative_services);
bnc359ed2a2016-04-29 20:43:454553 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524554 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454555 SendRequestAndExpectQuicResponse("hello!");
4556
4557 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524558 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454559 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584560
bnc359ed2a2016-04-29 20:43:454561 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304562}
4563
4564// Multiple origins have listed the same alternative services. When there's a
4565// existing QUIC session opened by a request to other origin,
4566// if the cert is valid, should select this QUIC session to make the request
4567// if this is also the first existing QUIC session.
4568TEST_P(QuicNetworkTransactionTest,
4569 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344570 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294571 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304572
rch9ae5b3b2016-02-11 00:36:294573 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304574 MockRead http_reads[] = {
4575 MockRead("HTTP/1.1 200 OK\r\n"),
4576 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294577 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304578 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4579 MockRead(ASYNC, OK)};
4580
Ryan Sleevib8d7ea02018-05-07 20:01:014581 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304582 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084583 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304584 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4585
4586 // HTTP data for request to mail.example.org.
4587 MockRead http_reads2[] = {
4588 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294589 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304590 MockRead("hello world from mail.example.org"),
4591 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4592 MockRead(ASYNC, OK)};
4593
Ryan Sleevib8d7ea02018-05-07 20:01:014594 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304595 socket_factory_.AddSocketDataProvider(&http_data2);
4596 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4597
Ryan Hamilton8d9ee76e2018-05-29 23:52:524598 quic::QuicStreamOffset request_header_offset = 0;
4599 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304600
Yixin Wang079ad542018-01-11 04:06:054601 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174602 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4603 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054604 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584605 server_maker_.set_hostname("www.example.org");
4606 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304607 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364608 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434609 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304610 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584611 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434612 SYNCHRONOUS,
4613 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334614 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434615 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4616
4617 mock_quic_data.AddRead(
4618 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334619 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434620 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434621 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334622 mock_quic_data.AddRead(
4623 ASYNC, ConstructServerDataPacket(
4624 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414625 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434626 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4627 // Second QUIC request data.
4628 mock_quic_data.AddWrite(
4629 SYNCHRONOUS,
4630 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334631 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434632 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334633 GetNthClientInitiatedBidirectionalStreamId(0),
4634 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434635 mock_quic_data.AddRead(
4636 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334637 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434638 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334639 mock_quic_data.AddRead(
4640 ASYNC, ConstructServerDataPacket(
4641 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414642 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434643 mock_quic_data.AddWrite(
4644 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304645 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4646 mock_quic_data.AddRead(ASYNC, 0); // EOF
4647
4648 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304649
rtennetib8e80fb2016-05-16 00:12:094650 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324651 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564652 QuicStreamFactoryPeer::SetAlarmFactory(
4653 session_->quic_stream_factory(),
4654 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4655 &clock_));
zhongyi32569c62016-01-08 02:54:304656
4657 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294658 request_.url = GURL("https://www.example.org/");
4659 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304660 request_.url = GURL("https://mail.example.org/");
4661 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4662
rch9ae5b3b2016-02-11 00:36:294663 // Open a QUIC session to mail.example.org:443 when making request
4664 // to mail.example.org.
4665 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454666 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304667
rch9ae5b3b2016-02-11 00:36:294668 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304669 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454670 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524671}
4672
4673TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524674 MockRead http_reads[] = {
4675 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564676 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524677 MockRead("hello world"),
4678 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4679 MockRead(ASYNC, OK)};
4680
Ryan Sleevib8d7ea02018-05-07 20:01:014681 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524682 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084683 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564684 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524685
rtennetib8e80fb2016-05-16 00:12:094686 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324687 CreateSession();
bncc958faa2015-07-31 18:14:524688
4689 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454690
4691 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344692 AlternativeServiceInfoVector alternative_service_info_vector =
4693 http_server_properties_.GetAlternativeServiceInfos(http_server);
4694 ASSERT_EQ(1u, alternative_service_info_vector.size());
4695 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544696 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344697 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4698 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4699 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524700}
4701
4702TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524703 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564704 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4705 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524706 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4707 MockRead(ASYNC, OK)};
4708
Ryan Sleevib8d7ea02018-05-07 20:01:014709 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524710 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084711 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564712 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524713
4714 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524715 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364716 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434717 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4718 mock_quic_data.AddWrite(
4719 SYNCHRONOUS,
4720 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334721 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434722 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434723 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334724 ASYNC, ConstructServerResponseHeadersPacket(
4725 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4726 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434727 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334728 mock_quic_data.AddRead(
4729 ASYNC, ConstructServerDataPacket(
4730 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414731 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434732 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524733 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4734 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524735
4736 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4737
rtennetib8e80fb2016-05-16 00:12:094738 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324739 CreateSession();
bncc958faa2015-07-31 18:14:524740
bnc3472afd2016-11-17 15:27:214741 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524742 HostPortPair::FromURL(request_.url));
4743 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4744 alternative_service);
4745 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4746 alternative_service));
4747
4748 SendRequestAndExpectHttpResponse("hello world");
4749 SendRequestAndExpectQuicResponse("hello!");
4750
mmenkee24011922015-12-17 22:12:594751 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524752
4753 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4754 alternative_service));
rchac7f35e2017-03-15 20:42:304755 EXPECT_NE(nullptr,
4756 http_server_properties_.GetServerNetworkStats(
4757 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524758}
4759
bncc958faa2015-07-31 18:14:524760TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524761 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564762 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4763 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524764 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4765 MockRead(ASYNC, OK)};
4766
Ryan Sleevib8d7ea02018-05-07 20:01:014767 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524768 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564769 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524770
4771 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524772 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364773 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434774 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4775 mock_quic_data.AddWrite(
4776 SYNCHRONOUS,
4777 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334778 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434779 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434780 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334781 ASYNC, ConstructServerResponseHeadersPacket(
4782 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4783 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434784 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334785 mock_quic_data.AddRead(
4786 ASYNC, ConstructServerDataPacket(
4787 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414788 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434789 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524790 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4791
4792 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4793
4794 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324795 CreateSession();
bncc958faa2015-07-31 18:14:524796
4797 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4798 SendRequestAndExpectHttpResponse("hello world");
4799}
4800
tbansalc3308d72016-08-27 10:25:044801// Tests that the connection to an HTTPS proxy is raced with an available
4802// alternative proxy server.
4803TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274804 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594805 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494806 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044807
4808 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524809 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364810 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434811 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4812 mock_quic_data.AddWrite(
4813 SYNCHRONOUS,
4814 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334815 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434816 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434817 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334818 ASYNC, ConstructServerResponseHeadersPacket(
4819 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4820 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434821 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334822 mock_quic_data.AddRead(
4823 ASYNC, ConstructServerDataPacket(
4824 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414825 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434826 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044827 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4828 mock_quic_data.AddRead(ASYNC, 0); // EOF
4829
4830 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4831
4832 // There is no need to set up main job, because no attempt will be made to
4833 // speak to the proxy over TCP.
4834 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044835 TestProxyDelegate test_proxy_delegate;
4836 const HostPortPair host_port_pair("mail.example.org", 443);
4837
4838 test_proxy_delegate.set_alternative_proxy_server(
4839 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524840 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044841 CreateSession();
4842 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4843
4844 // The main job needs to hang in order to guarantee that the alternative
4845 // proxy server job will "win".
4846 AddHangingNonAlternateProtocolSocketData();
4847
4848 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4849
4850 // Verify that the alternative proxy server is not marked as broken.
4851 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4852
4853 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594854 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274855
4856 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4857 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4858 1);
tbansalc3308d72016-08-27 10:25:044859}
4860
bnc1c196c6e2016-05-28 13:51:484861TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304862 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274863 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304864
4865 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564866 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294867 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564868 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304869
4870 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564871 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484872 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564873 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304874
Ryan Sleevib8d7ea02018-05-07 20:01:014875 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504876 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084877 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504878 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304879
4880 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454881 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304882 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454883 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304884 };
Ryan Sleevib8d7ea02018-05-07 20:01:014885 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504886 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304887
4888 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014889 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504890 socket_factory_.AddSocketDataProvider(&http_data2);
4891 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304892
bnc912a04b2016-04-20 14:19:504893 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304894
4895 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304896 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174897 ASSERT_TRUE(http_data.AllReadDataConsumed());
4898 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304899
4900 // Now run the second request in which the QUIC socket hangs,
4901 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304902 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454903 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304904
rch37de576c2015-05-17 20:28:174905 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4906 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454907 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304908}
4909
[email protected]1e960032013-12-20 19:00:204910TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204911 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524912 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:034913 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434914 mock_quic_data.AddWrite(
4915 SYNCHRONOUS,
4916 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334917 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434918 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434919 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334920 ASYNC, ConstructServerResponseHeadersPacket(
4921 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4922 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434923 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334924 mock_quic_data.AddRead(
4925 ASYNC, ConstructServerDataPacket(
4926 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414927 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434928 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504929 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594930 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484931
rcha5399e02015-04-21 19:32:044932 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484933
rtennetib8e80fb2016-05-16 00:12:094934 // The non-alternate protocol job needs to hang in order to guarantee that
4935 // the alternate-protocol job will "win".
4936 AddHangingNonAlternateProtocolSocketData();
4937
rch3f4b8452016-02-23 16:59:324938 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274939 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194940 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304941
4942 EXPECT_EQ(nullptr,
4943 http_server_properties_.GetServerNetworkStats(
4944 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484945}
4946
[email protected]1e960032013-12-20 19:00:204947TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204948 MockQuicData mock_quic_data;
Michael Warres167db3e2019-03-01 21:38:034949 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334950 mock_quic_data.AddWrite(
4951 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4952 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4953 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434954 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334955 ASYNC, ConstructServerResponseHeadersPacket(
4956 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4957 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434958 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334959 mock_quic_data.AddRead(
4960 ASYNC, ConstructServerDataPacket(
4961 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414962 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434963 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504964 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594965 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044966 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274967
4968 // In order for a new QUIC session to be established via alternate-protocol
4969 // without racing an HTTP connection, we need the host resolution to happen
4970 // synchronously.
4971 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294972 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564973 "");
[email protected]3a120a6b2013-06-25 01:08:274974
rtennetib8e80fb2016-05-16 00:12:094975 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324976 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274977 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274978 SendRequestAndExpectQuicResponse("hello!");
4979}
4980
[email protected]0fc924b2014-03-31 04:34:154981TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494982 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4983 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154984
4985 // Since we are using a proxy, the QUIC job will not succeed.
4986 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294987 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4988 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564989 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154990
4991 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564992 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484993 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564994 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154995
Ryan Sleevib8d7ea02018-05-07 20:01:014996 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154997 socket_factory_.AddSocketDataProvider(&http_data);
4998
4999 // In order for a new QUIC session to be established via alternate-protocol
5000 // without racing an HTTP connection, we need the host resolution to happen
5001 // synchronously.
5002 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295003 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565004 "");
[email protected]0fc924b2014-03-31 04:34:155005
rch9ae5b3b2016-02-11 00:36:295006 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325007 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275008 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155009 SendRequestAndExpectHttpResponse("hello world");
5010}
5011
[email protected]1e960032013-12-20 19:00:205012TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:205013 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525014 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365015 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435016 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5017 mock_quic_data.AddWrite(
5018 SYNCHRONOUS,
5019 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335020 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435021 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435022 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335023 ASYNC, ConstructServerResponseHeadersPacket(
5024 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5025 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435026 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335027 mock_quic_data.AddRead(
5028 ASYNC, ConstructServerDataPacket(
5029 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415030 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435031 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595032 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045033 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125034
rtennetib8e80fb2016-05-16 00:12:095035 // The non-alternate protocol job needs to hang in order to guarantee that
5036 // the alternate-protocol job will "win".
5037 AddHangingNonAlternateProtocolSocketData();
5038
[email protected]11c05872013-08-20 02:04:125039 // In order for a new QUIC session to be established via alternate-protocol
5040 // without racing an HTTP connection, we need the host resolution to happen
5041 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5042 // connection to the the server, in this test we require confirmation
5043 // before encrypting so the HTTP job will still start.
5044 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295045 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565046 "");
[email protected]11c05872013-08-20 02:04:125047
rch3f4b8452016-02-23 16:59:325048 CreateSession();
[email protected]11c05872013-08-20 02:04:125049 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275050 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125051
bnc691fda62016-08-12 00:43:165052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125053 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365054 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125056
5057 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525058 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015059 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505060
bnc691fda62016-08-12 00:43:165061 CheckWasQuicResponse(&trans);
5062 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125063}
5064
Steven Valdez58097ec32018-07-16 18:29:045065TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5066 MockQuicData mock_quic_data;
5067 quic::QuicStreamOffset client_header_stream_offset = 0;
5068 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035069 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045070 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335071 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5072 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5073 true, GetRequestHeaders("GET", "https", "/"),
5074 &client_header_stream_offset));
5075 mock_quic_data.AddRead(
5076 ASYNC,
5077 ConstructServerResponseHeadersPacket(
5078 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5079 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5080 mock_quic_data.AddWrite(SYNCHRONOUS,
5081 ConstructClientAckAndRstPacket(
5082 2, GetNthClientInitiatedBidirectionalStreamId(0),
5083 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045084
5085 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5086
5087 spdy::SpdySettingsIR settings_frame;
5088 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5089 quic::kDefaultMaxUncompressedHeaderSize);
5090 spdy::SpdySerializedFrame spdy_frame(
5091 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5092 mock_quic_data.AddWrite(
5093 SYNCHRONOUS,
5094 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565095 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5096 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045097 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5098 client_header_stream_offset += spdy_frame.size();
5099
5100 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335101 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5102 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5103 true, GetRequestHeaders("GET", "https", "/"),
5104 GetNthClientInitiatedBidirectionalStreamId(0),
5105 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045106 mock_quic_data.AddRead(
5107 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335108 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045109 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:435110 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045111 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335112 ASYNC, ConstructServerDataPacket(
5113 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415114 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045115 mock_quic_data.AddWrite(
5116 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5117 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5118 mock_quic_data.AddRead(ASYNC, 0); // EOF
5119
5120 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5121
5122 // In order for a new QUIC session to be established via alternate-protocol
5123 // without racing an HTTP connection, we need the host resolution to happen
5124 // synchronously.
5125 host_resolver_.set_synchronous_mode(true);
5126 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5127 "");
Steven Valdez58097ec32018-07-16 18:29:045128
5129 AddHangingNonAlternateProtocolSocketData();
5130 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275131 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565132 QuicStreamFactoryPeer::SetAlarmFactory(
5133 session_->quic_stream_factory(),
5134 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5135 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045136
5137 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5138 TestCompletionCallback callback;
5139 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5141
5142 // Confirm the handshake after the 425 Too Early.
5143 base::RunLoop().RunUntilIdle();
5144
5145 // The handshake hasn't been confirmed yet, so the retry should not have
5146 // succeeded.
5147 EXPECT_FALSE(callback.have_result());
5148
5149 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5150 quic::QuicSession::HANDSHAKE_CONFIRMED);
5151
5152 EXPECT_THAT(callback.WaitForResult(), IsOk());
5153 CheckWasQuicResponse(&trans);
5154 CheckResponseData(&trans, "hello!");
5155}
5156
5157TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5158 MockQuicData mock_quic_data;
5159 quic::QuicStreamOffset client_header_stream_offset = 0;
5160 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035161 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045162 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335163 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5164 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5165 true, GetRequestHeaders("GET", "https", "/"),
5166 &client_header_stream_offset));
5167 mock_quic_data.AddRead(
5168 ASYNC,
5169 ConstructServerResponseHeadersPacket(
5170 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5171 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5172 mock_quic_data.AddWrite(SYNCHRONOUS,
5173 ConstructClientAckAndRstPacket(
5174 2, GetNthClientInitiatedBidirectionalStreamId(0),
5175 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045176
5177 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5178
5179 spdy::SpdySettingsIR settings_frame;
5180 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5181 quic::kDefaultMaxUncompressedHeaderSize);
5182 spdy::SpdySerializedFrame spdy_frame(
5183 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5184 mock_quic_data.AddWrite(
5185 SYNCHRONOUS,
5186 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565187 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5188 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045189 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5190 client_header_stream_offset += spdy_frame.size();
5191
5192 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335193 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5194 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5195 true, GetRequestHeaders("GET", "https", "/"),
5196 GetNthClientInitiatedBidirectionalStreamId(0),
5197 &client_header_stream_offset));
5198 mock_quic_data.AddRead(
5199 ASYNC,
5200 ConstructServerResponseHeadersPacket(
5201 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5202 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5203 mock_quic_data.AddWrite(SYNCHRONOUS,
5204 ConstructClientAckAndRstPacket(
5205 5, GetNthClientInitiatedBidirectionalStreamId(1),
5206 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045207 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5208 mock_quic_data.AddRead(ASYNC, 0); // EOF
5209
5210 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5211
5212 // In order for a new QUIC session to be established via alternate-protocol
5213 // without racing an HTTP connection, we need the host resolution to happen
5214 // synchronously.
5215 host_resolver_.set_synchronous_mode(true);
5216 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5217 "");
Steven Valdez58097ec32018-07-16 18:29:045218
5219 AddHangingNonAlternateProtocolSocketData();
5220 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275221 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565222 QuicStreamFactoryPeer::SetAlarmFactory(
5223 session_->quic_stream_factory(),
5224 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5225 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045226
5227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5228 TestCompletionCallback callback;
5229 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5231
5232 // Confirm the handshake after the 425 Too Early.
5233 base::RunLoop().RunUntilIdle();
5234
5235 // The handshake hasn't been confirmed yet, so the retry should not have
5236 // succeeded.
5237 EXPECT_FALSE(callback.have_result());
5238
5239 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5240 quic::QuicSession::HANDSHAKE_CONFIRMED);
5241
5242 EXPECT_THAT(callback.WaitForResult(), IsOk());
5243 const HttpResponseInfo* response = trans.GetResponseInfo();
5244 ASSERT_TRUE(response != nullptr);
5245 ASSERT_TRUE(response->headers.get() != nullptr);
5246 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5247 EXPECT_TRUE(response->was_fetched_via_spdy);
5248 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565249 EXPECT_EQ(
5250 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5251 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045252}
5253
zhongyica364fbb2015-12-12 03:39:125254TEST_P(QuicNetworkTransactionTest,
5255 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485256 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125257 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525258 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365259 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435260 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5261 mock_quic_data.AddWrite(
5262 SYNCHRONOUS,
5263 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335264 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435265 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125266 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525267 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435268 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5270
5271 // The non-alternate protocol job needs to hang in order to guarantee that
5272 // the alternate-protocol job will "win".
5273 AddHangingNonAlternateProtocolSocketData();
5274
5275 // In order for a new QUIC session to be established via alternate-protocol
5276 // without racing an HTTP connection, we need the host resolution to happen
5277 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5278 // connection to the the server, in this test we require confirmation
5279 // before encrypting so the HTTP job will still start.
5280 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295281 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125282 "");
zhongyica364fbb2015-12-12 03:39:125283
rch3f4b8452016-02-23 16:59:325284 CreateSession();
zhongyica364fbb2015-12-12 03:39:125285 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275286 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125287
bnc691fda62016-08-12 00:43:165288 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125289 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365290 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015291 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125292
5293 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525294 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015295 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125296
5297 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525298 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125299
bnc691fda62016-08-12 00:43:165300 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125301 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525302 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5303 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125304}
5305
5306TEST_P(QuicNetworkTransactionTest,
5307 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485308 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125309 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525310 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365311 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435312 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5313 mock_quic_data.AddWrite(
5314 SYNCHRONOUS,
5315 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335316 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435317 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215318 // Peer sending data from an non-existing stream causes this end to raise
5319 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335320 mock_quic_data.AddRead(
5321 ASYNC, ConstructServerRstPacket(
5322 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5323 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215324 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525325 mock_quic_data.AddWrite(
5326 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5327 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5328 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125329 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5330
5331 // The non-alternate protocol job needs to hang in order to guarantee that
5332 // the alternate-protocol job will "win".
5333 AddHangingNonAlternateProtocolSocketData();
5334
5335 // In order for a new QUIC session to be established via alternate-protocol
5336 // without racing an HTTP connection, we need the host resolution to happen
5337 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5338 // connection to the the server, in this test we require confirmation
5339 // before encrypting so the HTTP job will still start.
5340 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295341 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125342 "");
zhongyica364fbb2015-12-12 03:39:125343
rch3f4b8452016-02-23 16:59:325344 CreateSession();
zhongyica364fbb2015-12-12 03:39:125345 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275346 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125347
bnc691fda62016-08-12 00:43:165348 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125349 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365350 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125352
5353 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525354 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015355 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125356 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525357 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125358
bnc691fda62016-08-12 00:43:165359 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525360 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125361}
5362
rchcd5f1c62016-06-23 02:43:485363TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5364 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525365 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365366 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435367 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5368 mock_quic_data.AddWrite(
5369 SYNCHRONOUS,
5370 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335371 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435372 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485373 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335374 mock_quic_data.AddRead(
5375 ASYNC, ConstructServerResponseHeadersPacket(
5376 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5377 GetResponseHeaders("200 OK")));
5378 mock_quic_data.AddRead(
5379 ASYNC, ConstructServerRstPacket(
5380 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5381 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435382 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485383 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5384 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5385
5386 // The non-alternate protocol job needs to hang in order to guarantee that
5387 // the alternate-protocol job will "win".
5388 AddHangingNonAlternateProtocolSocketData();
5389
5390 // In order for a new QUIC session to be established via alternate-protocol
5391 // without racing an HTTP connection, we need the host resolution to happen
5392 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5393 // connection to the the server, in this test we require confirmation
5394 // before encrypting so the HTTP job will still start.
5395 host_resolver_.set_synchronous_mode(true);
5396 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5397 "");
rchcd5f1c62016-06-23 02:43:485398
5399 CreateSession();
5400 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275401 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485402
bnc691fda62016-08-12 00:43:165403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485404 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365405 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015406 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485407
5408 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525409 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485410 // Read the headers.
robpercival214763f2016-07-01 23:27:015411 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485412
bnc691fda62016-08-12 00:43:165413 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485414 ASSERT_TRUE(response != nullptr);
5415 ASSERT_TRUE(response->headers.get() != nullptr);
5416 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5417 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525418 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565419 EXPECT_EQ(
5420 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5421 response->connection_info);
rchcd5f1c62016-06-23 02:43:485422
5423 std::string response_data;
bnc691fda62016-08-12 00:43:165424 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485425}
5426
5427TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485428 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485429 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525430 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365431 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435432 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5433 mock_quic_data.AddWrite(
5434 SYNCHRONOUS,
5435 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335436 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435437 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335438 mock_quic_data.AddRead(
5439 ASYNC, ConstructServerRstPacket(
5440 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5441 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485442 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5443 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5444
5445 // The non-alternate protocol job needs to hang in order to guarantee that
5446 // the alternate-protocol job will "win".
5447 AddHangingNonAlternateProtocolSocketData();
5448
5449 // In order for a new QUIC session to be established via alternate-protocol
5450 // without racing an HTTP connection, we need the host resolution to happen
5451 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5452 // connection to the the server, in this test we require confirmation
5453 // before encrypting so the HTTP job will still start.
5454 host_resolver_.set_synchronous_mode(true);
5455 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5456 "");
rchcd5f1c62016-06-23 02:43:485457
5458 CreateSession();
5459 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275460 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485461
bnc691fda62016-08-12 00:43:165462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485463 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365464 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015465 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485466
5467 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525468 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485469 // Read the headers.
robpercival214763f2016-07-01 23:27:015470 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485471}
5472
[email protected]1e960032013-12-20 19:00:205473TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305474 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525475 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585476 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305477 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505478 MockRead(ASYNC, close->data(), close->length()),
5479 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5480 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305481 };
Ryan Sleevib8d7ea02018-05-07 20:01:015482 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305483 socket_factory_.AddSocketDataProvider(&quic_data);
5484
5485 // Main job which will succeed even though the alternate job fails.
5486 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025487 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5488 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5489 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305490
Ryan Sleevib8d7ea02018-05-07 20:01:015491 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305492 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565493 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305494
rch3f4b8452016-02-23 16:59:325495 CreateSession();
David Schinazic8281052019-01-24 06:14:175496 AddQuicAlternateProtocolMapping(
5497 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195498 SendRequestAndExpectHttpResponse("hello from http");
5499 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305500}
5501
[email protected]1e960032013-12-20 19:00:205502TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595503 // Alternate-protocol job
5504 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025505 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595506 };
Ryan Sleevib8d7ea02018-05-07 20:01:015507 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595508 socket_factory_.AddSocketDataProvider(&quic_data);
5509
5510 // Main job which will succeed even though the alternate job fails.
5511 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025512 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5513 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5514 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595515
Ryan Sleevib8d7ea02018-05-07 20:01:015516 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595517 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565518 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595519
rch3f4b8452016-02-23 16:59:325520 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595521
Ryan Hamilton9835e662018-08-02 05:36:275522 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195523 SendRequestAndExpectHttpResponse("hello from http");
5524 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595525}
5526
[email protected]00c159f2014-05-21 22:38:165527TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535528 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165529 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025530 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165531 };
Ryan Sleevib8d7ea02018-05-07 20:01:015532 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165533 socket_factory_.AddSocketDataProvider(&quic_data);
5534
[email protected]eb71ab62014-05-23 07:57:535535 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165536 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025537 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165538 };
5539
Ryan Sleevib8d7ea02018-05-07 20:01:015540 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165541 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5542 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565543 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165544
rtennetib8e80fb2016-05-16 00:12:095545 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325546 CreateSession();
[email protected]00c159f2014-05-21 22:38:165547
Ryan Hamilton9835e662018-08-02 05:36:275548 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165550 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165551 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5553 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165554 ExpectQuicAlternateProtocolMapping();
5555}
5556
Zhongyi Shia0cef1082017-08-25 01:49:505557TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5558 // Tests that TCP job is delayed and QUIC job does not require confirmation
5559 // if QUIC was recently supported on the same IP on start.
5560
5561 // Set QUIC support on the last IP address, which is same with the local IP
5562 // address. Require confirmation mode will be turned off immediately when
5563 // local IP address is sorted out after we configure the UDP socket.
5564 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5565
5566 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525567 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035568 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435569 mock_quic_data.AddWrite(
5570 SYNCHRONOUS,
5571 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335572 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435573 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435574 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335575 ASYNC, ConstructServerResponseHeadersPacket(
5576 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5577 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435578 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335579 mock_quic_data.AddRead(
5580 ASYNC, ConstructServerDataPacket(
5581 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415582 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435583 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505584 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5585 mock_quic_data.AddRead(ASYNC, 0); // EOF
5586
5587 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5588 // No HTTP data is mocked as TCP job never starts in this case.
5589
5590 CreateSession();
5591 // QuicStreamFactory by default requires confirmation on construction.
5592 session_->quic_stream_factory()->set_require_confirmation(true);
5593
Ryan Hamilton9835e662018-08-02 05:36:275594 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505595
5596 // Stall host resolution so that QUIC job will not succeed synchronously.
5597 // Socket will not be configured immediately and QUIC support is not sorted
5598 // out, TCP job will still be delayed as server properties indicates QUIC
5599 // support on last IP address.
5600 host_resolver_.set_synchronous_mode(false);
5601
5602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5603 TestCompletionCallback callback;
5604 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5605 IsError(ERR_IO_PENDING));
5606 // Complete host resolution in next message loop so that QUIC job could
5607 // proceed.
5608 base::RunLoop().RunUntilIdle();
5609 EXPECT_THAT(callback.WaitForResult(), IsOk());
5610
5611 CheckWasQuicResponse(&trans);
5612 CheckResponseData(&trans, "hello!");
5613}
5614
5615TEST_P(QuicNetworkTransactionTest,
5616 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5617 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5618 // was recently supported on a different IP address on start.
5619
5620 // Set QUIC support on the last IP address, which is different with the local
5621 // IP address. Require confirmation mode will remain when local IP address is
5622 // sorted out after we configure the UDP socket.
5623 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5624
5625 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525626 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505627 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435628 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5629 mock_quic_data.AddWrite(
5630 SYNCHRONOUS,
5631 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335632 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435633 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435634 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335635 ASYNC, ConstructServerResponseHeadersPacket(
5636 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5637 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435638 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335639 mock_quic_data.AddRead(
5640 ASYNC, ConstructServerDataPacket(
5641 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415642 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435643 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505644 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5645 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5646 // No HTTP data is mocked as TCP job will be delayed and never starts.
5647
5648 CreateSession();
5649 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275650 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505651
5652 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5653 // Socket will not be configured immediately and QUIC support is not sorted
5654 // out, TCP job will still be delayed as server properties indicates QUIC
5655 // support on last IP address.
5656 host_resolver_.set_synchronous_mode(false);
5657
5658 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5659 TestCompletionCallback callback;
5660 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5661 IsError(ERR_IO_PENDING));
5662
5663 // Complete host resolution in next message loop so that QUIC job could
5664 // proceed.
5665 base::RunLoop().RunUntilIdle();
5666 // Explicitly confirm the handshake so that QUIC job could succeed.
5667 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525668 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505669 EXPECT_THAT(callback.WaitForResult(), IsOk());
5670
5671 CheckWasQuicResponse(&trans);
5672 CheckResponseData(&trans, "hello!");
5673}
5674
Ryan Hamilton75f197262017-08-17 14:00:075675TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5676 // Test that NetErrorDetails is correctly populated, even if the
5677 // handshake has not yet been confirmed and no stream has been created.
5678
5679 // QUIC job will pause. When resumed, it will fail.
5680 MockQuicData mock_quic_data;
5681 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5682 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5683 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5684
5685 // Main job will also fail.
5686 MockRead http_reads[] = {
5687 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5688 };
5689
Ryan Sleevib8d7ea02018-05-07 20:01:015690 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075691 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5692 socket_factory_.AddSocketDataProvider(&http_data);
5693 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5694
5695 AddHangingNonAlternateProtocolSocketData();
5696 CreateSession();
5697 // Require handshake confirmation to ensure that no QUIC streams are
5698 // created, and to ensure that the TCP job does not wait for the QUIC
5699 // job to fail before it starts.
5700 session_->quic_stream_factory()->set_require_confirmation(true);
5701
Ryan Hamilton9835e662018-08-02 05:36:275702 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5704 TestCompletionCallback callback;
5705 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5707 // Allow the TCP job to fail.
5708 base::RunLoop().RunUntilIdle();
5709 // Now let the QUIC job fail.
5710 mock_quic_data.Resume();
5711 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5712 ExpectQuicAlternateProtocolMapping();
5713 NetErrorDetails details;
5714 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525715 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075716}
5717
[email protected]1e960032013-12-20 19:00:205718TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455719 // Alternate-protocol job
5720 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025721 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455722 };
Ryan Sleevib8d7ea02018-05-07 20:01:015723 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455724 socket_factory_.AddSocketDataProvider(&quic_data);
5725
[email protected]c92c1b52014-05-31 04:16:065726 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015727 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065728 socket_factory_.AddSocketDataProvider(&quic_data2);
5729
[email protected]4d283b32013-10-17 12:57:275730 // Final job that will proceed when the QUIC job fails.
5731 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025732 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5733 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5734 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275735
Ryan Sleevib8d7ea02018-05-07 20:01:015736 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275737 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565738 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275739
rtennetiafccbc062016-05-16 18:21:145740 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325741 CreateSession();
[email protected]77c6c162013-08-17 02:57:455742
Ryan Hamilton9835e662018-08-02 05:36:275743 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455744
[email protected]4d283b32013-10-17 12:57:275745 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455746
5747 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275748
rch37de576c2015-05-17 20:28:175749 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5750 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455751}
5752
[email protected]93b31772014-06-19 08:03:355753TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035754 // Alternate-protocol job
5755 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595756 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035757 };
Ryan Sleevib8d7ea02018-05-07 20:01:015758 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035759 socket_factory_.AddSocketDataProvider(&quic_data);
5760
5761 // Main job that will proceed when the QUIC job fails.
5762 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025763 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5764 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5765 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035766
Ryan Sleevib8d7ea02018-05-07 20:01:015767 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035768 socket_factory_.AddSocketDataProvider(&http_data);
5769
rtennetib8e80fb2016-05-16 00:12:095770 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325771 CreateSession();
[email protected]65768442014-06-06 23:37:035772
Ryan Hamilton9835e662018-08-02 05:36:275773 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035774
5775 SendRequestAndExpectHttpResponse("hello from http");
5776}
5777
[email protected]eb71ab62014-05-23 07:57:535778TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335779 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015780 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495781 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335782 socket_factory_.AddSocketDataProvider(&quic_data);
5783
5784 // Main job which will succeed even though the alternate job fails.
5785 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025786 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5787 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5788 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335789
Ryan Sleevib8d7ea02018-05-07 20:01:015790 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335791 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565792 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335793
rch3f4b8452016-02-23 16:59:325794 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275795 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335796 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535797
5798 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335799}
5800
[email protected]4fee9672014-01-08 14:47:155801TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155802 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175803 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5804 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045805 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155806
5807 // When the QUIC connection fails, we will try the request again over HTTP.
5808 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485809 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565810 MockRead("hello world"),
5811 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5812 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155813
Ryan Sleevib8d7ea02018-05-07 20:01:015814 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155815 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565816 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155817
5818 // In order for a new QUIC session to be established via alternate-protocol
5819 // without racing an HTTP connection, we need the host resolution to happen
5820 // synchronously.
5821 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295822 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565823 "");
[email protected]4fee9672014-01-08 14:47:155824
rch3f4b8452016-02-23 16:59:325825 CreateSession();
David Schinazic8281052019-01-24 06:14:175826 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5827 AddQuicAlternateProtocolMapping(
5828 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155829 SendRequestAndExpectHttpResponse("hello world");
5830}
5831
tbansalc3308d72016-08-27 10:25:045832// For an alternative proxy that supports QUIC, test that the request is
5833// successfully fetched by the main job when the alternate proxy job encounters
5834// an error.
5835TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5836 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5837}
5838TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5839 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5840}
5841TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5842 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5843}
5844TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5845 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5846}
5847TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5848 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5849}
5850TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5851 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5852}
5853TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5854 TestAlternativeProxy(ERR_IO_PENDING);
5855}
5856TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5857 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5858}
5859
5860TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5861 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175862 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5863 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335864 mock_quic_data.AddWrite(
5865 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5866 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5867 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435868 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045869 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5870
5871 // When the QUIC connection fails, we will try the request again over HTTP.
5872 MockRead http_reads[] = {
5873 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5874 MockRead("hello world"),
5875 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5876 MockRead(ASYNC, OK)};
5877
Ryan Sleevib8d7ea02018-05-07 20:01:015878 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045879 socket_factory_.AddSocketDataProvider(&http_data);
5880 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5881
5882 TestProxyDelegate test_proxy_delegate;
5883 const HostPortPair host_port_pair("myproxy.org", 443);
5884 test_proxy_delegate.set_alternative_proxy_server(
5885 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5886 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5887
Ramin Halavatica8d5252018-03-12 05:33:495888 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5889 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525890 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045891 request_.url = GURL("http://mail.example.org/");
5892
5893 // In order for a new QUIC session to be established via alternate-protocol
5894 // without racing an HTTP connection, we need the host resolution to happen
5895 // synchronously.
5896 host_resolver_.set_synchronous_mode(true);
5897 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045898
5899 CreateSession();
David Schinazic8281052019-01-24 06:14:175900 crypto_client_stream_factory_.set_handshake_mode(
5901 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045902 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595903 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165904 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045905}
5906
bnc508835902015-05-12 20:10:295907TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585908 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385909 EXPECT_FALSE(
5910 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295911 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525912 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365913 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435914 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5915 mock_quic_data.AddWrite(
5916 SYNCHRONOUS,
5917 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335918 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435919 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435920 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335921 ASYNC, ConstructServerResponseHeadersPacket(
5922 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5923 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435924 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335925 mock_quic_data.AddRead(
5926 ASYNC, ConstructServerDataPacket(
5927 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415928 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435929 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505930 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295931 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5932
bncb07c05532015-05-14 19:07:205933 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095934 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325935 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275936 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295937 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385938 EXPECT_TRUE(
5939 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295940}
5941
zhongyi363c91c2017-03-23 23:16:085942// TODO(zhongyi): disabled this broken test as it was not testing the correct
5943// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5944TEST_P(QuicNetworkTransactionTest,
5945 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275946 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595947 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495948 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045949
5950 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045951
5952 test_proxy_delegate.set_alternative_proxy_server(
5953 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525954 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045955
5956 request_.url = GURL("http://mail.example.org/");
5957
5958 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5959 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015960 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045961 socket_factory_.AddSocketDataProvider(&socket_data);
5962
5963 // The non-alternate protocol job needs to hang in order to guarantee that
5964 // the alternate-protocol job will "win".
5965 AddHangingNonAlternateProtocolSocketData();
5966
5967 CreateSession();
5968 request_.method = "POST";
5969 ChunkedUploadDataStream upload_data(0);
5970 upload_data.AppendData("1", 1, true);
5971
5972 request_.upload_data_stream = &upload_data;
5973
5974 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5975 TestCompletionCallback callback;
5976 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5978 EXPECT_NE(OK, callback.WaitForResult());
5979
5980 // Verify that the alternative proxy server is not marked as broken.
5981 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5982
5983 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595984 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275985
5986 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5987 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5988 1);
tbansalc3308d72016-08-27 10:25:045989}
5990
rtenneti56977812016-01-15 19:26:565991TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415992 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575993 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565994
5995 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5996 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015997 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565998 socket_factory_.AddSocketDataProvider(&socket_data);
5999
rtennetib8e80fb2016-05-16 00:12:096000 // The non-alternate protocol job needs to hang in order to guarantee that
6001 // the alternate-protocol job will "win".
6002 AddHangingNonAlternateProtocolSocketData();
6003
rtenneti56977812016-01-15 19:26:566004 CreateSession();
6005 request_.method = "POST";
6006 ChunkedUploadDataStream upload_data(0);
6007 upload_data.AppendData("1", 1, true);
6008
6009 request_.upload_data_stream = &upload_data;
6010
bnc691fda62016-08-12 00:43:166011 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566012 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166013 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016014 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566015 EXPECT_NE(OK, callback.WaitForResult());
6016}
6017
rche11300ef2016-09-02 01:44:286018TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486019 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286020 ScopedMockNetworkChangeNotifier network_change_notifier;
6021 MockNetworkChangeNotifier* mock_ncn =
6022 network_change_notifier.mock_network_change_notifier();
6023 mock_ncn->ForceNetworkHandlesSupported();
6024 mock_ncn->SetConnectedNetworksList(
6025 {kDefaultNetworkForTests, kNewNetworkForTests});
6026
mmenke6ddfbea2017-05-31 21:48:416027 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286028 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316029 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286030
6031 MockQuicData socket_data;
6032 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526033 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436034 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336035 socket_data.AddWrite(
6036 SYNCHRONOUS,
6037 ConstructClientRequestHeadersPacket(
6038 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6039 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286040 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6041 socket_data.AddSocketDataToFactory(&socket_factory_);
6042
6043 MockQuicData socket_data2;
6044 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6045 socket_data2.AddSocketDataToFactory(&socket_factory_);
6046
6047 // The non-alternate protocol job needs to hang in order to guarantee that
6048 // the alternate-protocol job will "win".
6049 AddHangingNonAlternateProtocolSocketData();
6050
6051 CreateSession();
6052 request_.method = "POST";
6053 ChunkedUploadDataStream upload_data(0);
6054
6055 request_.upload_data_stream = &upload_data;
6056
rdsmith1d343be52016-10-21 20:37:506057 std::unique_ptr<HttpNetworkTransaction> trans(
6058 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286059 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506060 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6062
6063 base::RunLoop().RunUntilIdle();
6064 upload_data.AppendData("1", 1, true);
6065 base::RunLoop().RunUntilIdle();
6066
6067 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506068 trans.reset();
rche11300ef2016-09-02 01:44:286069 session_.reset();
6070}
6071
Ryan Hamilton4b3574532017-10-30 20:17:256072TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6073 session_params_.origins_to_force_quic_on.insert(
6074 HostPortPair::FromString("mail.example.org:443"));
6075
6076 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526077 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436078 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256079 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336080 socket_data.AddWrite(
6081 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6082 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6083 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436084 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336085 ASYNC, ConstructServerResponseHeadersPacket(
6086 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6087 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436088 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336089 socket_data.AddRead(
6090 ASYNC, ConstructServerDataPacket(
6091 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416092 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436093 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256094 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166095 socket_data.AddWrite(
6096 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6097 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6098 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256099
6100 socket_data.AddSocketDataToFactory(&socket_factory_);
6101
6102 CreateSession();
6103
6104 SendRequestAndExpectQuicResponse("hello!");
6105 session_.reset();
6106}
6107
6108TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6109 session_params_.origins_to_force_quic_on.insert(
6110 HostPortPair::FromString("mail.example.org:443"));
6111
6112 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526113 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436114 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256115 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336116 socket_data.AddWrite(
6117 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6118 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6119 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436120 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336121 ASYNC, ConstructServerResponseHeadersPacket(
6122 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6123 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436124 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336125 socket_data.AddRead(
6126 ASYNC, ConstructServerDataPacket(
6127 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416128 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436129 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256130 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166131 socket_data.AddWrite(
6132 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6133 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6134 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256135
6136 socket_data.AddSocketDataToFactory(&socket_factory_);
6137
6138 CreateSession();
6139
6140 SendRequestAndExpectQuicResponse("hello!");
6141 session_.reset();
6142}
6143
Ryan Hamilton9edcf1a2017-11-22 05:55:176144TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486145 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256146 session_params_.origins_to_force_quic_on.insert(
6147 HostPortPair::FromString("mail.example.org:443"));
6148
6149 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526150 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256151 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436152 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176153 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256154 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6155 }
6156 socket_data.AddSocketDataToFactory(&socket_factory_);
6157
6158 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176159 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176160 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6161 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256162
Ryan Hamilton8d9ee76e2018-05-29 23:52:526163 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6165 TestCompletionCallback callback;
6166 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6167 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176168 while (!callback.have_result()) {
6169 base::RunLoop().RunUntilIdle();
6170 quic_task_runner_->RunUntilIdle();
6171 }
6172 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256173 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176174 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6175 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6176 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526177 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6178 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256179}
6180
Ryan Hamilton9edcf1a2017-11-22 05:55:176181TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486182 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256183 session_params_.origins_to_force_quic_on.insert(
6184 HostPortPair::FromString("mail.example.org:443"));
6185
6186 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526187 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256188 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436189 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176190 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256191 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6192 }
6193 socket_data.AddSocketDataToFactory(&socket_factory_);
6194
6195 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176196 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176197 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6198 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256199
Ryan Hamilton8d9ee76e2018-05-29 23:52:526200 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6202 TestCompletionCallback callback;
6203 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6204 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176205 while (!callback.have_result()) {
6206 base::RunLoop().RunUntilIdle();
6207 quic_task_runner_->RunUntilIdle();
6208 }
6209 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256210 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176211 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6212 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6213 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526214 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6215 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256216}
6217
Cherie Shi7596de632018-02-22 07:28:186218TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486219 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186220 session_params_.origins_to_force_quic_on.insert(
6221 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436222 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526223 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6224 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186225
6226 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526227 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186228 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436229 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186230 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6231 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526232 socket_data.AddWrite(
6233 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6234 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186235 socket_data.AddSocketDataToFactory(&socket_factory_);
6236
6237 CreateSession();
6238
6239 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6240 TestCompletionCallback callback;
6241 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6243 base::RunLoop().RunUntilIdle();
6244 ASSERT_TRUE(callback.have_result());
6245 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6246 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6247 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6248}
6249
ckrasic769733c2016-06-30 00:42:136250// Adds coverage to catch regression such as https://crbug.com/622043
6251TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416252 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136253 HostPortPair::FromString("mail.example.org:443"));
6254
6255 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526256 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236257 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436258 mock_quic_data.AddWrite(
6259 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6260 &header_stream_offset));
6261 mock_quic_data.AddWrite(
6262 SYNCHRONOUS,
6263 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336264 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6265 true, true, GetRequestHeaders("GET", "https", "/"),
6266 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526267 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436268 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336269 ASYNC, ConstructServerPushPromisePacket(
6270 1, GetNthClientInitiatedBidirectionalStreamId(0),
6271 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6272 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6273 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576274 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566275 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336276 mock_quic_data.AddWrite(SYNCHRONOUS,
6277 ConstructClientPriorityPacket(
6278 client_packet_number++, false,
6279 GetNthServerInitiatedUnidirectionalStreamId(0),
6280 GetNthClientInitiatedBidirectionalStreamId(0),
6281 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576282 }
Zhongyi Shi32f2fd02018-04-16 18:23:436283 mock_quic_data.AddRead(
6284 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336285 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436286 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576287 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436288 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6289 mock_quic_data.AddRead(
6290 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336291 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6292 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436293 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436294 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336295 ASYNC, ConstructServerDataPacket(
6296 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416297 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576298 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436299 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436300 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436301 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336302 ASYNC, ConstructServerDataPacket(
6303 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416304 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336305 mock_quic_data.AddWrite(SYNCHRONOUS,
6306 ConstructClientAckAndRstPacket(
6307 client_packet_number++,
6308 GetNthServerInitiatedUnidirectionalStreamId(0),
6309 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136310 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6311 mock_quic_data.AddRead(ASYNC, 0); // EOF
6312 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6313
6314 // The non-alternate protocol job needs to hang in order to guarantee that
6315 // the alternate-protocol job will "win".
6316 AddHangingNonAlternateProtocolSocketData();
6317
6318 CreateSession();
6319
6320 // PUSH_PROMISE handling in the http layer gets exercised here.
6321 SendRequestAndExpectQuicResponse("hello!");
6322
6323 request_.url = GURL("https://mail.example.org/pushed.jpg");
6324 SendRequestAndExpectQuicResponse("and hello!");
6325
6326 // Check that the NetLog was filled reasonably.
6327 TestNetLogEntry::List entries;
6328 net_log_.GetEntries(&entries);
6329 EXPECT_LT(0u, entries.size());
6330
6331 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6332 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006333 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6334 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136335 EXPECT_LT(0, pos);
6336}
6337
rch56ec40a2017-06-23 14:48:446338// Regression test for http://crbug.com/719461 in which a promised stream
6339// is closed before the pushed headers arrive, but after the connection
6340// is closed and before the callbacks are executed.
6341TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486342 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446343 session_params_.origins_to_force_quic_on.insert(
6344 HostPortPair::FromString("mail.example.org:443"));
6345
6346 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526347 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236348 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446349 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436350 mock_quic_data.AddWrite(
6351 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6352 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446353 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436354 mock_quic_data.AddWrite(
6355 SYNCHRONOUS,
6356 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336357 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6358 true, true, GetRequestHeaders("GET", "https", "/"),
6359 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526360 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446361 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436362 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336363 ASYNC, ConstructServerPushPromisePacket(
6364 1, GetNthClientInitiatedBidirectionalStreamId(0),
6365 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6366 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6367 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576368 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566369 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336370 mock_quic_data.AddWrite(SYNCHRONOUS,
6371 ConstructClientPriorityPacket(
6372 client_packet_number++, false,
6373 GetNthServerInitiatedUnidirectionalStreamId(0),
6374 GetNthClientInitiatedBidirectionalStreamId(0),
6375 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576376 }
rch56ec40a2017-06-23 14:48:446377 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436378 mock_quic_data.AddRead(
6379 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336380 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436381 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446382 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576383 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436384 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446385 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436386 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436387 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336388 ASYNC, ConstructServerDataPacket(
6389 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416390 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446391 // Write error for the third request.
6392 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6393 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6394 mock_quic_data.AddRead(ASYNC, 0); // EOF
6395 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6396
6397 CreateSession();
6398
6399 // Send a request which triggers a push promise from the server.
6400 SendRequestAndExpectQuicResponse("hello!");
6401
6402 // Start a push transaction that will be cancelled after the connection
6403 // is closed, but before the callback is executed.
6404 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196405 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446406 session_.get());
6407 TestCompletionCallback callback2;
6408 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6410 base::RunLoop().RunUntilIdle();
6411
6412 // Cause the connection to close on a write error.
6413 HttpRequestInfo request3;
6414 request3.method = "GET";
6415 request3.url = GURL("https://mail.example.org/");
6416 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106417 request3.traffic_annotation =
6418 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446419 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6420 TestCompletionCallback callback3;
6421 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6422 IsError(ERR_IO_PENDING));
6423
6424 base::RunLoop().RunUntilIdle();
6425
6426 // When |trans2| is destroyed, the underlying stream will be closed.
6427 EXPECT_FALSE(callback2.have_result());
6428 trans2 = nullptr;
6429
6430 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6431}
6432
ckrasicda193a82016-07-09 00:39:366433TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416434 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366435 HostPortPair::FromString("mail.example.org:443"));
6436
6437 MockQuicData mock_quic_data;
6438
Ryan Hamilton8d9ee76e2018-05-29 23:52:526439 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416440 int write_packet_index = 1;
6441 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6442 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366443
Victor Vasiliev076657c2019-03-12 02:46:436444 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566445 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416446 mock_quic_data.AddWrite(
6447 SYNCHRONOUS,
6448 ConstructClientRequestHeadersAndDataFramesPacket(
6449 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6450 true, true, DEFAULT_PRIORITY,
6451 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6452 {"1"}));
6453 } else {
6454 mock_quic_data.AddWrite(
6455 SYNCHRONOUS,
6456 ConstructClientRequestHeadersAndDataFramesPacket(
6457 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6458 true, true, DEFAULT_PRIORITY,
6459 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6460 {header, "1"}));
6461 }
ckrasicda193a82016-07-09 00:39:366462
Zhongyi Shi32f2fd02018-04-16 18:23:436463 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336464 ASYNC, ConstructServerResponseHeadersPacket(
6465 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6466 GetResponseHeaders("200 OK")));
6467
Victor Vasiliev076657c2019-03-12 02:46:436468 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336469 mock_quic_data.AddRead(
6470 ASYNC, ConstructServerDataPacket(
6471 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416472 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366473
Renjief49758b2019-01-11 23:32:416474 mock_quic_data.AddWrite(
6475 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366476
6477 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6478 mock_quic_data.AddRead(ASYNC, 0); // EOF
6479 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6480
6481 // The non-alternate protocol job needs to hang in order to guarantee that
6482 // the alternate-protocol job will "win".
6483 AddHangingNonAlternateProtocolSocketData();
6484
6485 CreateSession();
6486 request_.method = "POST";
6487 ChunkedUploadDataStream upload_data(0);
6488 upload_data.AppendData("1", 1, true);
6489
6490 request_.upload_data_stream = &upload_data;
6491
6492 SendRequestAndExpectQuicResponse("hello!");
6493}
6494
allada71b2efb2016-09-09 04:57:486495class QuicURLRequestContext : public URLRequestContext {
6496 public:
6497 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6498 MockClientSocketFactory* socket_factory)
6499 : storage_(this) {
6500 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076501 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046502 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486503 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046504 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596505 storage_.set_proxy_resolution_service(
6506 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076507 storage_.set_ssl_config_service(
6508 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486509 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116510 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486511 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076512 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046513 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486514 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046515 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6516 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6517 false));
allada71b2efb2016-09-09 04:57:486518 }
6519
6520 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6521
6522 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6523
6524 private:
6525 MockClientSocketFactory* socket_factory_;
6526 URLRequestContextStorage storage_;
6527};
6528
6529TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416530 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486531 HostPortPair::FromString("mail.example.org:443"));
6532
6533 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526534 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366535 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436536 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136537 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486538 headers["user-agent"] = "";
6539 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336540 mock_quic_data.AddWrite(
6541 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6542 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6543 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486544
Ryan Hamilton8d9ee76e2018-05-29 23:52:526545 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336546 mock_quic_data.AddRead(
6547 ASYNC,
6548 ConstructServerResponseHeadersPacket(
6549 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6550 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486551
Victor Vasiliev076657c2019-03-12 02:46:436552 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366553 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336554 ASYNC, ConstructServerDataPacket(
6555 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6556 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436557 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486558
6559 mock_quic_data.AddRead(ASYNC, 0); // EOF
6560
6561 CreateSession();
6562
6563 TestDelegate delegate;
6564 QuicURLRequestContext quic_url_request_context(std::move(session_),
6565 &socket_factory_);
6566
6567 mock_quic_data.AddSocketDataToFactory(
6568 &quic_url_request_context.socket_factory());
6569 TestNetworkDelegate network_delegate;
6570 quic_url_request_context.set_network_delegate(&network_delegate);
6571
6572 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296573 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6574 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486575 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6576 &ssl_data_);
6577
6578 request->Start();
Wez2a31b222018-06-07 22:07:156579 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486580
6581 EXPECT_LT(0, request->GetTotalSentBytes());
6582 EXPECT_LT(0, request->GetTotalReceivedBytes());
6583 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6584 request->GetTotalSentBytes());
6585 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6586 request->GetTotalReceivedBytes());
6587 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6588 request->raw_header_size());
Wez0e717112018-06-18 23:09:226589
6590 // Pump the message loop to allow all data to be consumed.
6591 base::RunLoop().RunUntilIdle();
6592
allada71b2efb2016-09-09 04:57:486593 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6594 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6595}
6596
6597TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416598 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486599 HostPortPair::FromString("mail.example.org:443"));
6600
6601 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526602 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236603 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436604 mock_quic_data.AddWrite(
6605 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6606 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136607 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486608 headers["user-agent"] = "";
6609 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436610 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336611 SYNCHRONOUS,
6612 ConstructClientRequestHeadersPacket(
6613 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6614 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486615
Ryan Hamilton8d9ee76e2018-05-29 23:52:526616 quic::QuicStreamOffset server_header_offset = 0;
6617 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486618
Zhongyi Shi32f2fd02018-04-16 18:23:436619 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336620 ASYNC, ConstructServerPushPromisePacket(
6621 1, GetNthClientInitiatedBidirectionalStreamId(0),
6622 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6623 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6624 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486625
Yixin Wangb470bc882018-02-15 18:43:576626 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566627 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336628 mock_quic_data.AddWrite(SYNCHRONOUS,
6629 ConstructClientPriorityPacket(
6630 client_packet_number++, false,
6631 GetNthServerInitiatedUnidirectionalStreamId(0),
6632 GetNthClientInitiatedBidirectionalStreamId(0),
6633 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576634 }
6635
allada71b2efb2016-09-09 04:57:486636 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436637 mock_quic_data.AddRead(
6638 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336639 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436640 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486641 expected_raw_header_response_size =
6642 server_header_offset - expected_raw_header_response_size;
6643
Yixin Wangb470bc882018-02-15 18:43:576644 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436645 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486646
ckrasicbf2f59c2017-05-04 23:54:366647 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436648 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336649 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6650 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436651 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436652 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336653 ASYNC, ConstructServerDataPacket(
6654 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416655 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486656
Yixin Wangb470bc882018-02-15 18:43:576657 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436658 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436659 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366660 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336661 ASYNC, ConstructServerDataPacket(
6662 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416663 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486664
Zhongyi Shi32f2fd02018-04-16 18:23:436665 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486666
6667 CreateSession();
6668
6669 TestDelegate delegate;
6670 QuicURLRequestContext quic_url_request_context(std::move(session_),
6671 &socket_factory_);
6672
6673 mock_quic_data.AddSocketDataToFactory(
6674 &quic_url_request_context.socket_factory());
6675 TestNetworkDelegate network_delegate;
6676 quic_url_request_context.set_network_delegate(&network_delegate);
6677
6678 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296679 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6680 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486681 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6682 &ssl_data_);
6683
6684 request->Start();
Wez2a31b222018-06-07 22:07:156685 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486686
6687 EXPECT_LT(0, request->GetTotalSentBytes());
6688 EXPECT_LT(0, request->GetTotalReceivedBytes());
6689 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6690 request->GetTotalSentBytes());
6691 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6692 request->GetTotalReceivedBytes());
6693 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6694 request->raw_header_size());
Wez0e717112018-06-18 23:09:226695
6696 // Pump the message loop to allow all data to be consumed.
6697 base::RunLoop().RunUntilIdle();
6698
allada71b2efb2016-09-09 04:57:486699 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6700 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6701}
6702
Yixin Wang10f477ed2017-11-21 04:20:206703TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6704 session_params_.quic_host_whitelist.insert("mail.example.org");
6705
6706 MockRead http_reads[] = {
6707 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6708 MockRead("hello world"),
6709 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6710 MockRead(ASYNC, OK)};
6711
Ryan Sleevib8d7ea02018-05-07 20:01:016712 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206713 socket_factory_.AddSocketDataProvider(&http_data);
6714 AddCertificate(&ssl_data_);
6715 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6716
6717 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526718 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206719 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436720 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6721 mock_quic_data.AddWrite(
6722 SYNCHRONOUS,
6723 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336724 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436725 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436726 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336727 ASYNC, ConstructServerResponseHeadersPacket(
6728 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6729 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436730 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336731 mock_quic_data.AddRead(
6732 ASYNC, ConstructServerDataPacket(
6733 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416734 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436735 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206736 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6737 mock_quic_data.AddRead(ASYNC, 0); // EOF
6738
6739 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6740
6741 AddHangingNonAlternateProtocolSocketData();
6742 CreateSession();
6743
6744 SendRequestAndExpectHttpResponse("hello world");
6745 SendRequestAndExpectQuicResponse("hello!");
6746}
6747
6748TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6749 session_params_.quic_host_whitelist.insert("mail.example.com");
6750
6751 MockRead http_reads[] = {
6752 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6753 MockRead("hello world"),
6754 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6755 MockRead(ASYNC, OK)};
6756
Ryan Sleevib8d7ea02018-05-07 20:01:016757 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206758 socket_factory_.AddSocketDataProvider(&http_data);
6759 AddCertificate(&ssl_data_);
6760 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6761 socket_factory_.AddSocketDataProvider(&http_data);
6762 AddCertificate(&ssl_data_);
6763 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6764
6765 AddHangingNonAlternateProtocolSocketData();
6766 CreateSession();
6767
6768 SendRequestAndExpectHttpResponse("hello world");
6769 SendRequestAndExpectHttpResponse("hello world");
6770}
6771
bnc359ed2a2016-04-29 20:43:456772class QuicNetworkTransactionWithDestinationTest
6773 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016774 public ::testing::WithParamInterface<PoolingTestParams>,
6775 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456776 protected:
6777 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556778 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056779 client_headers_include_h2_stream_dependency_(
6780 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:566781 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456782 destination_type_(GetParam().destination_type),
6783 cert_transparency_verifier_(new MultiLogCTVerifier()),
6784 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596785 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116786 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456787 random_generator_(0),
6788 ssl_data_(ASYNC, OK) {}
6789
6790 void SetUp() override {
6791 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556792 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456793
mmenke6ddfbea2017-05-31 21:48:416794 HttpNetworkSession::Params session_params;
6795 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346796 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446797 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056798 session_params.quic_headers_include_h2_stream_dependency =
6799 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416800
6801 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456802
Ryan Hamilton8d9ee76e2018-05-29 23:52:526803 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416804 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456805
6806 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276807 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416808 session_context.quic_crypto_client_stream_factory =
6809 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456810
mmenke6ddfbea2017-05-31 21:48:416811 session_context.quic_random = &random_generator_;
6812 session_context.client_socket_factory = &socket_factory_;
6813 session_context.host_resolver = &host_resolver_;
6814 session_context.cert_verifier = &cert_verifier_;
6815 session_context.transport_security_state = &transport_security_state_;
6816 session_context.cert_transparency_verifier =
6817 cert_transparency_verifier_.get();
6818 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6819 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456820 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416821 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596822 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416823 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6824 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456825
mmenke6ddfbea2017-05-31 21:48:416826 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456827 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456828 }
6829
6830 void TearDown() override {
6831 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6832 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556833 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456834 PlatformTest::TearDown();
6835 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556836 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406837 session_.reset();
bnc359ed2a2016-04-29 20:43:456838 }
6839
zhongyie537a002017-06-27 16:48:216840 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456841 HostPortPair destination;
6842 switch (destination_type_) {
6843 case SAME_AS_FIRST:
6844 destination = HostPortPair(origin1_, 443);
6845 break;
6846 case SAME_AS_SECOND:
6847 destination = HostPortPair(origin2_, 443);
6848 break;
6849 case DIFFERENT:
6850 destination = HostPortPair(kDifferentHostname, 443);
6851 break;
6852 }
bnc3472afd2016-11-17 15:27:216853 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456854 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216855 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456856 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446857 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456858 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526859 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236860 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526861 quic::QuicStreamId stream_id,
6862 bool should_include_version,
6863 quic::QuicStreamOffset* offset,
6864 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486865 return ConstructClientRequestHeadersPacket(
6866 packet_number, stream_id, should_include_version, 0, offset, maker);
6867 }
bnc359ed2a2016-04-29 20:43:456868
Ryan Hamilton8d9ee76e2018-05-29 23:52:526869 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236870 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526871 quic::QuicStreamId stream_id,
6872 bool should_include_version,
6873 quic::QuicStreamId parent_stream_id,
6874 quic::QuicStreamOffset* offset,
6875 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136876 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456877 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136878 spdy::SpdyHeaderBlock headers(
6879 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456880 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6881 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486882 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456883 }
6884
Ryan Hamilton8d9ee76e2018-05-29 23:52:526885 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236886 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526887 quic::QuicStreamId stream_id,
6888 bool should_include_version,
6889 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586890 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456891 packet_number, stream_id, should_include_version, nullptr, maker);
6892 }
6893
Ryan Hamilton8d9ee76e2018-05-29 23:52:526894 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236895 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526896 quic::QuicStreamId stream_id,
6897 quic::QuicStreamOffset* offset,
6898 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136899 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456900 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266901 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456902 }
6903
Ryan Hamilton8d9ee76e2018-05-29 23:52:526904 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236905 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526906 quic::QuicStreamId stream_id,
6907 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586908 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6909 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456910 }
6911
Ryan Hamilton8d9ee76e2018-05-29 23:52:526912 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236913 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526914 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456915 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436916 std::string header = "";
Nick Harper23290b82019-05-02 00:02:566917 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416918 quic::HttpEncoder encoder;
6919 std::unique_ptr<char[]> buffer;
6920 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436921 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416922 }
bnc359ed2a2016-04-29 20:43:456923 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416924 header + "hello");
bnc359ed2a2016-04-29 20:43:456925 }
6926
Ryan Hamilton8d9ee76e2018-05-29 23:52:526927 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236928 uint64_t packet_number,
6929 uint64_t largest_received,
6930 uint64_t smallest_received,
6931 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456932 QuicTestPacketMaker* maker) {
6933 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496934 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456935 }
6936
Ryan Hamilton8d9ee76e2018-05-29 23:52:526937 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236938 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526939 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376940 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366941 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376942 }
6943
bnc359ed2a2016-04-29 20:43:456944 void AddRefusedSocketData() {
6945 std::unique_ptr<StaticSocketDataProvider> refused_data(
6946 new StaticSocketDataProvider());
6947 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6948 refused_data->set_connect_data(refused_connect);
6949 socket_factory_.AddSocketDataProvider(refused_data.get());
6950 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6951 }
6952
6953 void AddHangingSocketData() {
6954 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6955 new StaticSocketDataProvider());
6956 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6957 hanging_data->set_connect_data(hanging_connect);
6958 socket_factory_.AddSocketDataProvider(hanging_data.get());
6959 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6960 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6961 }
6962
6963 bool AllDataConsumed() {
6964 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6965 if (!socket_data_ptr->AllReadDataConsumed() ||
6966 !socket_data_ptr->AllWriteDataConsumed()) {
6967 return false;
6968 }
6969 }
6970 return true;
6971 }
6972
6973 void SendRequestAndExpectQuicResponse(const std::string& host) {
6974 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6975 HttpRequestInfo request;
6976 std::string url("https://");
6977 url.append(host);
6978 request.url = GURL(url);
6979 request.load_flags = 0;
6980 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106981 request.traffic_annotation =
6982 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456983 TestCompletionCallback callback;
6984 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016985 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456986
6987 std::string response_data;
robpercival214763f2016-07-01 23:27:016988 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456989 EXPECT_EQ("hello", response_data);
6990
6991 const HttpResponseInfo* response = trans.GetResponseInfo();
6992 ASSERT_TRUE(response != nullptr);
6993 ASSERT_TRUE(response->headers.get() != nullptr);
6994 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6995 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526996 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:566997 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
6998 version_.transport_version),
bnc359ed2a2016-04-29 20:43:456999 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:377000 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:457001 }
7002
Fan Yang32c5a112018-12-10 20:06:337003 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:567004 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
7005 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:367006 }
7007
Ryan Hamilton8d9ee76e2018-05-29 23:52:527008 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:567009 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:057010 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:567011 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457012 DestinationType destination_type_;
7013 std::string origin1_;
7014 std::string origin2_;
7015 std::unique_ptr<HttpNetworkSession> session_;
7016 MockClientSocketFactory socket_factory_;
7017 MockHostResolver host_resolver_;
7018 MockCertVerifier cert_verifier_;
7019 TransportSecurityState transport_security_state_;
7020 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237021 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457022 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077023 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597024 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457025 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527026 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457027 HttpServerPropertiesImpl http_server_properties_;
7028 BoundTestNetLog net_log_;
7029 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7030 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7031 static_socket_data_provider_vector_;
7032 SSLSocketDataProvider ssl_data_;
7033};
7034
Victor Costane635086f2019-01-27 05:20:307035INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7036 QuicNetworkTransactionWithDestinationTest,
7037 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457038
7039// A single QUIC request fails because the certificate does not match the origin
7040// hostname, regardless of whether it matches the alternative service hostname.
7041TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7042 if (destination_type_ == DIFFERENT)
7043 return;
7044
7045 GURL url("https://mail.example.com/");
7046 origin1_ = url.host();
7047
7048 // Not used for requests, but this provides a test case where the certificate
7049 // is valid for the hostname of the alternative service.
7050 origin2_ = "mail.example.org";
7051
zhongyie537a002017-06-27 16:48:217052 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457053
7054 scoped_refptr<X509Certificate> cert(
7055 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247056 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7057 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457058
7059 ProofVerifyDetailsChromium verify_details;
7060 verify_details.cert_verify_result.verified_cert = cert;
7061 verify_details.cert_verify_result.is_issued_by_known_root = true;
7062 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7063
7064 MockQuicData mock_quic_data;
7065 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7066 mock_quic_data.AddRead(ASYNC, 0);
7067
7068 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7069
7070 AddRefusedSocketData();
7071
7072 HttpRequestInfo request;
7073 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107074 request.traffic_annotation =
7075 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457076
7077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7078 TestCompletionCallback callback;
7079 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017080 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457081
7082 EXPECT_TRUE(AllDataConsumed());
7083}
7084
7085// First request opens QUIC session to alternative service. Second request
7086// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527087// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457088TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7089 origin1_ = "mail.example.org";
7090 origin2_ = "news.example.org";
7091
zhongyie537a002017-06-27 16:48:217092 SetQuicAlternativeService(origin1_);
7093 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457094
7095 scoped_refptr<X509Certificate> cert(
7096 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247097 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7098 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7099 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457100
7101 ProofVerifyDetailsChromium verify_details;
7102 verify_details.cert_verify_result.verified_cert = cert;
7103 verify_details.cert_verify_result.is_issued_by_known_root = true;
7104 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7105
Yixin Wang079ad542018-01-11 04:06:057106 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177107 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7108 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057109 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177110 QuicTestPacketMaker server_maker(
7111 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7112 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457113
Ryan Hamilton8d9ee76e2018-05-29 23:52:527114 quic::QuicStreamOffset request_header_offset(0);
7115 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457116
7117 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057118 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437119 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057120 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337121 mock_quic_data.AddWrite(
7122 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7123 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7124 &request_header_offset, &client_maker));
7125 mock_quic_data.AddRead(ASYNC,
7126 ConstructServerResponseHeadersPacket(
7127 1, GetNthClientInitiatedBidirectionalStreamId(0),
7128 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437129 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337130 ASYNC,
7131 ConstructServerDataPacket(
7132 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437133 mock_quic_data.AddWrite(SYNCHRONOUS,
7134 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457135
Yixin Wang079ad542018-01-11 04:06:057136 client_maker.set_hostname(origin2_);
7137 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457138
Zhongyi Shi32f2fd02018-04-16 18:23:437139 mock_quic_data.AddWrite(
7140 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337141 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7142 GetNthClientInitiatedBidirectionalStreamId(0),
7143 &request_header_offset, &client_maker));
7144 mock_quic_data.AddRead(ASYNC,
7145 ConstructServerResponseHeadersPacket(
7146 3, GetNthClientInitiatedBidirectionalStreamId(1),
7147 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437148 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337149 ASYNC,
7150 ConstructServerDataPacket(
7151 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437152 mock_quic_data.AddWrite(SYNCHRONOUS,
7153 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457154 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7155 mock_quic_data.AddRead(ASYNC, 0); // EOF
7156
7157 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7158
7159 AddHangingSocketData();
7160 AddHangingSocketData();
7161
Nick Harpereb483e12019-05-14 00:18:097162 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:567163 QuicStreamFactoryPeer::SetAlarmFactory(
7164 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097165 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:567166 &clock_));
7167
bnc359ed2a2016-04-29 20:43:457168 SendRequestAndExpectQuicResponse(origin1_);
7169 SendRequestAndExpectQuicResponse(origin2_);
7170
7171 EXPECT_TRUE(AllDataConsumed());
7172}
7173
7174// First request opens QUIC session to alternative service. Second request does
7175// not pool to it, even though destination matches, because certificate is not
7176// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527177// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457178TEST_P(QuicNetworkTransactionWithDestinationTest,
7179 DoNotPoolIfCertificateInvalid) {
7180 origin1_ = "news.example.org";
7181 origin2_ = "mail.example.com";
7182
zhongyie537a002017-06-27 16:48:217183 SetQuicAlternativeService(origin1_);
7184 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457185
7186 scoped_refptr<X509Certificate> cert1(
7187 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247188 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7189 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7190 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457191
7192 scoped_refptr<X509Certificate> cert2(
7193 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247194 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7195 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457196
7197 ProofVerifyDetailsChromium verify_details1;
7198 verify_details1.cert_verify_result.verified_cert = cert1;
7199 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7200 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7201
7202 ProofVerifyDetailsChromium verify_details2;
7203 verify_details2.cert_verify_result.verified_cert = cert2;
7204 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7205 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7206
Yixin Wang079ad542018-01-11 04:06:057207 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177208 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7209 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057210 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177211 QuicTestPacketMaker server_maker1(
7212 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7213 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457214
7215 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527216 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457217 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437218 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7219 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337220 mock_quic_data1.AddWrite(
7221 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7222 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7223 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437224 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337225 ASYNC,
7226 ConstructServerResponseHeadersPacket(
7227 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437228 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337229 ASYNC,
7230 ConstructServerDataPacket(
7231 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437232 mock_quic_data1.AddWrite(
7233 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457234 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7235 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7236
7237 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7238
Yixin Wang079ad542018-01-11 04:06:057239 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177240 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7241 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057242 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177243 QuicTestPacketMaker server_maker2(
7244 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7245 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457246
7247 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527248 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457249 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437250 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7251 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337252 mock_quic_data2.AddWrite(
7253 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7254 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7255 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437256 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337257 ASYNC,
7258 ConstructServerResponseHeadersPacket(
7259 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437260 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337261 ASYNC,
7262 ConstructServerDataPacket(
7263 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437264 mock_quic_data2.AddWrite(
7265 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457266 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7267 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7268
7269 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7270
bnc359ed2a2016-04-29 20:43:457271 SendRequestAndExpectQuicResponse(origin1_);
7272 SendRequestAndExpectQuicResponse(origin2_);
7273
7274 EXPECT_TRUE(AllDataConsumed());
7275}
7276
ckrasicdee37572017-04-06 22:42:277277// crbug.com/705109 - this confirms that matching request with a body
7278// triggers a crash (pre-fix).
7279TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417280 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277281 HostPortPair::FromString("mail.example.org:443"));
7282
7283 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527284 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237285 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437286 mock_quic_data.AddWrite(
7287 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7288 &header_stream_offset));
7289 mock_quic_data.AddWrite(
7290 SYNCHRONOUS,
7291 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337292 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7293 true, true, GetRequestHeaders("GET", "https", "/"),
7294 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527295 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437296 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337297 ASYNC, ConstructServerPushPromisePacket(
7298 1, GetNthClientInitiatedBidirectionalStreamId(0),
7299 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7300 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7301 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577302 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:567303 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337304 mock_quic_data.AddWrite(SYNCHRONOUS,
7305 ConstructClientPriorityPacket(
7306 client_packet_number++, false,
7307 GetNthServerInitiatedUnidirectionalStreamId(0),
7308 GetNthClientInitiatedBidirectionalStreamId(0),
7309 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577310 }
Zhongyi Shi32f2fd02018-04-16 18:23:437311 mock_quic_data.AddRead(
7312 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337313 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437314 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577315 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437316 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7317 mock_quic_data.AddRead(
7318 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337319 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7320 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437321 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437322 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337323 ASYNC, ConstructServerDataPacket(
7324 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417325 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577326 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437327 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417328
Victor Vasiliev076657c2019-03-12 02:46:437329 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437330 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337331 ASYNC, ConstructServerDataPacket(
7332 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417333 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277334
7335 // Because the matching request has a body, we will see the push
7336 // stream get cancelled, and the matching request go out on the
7337 // wire.
Fan Yang32c5a112018-12-10 20:06:337338 mock_quic_data.AddWrite(SYNCHRONOUS,
7339 ConstructClientAckAndRstPacket(
7340 client_packet_number++,
7341 GetNthServerInitiatedUnidirectionalStreamId(0),
7342 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277343 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437344 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567345 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417346 mock_quic_data.AddWrite(
7347 SYNCHRONOUS,
7348 ConstructClientRequestHeadersAndDataFramesPacket(
7349 client_packet_number++,
7350 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7351 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7352 GetNthServerInitiatedUnidirectionalStreamId(0),
7353 &header_stream_offset, nullptr, {kBody}));
7354 } else {
7355 mock_quic_data.AddWrite(
7356 SYNCHRONOUS,
7357 ConstructClientRequestHeadersAndDataFramesPacket(
7358 client_packet_number++,
7359 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7360 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7361 GetNthServerInitiatedUnidirectionalStreamId(0),
7362 &header_stream_offset, nullptr, {header3, kBody}));
7363 }
ckrasicdee37572017-04-06 22:42:277364
7365 // We see the same response as for the earlier pushed and cancelled
7366 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437367 mock_quic_data.AddRead(
7368 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337369 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437370 GetResponseHeaders("200 OK"), &server_header_offset));
7371 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337372 ASYNC, ConstructServerDataPacket(
7373 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417374 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277375
Yixin Wangb470bc882018-02-15 18:43:577376 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437377 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277378 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7379 mock_quic_data.AddRead(ASYNC, 0); // EOF
7380 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7381
7382 // The non-alternate protocol job needs to hang in order to guarantee that
7383 // the alternate-protocol job will "win".
7384 AddHangingNonAlternateProtocolSocketData();
7385
7386 CreateSession();
7387
7388 // PUSH_PROMISE handling in the http layer gets exercised here.
7389 SendRequestAndExpectQuicResponse("hello!");
7390
7391 request_.url = GURL("https://mail.example.org/pushed.jpg");
7392 ChunkedUploadDataStream upload_data(0);
7393 upload_data.AppendData("1", 1, true);
7394 request_.upload_data_stream = &upload_data;
7395 SendRequestAndExpectQuicResponse("and hello!");
7396}
7397
Bence Béky7538a952018-02-01 16:59:527398// Regression test for https://crbug.com/797825: If pushed headers describe a
7399// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7400// not be called (otherwise a DCHECK fails).
7401TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137402 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527403 pushed_request_headers[":authority"] = "";
7404 pushed_request_headers[":method"] = "GET";
7405 pushed_request_headers[":path"] = "/";
7406 pushed_request_headers[":scheme"] = "nosuchscheme";
7407
7408 session_params_.origins_to_force_quic_on.insert(
7409 HostPortPair::FromString("mail.example.org:443"));
7410
7411 MockQuicData mock_quic_data;
7412
Ryan Hamilton8d9ee76e2018-05-29 23:52:527413 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527414 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437415 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7416 mock_quic_data.AddWrite(
7417 SYNCHRONOUS,
7418 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337419 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437420 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527421
Ryan Hamilton8d9ee76e2018-05-29 23:52:527422 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337423 mock_quic_data.AddRead(
7424 ASYNC, ConstructServerPushPromisePacket(
7425 1, GetNthClientInitiatedBidirectionalStreamId(0),
7426 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7427 std::move(pushed_request_headers), &server_header_offset,
7428 &server_maker_));
7429 mock_quic_data.AddWrite(SYNCHRONOUS,
7430 ConstructClientRstPacket(
7431 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7432 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527433
Zhongyi Shi32f2fd02018-04-16 18:23:437434 mock_quic_data.AddRead(
7435 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337436 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437437 GetResponseHeaders("200 OK"), &server_header_offset));
7438 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527439
Zhongyi Shi32f2fd02018-04-16 18:23:437440 mock_quic_data.AddRead(
7441 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337442 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7443 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437444 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437445 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337446 ASYNC, ConstructServerDataPacket(
7447 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417448 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437449 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527450
7451 mock_quic_data.AddRead(ASYNC, 0);
7452 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7453
7454 // The non-alternate protocol job needs to hang in order to guarantee that
7455 // the alternate-protocol job will "win".
7456 AddHangingNonAlternateProtocolSocketData();
7457
7458 CreateSession();
7459
7460 // PUSH_PROMISE handling in the http layer gets exercised here.
7461 SendRequestAndExpectQuicResponse("hello!");
7462
7463 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7464 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7465}
7466
Yixin Wang46a273ec302018-01-23 17:59:567467// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147468TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567469 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147470 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567471 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497472 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567473
7474 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527475 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567476 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357477 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337478 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357479 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7480 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047481 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7482 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357483 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337484 mock_quic_data.AddRead(
7485 ASYNC, ConstructServerResponseHeadersPacket(
7486 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7487 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567488
7489 const char get_request[] =
7490 "GET / HTTP/1.1\r\n"
7491 "Host: mail.example.org\r\n"
7492 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437493 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567494 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417495 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357496 SYNCHRONOUS,
7497 ConstructClientAckAndDataPacket(
7498 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7499 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417500 } else {
7501 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417502 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357503 ConstructClientAckAndMultipleDataFramesPacket(
7504 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437505 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417506 }
7507
Yixin Wang46a273ec302018-01-23 17:59:567508 const char get_response[] =
7509 "HTTP/1.1 200 OK\r\n"
7510 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437511 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437512 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337513 ASYNC, ConstructServerDataPacket(
7514 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437515 0, header2 + std::string(get_response)));
7516 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337517 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417518 SYNCHRONOUS, ConstructServerDataPacket(
7519 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7520 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437521 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357522 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567523 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7524
7525 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417526 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357527 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7528 quic::QUIC_STREAM_CANCELLED,
7529 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567530
7531 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7532
7533 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7534
7535 CreateSession();
7536
7537 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097538 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567539 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7540 HeadersHandler headers_handler;
7541 trans.SetBeforeHeadersSentCallback(
7542 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7543 base::Unretained(&headers_handler)));
7544 RunTransaction(&trans);
7545 CheckWasHttpResponse(&trans);
7546 CheckResponsePort(&trans, 70);
7547 CheckResponseData(&trans, "0123456789");
7548 EXPECT_TRUE(headers_handler.was_proxied());
7549 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7550
7551 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7552 // proxy socket to disconnect.
7553 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7554
7555 base::RunLoop().RunUntilIdle();
7556 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7557 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7558}
7559
7560// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147561TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567562 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147563 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567564 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497565 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567566
7567 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527568 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567569 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357570 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337571 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357572 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7573 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047574 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7575 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357576 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337577 mock_quic_data.AddRead(
7578 ASYNC, ConstructServerResponseHeadersPacket(
7579 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7580 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567581
7582 SpdyTestUtil spdy_util;
7583
Ryan Hamilton0239aac2018-05-19 00:03:137584 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567585 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437586 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567587 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417588 mock_quic_data.AddWrite(
7589 SYNCHRONOUS,
7590 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357591 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7592 false, 0,
Renjief49758b2019-01-11 23:32:417593 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7594 } else {
7595 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417596 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357597 ConstructClientAckAndMultipleDataFramesPacket(
7598 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7599 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437600 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417601 }
Ryan Hamilton0239aac2018-05-19 00:03:137602 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567603 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437604 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437605 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337606 ASYNC,
7607 ConstructServerDataPacket(
7608 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437609 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567610
Ryan Hamilton0239aac2018-05-19 00:03:137611 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197612 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437613 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437614 mock_quic_data.AddRead(
7615 SYNCHRONOUS,
7616 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337617 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417618 resp_frame.size() + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437619 header3 + std::string(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357620 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567621 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7622
7623 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437624 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357625 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7626 quic::QUIC_STREAM_CANCELLED,
7627 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567628
7629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7630
7631 SSLSocketDataProvider ssl_data(ASYNC, OK);
7632 ssl_data.next_proto = kProtoHTTP2;
7633 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7634
7635 CreateSession();
7636
7637 request_.url = GURL("https://mail.example.org/");
7638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7639 HeadersHandler headers_handler;
7640 trans.SetBeforeHeadersSentCallback(
7641 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7642 base::Unretained(&headers_handler)));
7643 RunTransaction(&trans);
7644 CheckWasSpdyResponse(&trans);
7645 CheckResponsePort(&trans, 70);
7646 CheckResponseData(&trans, "0123456789");
7647 EXPECT_TRUE(headers_handler.was_proxied());
7648 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7649
Wez0e717112018-06-18 23:09:227650 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7651 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567652 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7653
7654 base::RunLoop().RunUntilIdle();
7655 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7656 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7657}
7658
7659// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7660// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147661TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567662 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147663 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567664 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497665 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567666
7667 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527668 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417669 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567670 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417671 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7672 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337673 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417674 SYNCHRONOUS,
7675 ConstructClientRequestHeadersPacket(
7676 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047677 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7678 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjief49758b2019-01-11 23:32:417679 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337680 mock_quic_data.AddRead(
7681 ASYNC, ConstructServerResponseHeadersPacket(
7682 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7683 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567684
Ryan Hamilton8d9ee76e2018-05-29 23:52:527685 quic::QuicStreamOffset client_data_offset = 0;
7686 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567687 const char get_request_1[] =
7688 "GET / HTTP/1.1\r\n"
7689 "Host: mail.example.org\r\n"
7690 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437691 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567692 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417693 mock_quic_data.AddWrite(
7694 SYNCHRONOUS,
7695 ConstructClientAckAndDataPacket(
7696 write_packet_index++, false,
7697 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7698 client_data_offset, quic::QuicStringPiece(get_request_1)));
7699 } else {
7700 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417701 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357702 ConstructClientAckAndMultipleDataFramesPacket(
7703 write_packet_index++, false,
7704 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
Victor Vasiliev076657c2019-03-12 02:46:437705 client_data_offset, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417706 }
7707
7708 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567709
7710 const char get_response_1[] =
7711 "HTTP/1.1 200 OK\r\n"
7712 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437713 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437714 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437715 ASYNC, ConstructServerDataPacket(
7716 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7717 server_data_offset, header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417718 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567719
Victor Vasiliev076657c2019-03-12 02:46:437720 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337721 mock_quic_data.AddRead(
7722 SYNCHRONOUS,
7723 ConstructServerDataPacket(
7724 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437725 server_data_offset, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417726 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567727
Renjief49758b2019-01-11 23:32:417728 mock_quic_data.AddWrite(
7729 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567730
7731 const char get_request_2[] =
7732 "GET /2 HTTP/1.1\r\n"
7733 "Host: mail.example.org\r\n"
7734 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437735 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:567736 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417737 mock_quic_data.AddWrite(
7738 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357739 ConstructClientMultipleDataFramesPacket(
7740 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7741 false, false, client_data_offset,
Victor Vasiliev076657c2019-03-12 02:46:437742 {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357743 client_data_offset += header4.length() + strlen(get_request_2);
7744 } else {
7745 mock_quic_data.AddWrite(
7746 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417747 ConstructClientDataPacket(write_packet_index++,
7748 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357749 false, false, client_data_offset,
7750 quic::QuicStringPiece(get_request_2)));
7751 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417752 }
Yixin Wang46a273ec302018-01-23 17:59:567753
7754 const char get_response_2[] =
7755 "HTTP/1.1 200 OK\r\n"
7756 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437757 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437758 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437759 ASYNC, ConstructServerDataPacket(
7760 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7761 server_data_offset, header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417762 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567763
Victor Vasiliev076657c2019-03-12 02:46:437764 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527765 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337766 SYNCHRONOUS,
7767 ConstructServerDataPacket(
7768 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437769 server_data_offset, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417770 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567771
Renjief49758b2019-01-11 23:32:417772 mock_quic_data.AddWrite(
7773 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567774 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7775
Renjief49758b2019-01-11 23:32:417776 mock_quic_data.AddWrite(
7777 SYNCHRONOUS,
7778 ConstructClientRstPacket(
7779 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7780 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567781
7782 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7783
7784 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7785
7786 CreateSession();
7787
7788 request_.url = GURL("https://mail.example.org/");
7789 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7790 HeadersHandler headers_handler_1;
7791 trans_1.SetBeforeHeadersSentCallback(
7792 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7793 base::Unretained(&headers_handler_1)));
7794 RunTransaction(&trans_1);
7795 CheckWasHttpResponse(&trans_1);
7796 CheckResponsePort(&trans_1, 70);
7797 CheckResponseData(&trans_1, "0123456789");
7798 EXPECT_TRUE(headers_handler_1.was_proxied());
7799 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7800
7801 request_.url = GURL("https://mail.example.org/2");
7802 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7803 HeadersHandler headers_handler_2;
7804 trans_2.SetBeforeHeadersSentCallback(
7805 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7806 base::Unretained(&headers_handler_2)));
7807 RunTransaction(&trans_2);
7808 CheckWasHttpResponse(&trans_2);
7809 CheckResponsePort(&trans_2, 70);
7810 CheckResponseData(&trans_2, "0123456");
7811 EXPECT_TRUE(headers_handler_2.was_proxied());
7812 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7813
7814 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7815 // proxy socket to disconnect.
7816 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7817
7818 base::RunLoop().RunUntilIdle();
7819 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7820 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7821}
7822
7823// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7824// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7825// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147826TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567827 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147828 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567829 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497830 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567831
7832 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527833 quic::QuicStreamOffset client_header_stream_offset = 0;
7834 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357835 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7836 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567837
7838 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337839 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357840 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7841 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047842 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7843 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357844 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437845 mock_quic_data.AddRead(
7846 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337847 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437848 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567849
7850 // GET request, response, and data over QUIC tunnel for first request
7851 const char get_request[] =
7852 "GET / HTTP/1.1\r\n"
7853 "Host: mail.example.org\r\n"
7854 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437855 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567856 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417857 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357858 SYNCHRONOUS,
7859 ConstructClientAckAndDataPacket(
7860 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7861 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417862 } else {
7863 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417864 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357865 ConstructClientAckAndMultipleDataFramesPacket(
7866 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437867 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417868 }
7869
Yixin Wang46a273ec302018-01-23 17:59:567870 const char get_response[] =
7871 "HTTP/1.1 200 OK\r\n"
7872 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437873 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567874 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337875 ASYNC, ConstructServerDataPacket(
7876 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437877 0, header2 + std::string(get_response)));
7878 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337879 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417880 SYNCHRONOUS, ConstructServerDataPacket(
7881 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7882 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437883 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357884 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567885
7886 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437887 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047888 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7889 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
7890 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7891 ConnectRequestHeaders("different.example.org:443"),
7892 GetNthClientInitiatedBidirectionalStreamId(0),
7893 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437894 mock_quic_data.AddRead(
7895 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337896 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437897 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567898
7899 // GET request, response, and data over QUIC tunnel for second request
7900 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137901 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567902 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437903 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567904 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417905 mock_quic_data.AddWrite(
7906 SYNCHRONOUS,
7907 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357908 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7909 false, 0,
Renjief49758b2019-01-11 23:32:417910 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7911 } else {
7912 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417913 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357914 ConstructClientAckAndMultipleDataFramesPacket(
7915 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7916 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437917 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417918 }
Yixin Wang46a273ec302018-01-23 17:59:567919
Ryan Hamilton0239aac2018-05-19 00:03:137920 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567921 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437922 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437923 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337924 ASYNC,
7925 ConstructServerDataPacket(
7926 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437927 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567928
Ryan Hamilton0239aac2018-05-19 00:03:137929 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197930 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437931 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437932 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437933 ASYNC, ConstructServerDataPacket(
7934 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7935 resp_frame.size() + header5.length(),
7936 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567937
Renjied172e812019-01-16 05:12:357938 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567939 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7940
7941 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417942 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357943 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7944 quic::QUIC_STREAM_CANCELLED,
7945 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567946 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437947 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357948 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7949 quic::QUIC_STREAM_CANCELLED,
7950 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567951
7952 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7953
7954 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7955
7956 SSLSocketDataProvider ssl_data(ASYNC, OK);
7957 ssl_data.next_proto = kProtoHTTP2;
7958 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7959
7960 CreateSession();
7961
7962 request_.url = GURL("https://mail.example.org/");
7963 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7964 HeadersHandler headers_handler_1;
7965 trans_1.SetBeforeHeadersSentCallback(
7966 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7967 base::Unretained(&headers_handler_1)));
7968 RunTransaction(&trans_1);
7969 CheckWasHttpResponse(&trans_1);
7970 CheckResponsePort(&trans_1, 70);
7971 CheckResponseData(&trans_1, "0123456789");
7972 EXPECT_TRUE(headers_handler_1.was_proxied());
7973 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7974
7975 request_.url = GURL("https://different.example.org/");
7976 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7977 HeadersHandler headers_handler_2;
7978 trans_2.SetBeforeHeadersSentCallback(
7979 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7980 base::Unretained(&headers_handler_2)));
7981 RunTransaction(&trans_2);
7982 CheckWasSpdyResponse(&trans_2);
7983 CheckResponsePort(&trans_2, 70);
7984 CheckResponseData(&trans_2, "0123456");
7985 EXPECT_TRUE(headers_handler_2.was_proxied());
7986 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7987
7988 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7989 // proxy socket to disconnect.
7990 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7991
7992 base::RunLoop().RunUntilIdle();
7993 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7994 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7995}
7996
7997// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147998TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567999 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148000 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568001 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498002 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568003
8004 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528005 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568006 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438007 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528008 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338009 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8010 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048011 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8012 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338013 &header_stream_offset));
8014 mock_quic_data.AddRead(
8015 ASYNC, ConstructServerResponseHeadersPacket(
8016 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8017 GetResponseHeaders("500")));
8018 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8019 mock_quic_data.AddWrite(SYNCHRONOUS,
8020 ConstructClientAckAndRstPacket(
8021 3, GetNthClientInitiatedBidirectionalStreamId(0),
8022 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568023
8024 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8025
8026 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8027
8028 CreateSession();
8029
8030 request_.url = GURL("https://mail.example.org/");
8031 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8032 HeadersHandler headers_handler;
8033 trans.SetBeforeHeadersSentCallback(
8034 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8035 base::Unretained(&headers_handler)));
8036 TestCompletionCallback callback;
8037 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8038 EXPECT_EQ(ERR_IO_PENDING, rv);
8039 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8040 EXPECT_EQ(false, headers_handler.was_proxied());
8041
8042 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8043 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8044}
8045
8046// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148047TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568048 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148049 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568050 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498051 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568052
8053 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528054 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568055 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438056 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338057 mock_quic_data.AddWrite(
8058 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8059 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048060 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8061 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338062 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568063 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8064
8065 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8066
8067 CreateSession();
8068
8069 request_.url = GURL("https://mail.example.org/");
8070 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8071 HeadersHandler headers_handler;
8072 trans.SetBeforeHeadersSentCallback(
8073 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8074 base::Unretained(&headers_handler)));
8075 TestCompletionCallback callback;
8076 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8077 EXPECT_EQ(ERR_IO_PENDING, rv);
8078 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8079
8080 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8081 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8082}
8083
8084// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8085// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148086TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568087 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148088 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568089 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498090 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568091
8092 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528093 quic::QuicStreamOffset client_header_stream_offset = 0;
8094 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358095 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8096 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338097 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358098 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8099 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048100 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8101 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:358102 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438103 mock_quic_data.AddRead(
8104 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338105 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438106 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358107 mock_quic_data.AddWrite(SYNCHRONOUS,
8108 ConstructClientAckAndRstPacket(
8109 3, GetNthClientInitiatedBidirectionalStreamId(0),
8110 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568111
Zhongyi Shi32f2fd02018-04-16 18:23:438112 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358113 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8114 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Matt Menke6e879bd2019-03-18 17:26:048115 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8116 ConnectRequestHeaders("mail.example.org:443"),
Renjied172e812019-01-16 05:12:358117 GetNthClientInitiatedBidirectionalStreamId(0),
8118 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438119 mock_quic_data.AddRead(
8120 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338121 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438122 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568123
8124 const char get_request[] =
8125 "GET / HTTP/1.1\r\n"
8126 "Host: mail.example.org\r\n"
8127 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438128 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568129 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418130 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358131 SYNCHRONOUS,
8132 ConstructClientAckAndDataPacket(
8133 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8134 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418135 } else {
8136 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418137 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358138 ConstructClientAckAndMultipleDataFramesPacket(
8139 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Victor Vasiliev076657c2019-03-12 02:46:438140 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418141 }
Yixin Wang46a273ec302018-01-23 17:59:568142 const char get_response[] =
8143 "HTTP/1.1 200 OK\r\n"
8144 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438145 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438146 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338147 ASYNC, ConstructServerDataPacket(
8148 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438149 0, header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528150
Victor Vasiliev076657c2019-03-12 02:46:438151 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338152 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418153 SYNCHRONOUS, ConstructServerDataPacket(
8154 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8155 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:438156 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:358157 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568158 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8159
8160 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418161 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358162 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8163 quic::QUIC_STREAM_CANCELLED,
8164 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568165
8166 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8167
8168 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8169 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8170
8171 SSLSocketDataProvider ssl_data(ASYNC, OK);
8172 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8173
8174 CreateSession();
8175
8176 request_.url = GURL("https://mail.example.org/");
8177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8178 HeadersHandler headers_handler;
8179 trans.SetBeforeHeadersSentCallback(
8180 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8181 base::Unretained(&headers_handler)));
8182 TestCompletionCallback callback;
8183 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8184 EXPECT_EQ(ERR_IO_PENDING, rv);
8185 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8186
8187 rv = trans.RestartIgnoringLastError(callback.callback());
8188 EXPECT_EQ(ERR_IO_PENDING, rv);
8189 EXPECT_EQ(OK, callback.WaitForResult());
8190
8191 CheckWasHttpResponse(&trans);
8192 CheckResponsePort(&trans, 70);
8193 CheckResponseData(&trans, "0123456789");
8194 EXPECT_EQ(true, headers_handler.was_proxied());
8195 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8196
8197 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8198 // proxy socket to disconnect.
8199 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8200
8201 base::RunLoop().RunUntilIdle();
8202 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8203 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8204}
8205
8206// Checks if a request's specified "user-agent" header shows up correctly in the
8207// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148208TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008209 const char kConfiguredUserAgent[] = "Configured User-Agent";
8210 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568211 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148212 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568213 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498214 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568215
8216 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528217 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568218 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438219 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568220
Ryan Hamilton0239aac2018-05-19 00:03:138221 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008222 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338223 mock_quic_data.AddWrite(
8224 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8225 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048226 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8227 std::move(headers), 0, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568228 // Return an error, so the transaction stops here (this test isn't interested
8229 // in the rest).
8230 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8231
8232 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8233
Matt Menked732ea42019-03-08 12:05:008234 StaticHttpUserAgentSettings http_user_agent_settings(
8235 std::string() /* accept_language */, kConfiguredUserAgent);
8236 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568237 CreateSession();
8238
8239 request_.url = GURL("https://mail.example.org/");
8240 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008241 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8243 HeadersHandler headers_handler;
8244 trans.SetBeforeHeadersSentCallback(
8245 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8246 base::Unretained(&headers_handler)));
8247 TestCompletionCallback callback;
8248 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8249 EXPECT_EQ(ERR_IO_PENDING, rv);
8250 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8251
8252 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8253 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8254}
8255
Yixin Wang00fc44c2018-01-23 21:12:208256// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8257// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148258TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208259 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148260 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208261 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498262 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208263
8264 const RequestPriority request_priority = MEDIUM;
8265
8266 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528267 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208268 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438269 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8270 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048271 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8272 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8273 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8274 ConnectRequestHeaders("mail.example.org:443"), 0,
8275 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208276 // Return an error, so the transaction stops here (this test isn't interested
8277 // in the rest).
8278 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8279
8280 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8281
8282 CreateSession();
8283
8284 request_.url = GURL("https://mail.example.org/");
8285 HttpNetworkTransaction trans(request_priority, session_.get());
8286 TestCompletionCallback callback;
8287 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8288 EXPECT_EQ(ERR_IO_PENDING, rv);
8289 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8290
8291 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8292 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8293}
8294
Matt Menkeedaf3b82019-03-14 21:39:448295// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8296// HTTP/2 stream dependency and weights given the request priority.
8297TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8298 session_params_.enable_quic = true;
8299 session_params_.enable_quic_proxies_for_https_urls = true;
8300 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8301 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8302
8303 const RequestPriority kRequestPriority = MEDIUM;
8304 const RequestPriority kRequestPriority2 = LOWEST;
8305
8306 MockQuicData mock_quic_data;
8307 quic::QuicStreamOffset header_stream_offset = 0;
8308 mock_quic_data.AddWrite(
8309 ASYNC, ConstructInitialSettingsPacket(1, &header_stream_offset));
8310 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8311 // This should never be reached.
8312 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8313 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8314
8315 // Second connection attempt just fails - result doesn't really matter.
8316 MockQuicData mock_quic_data2;
8317 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8318 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8319
8320 int original_max_sockets_per_group =
8321 ClientSocketPoolManager::max_sockets_per_group(
8322 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8323 ClientSocketPoolManager::set_max_sockets_per_group(
8324 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8325 int original_max_sockets_per_pool =
8326 ClientSocketPoolManager::max_sockets_per_pool(
8327 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8328 ClientSocketPoolManager::set_max_sockets_per_pool(
8329 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8330 CreateSession();
8331
8332 request_.url = GURL("https://mail.example.org/");
8333 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8334 TestCompletionCallback callback;
8335 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8336 EXPECT_EQ(ERR_IO_PENDING, rv);
8337
8338 HttpRequestInfo request2;
8339 request2.url = GURL("https://mail.example.org/some/other/path/");
8340 request2.traffic_annotation =
8341 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8342
8343 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8344 TestCompletionCallback callback2;
8345 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8346 EXPECT_EQ(ERR_IO_PENDING, rv2);
8347
8348 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8349 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8350
8351 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8352
8353 ClientSocketPoolManager::set_max_sockets_per_pool(
8354 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8355 original_max_sockets_per_pool);
8356 ClientSocketPoolManager::set_max_sockets_per_group(
8357 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8358 original_max_sockets_per_group);
8359}
8360
Yixin Wang46a273ec302018-01-23 17:59:568361// Test the request-challenge-retry sequence for basic auth, over a QUIC
8362// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148363TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568364 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8365 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568366
8367 std::unique_ptr<QuicTestPacketMaker> client_maker;
8368 std::unique_ptr<QuicTestPacketMaker> server_maker;
8369
8370 // On the second pass, the body read of the auth challenge is synchronous, so
8371 // IsConnectedAndIdle returns false. The socket should still be drained and
8372 // reused. See http://crbug.com/544255.
8373 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338374 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178375 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8376 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338377 client_headers_include_h2_stream_dependency_));
8378 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178379 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8380 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568381
8382 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148383 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568384 proxy_resolution_service_ =
8385 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498386 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568387
8388 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528389 quic::QuicStreamOffset client_header_stream_offset = 0;
8390 quic::QuicStreamOffset server_header_stream_offset = 0;
8391 quic::QuicStreamOffset client_data_offset = 0;
8392 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568393
Zhongyi Shi32f2fd02018-04-16 18:23:438394 mock_quic_data.AddWrite(SYNCHRONOUS,
8395 client_maker->MakeInitialSettingsPacket(
8396 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568397
8398 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438399 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568400 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338401 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
Matt Menke6e879bd2019-03-18 17:26:048402 ConvertRequestPriorityToQuicPriority(
8403 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568404 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8405 &client_header_stream_offset));
8406
Ryan Hamilton0239aac2018-05-19 00:03:138407 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568408 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8409 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8410 headers["content-length"] = "10";
8411 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438412 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338413 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8414 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568415
8416 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438417 mock_quic_data.AddRead(
8418 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338419 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8420 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568421 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438422 mock_quic_data.AddRead(
8423 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338424 2, GetNthClientInitiatedBidirectionalStreamId(0),
8425 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568426 }
8427 server_data_offset += 10;
8428
Zhongyi Shi32f2fd02018-04-16 18:23:438429 mock_quic_data.AddWrite(SYNCHRONOUS,
8430 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568431
8432 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338433 SYNCHRONOUS,
8434 client_maker->MakeRstPacket(
8435 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188436 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8437 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568438
8439 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8440 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8441 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048442 SYNCHRONOUS,
8443 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8444 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8445 ConvertRequestPriorityToQuicPriority(
8446 HttpProxyConnectJob::kH2QuicTunnelPriority),
8447 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
8448 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568449
8450 // Response to wrong password
8451 headers =
8452 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8453 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8454 headers["content-length"] = "10";
8455 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438456 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338457 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8458 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568459 mock_quic_data.AddRead(SYNCHRONOUS,
8460 ERR_IO_PENDING); // No more data to read
8461
Fan Yang32c5a112018-12-10 20:06:338462 mock_quic_data.AddWrite(
8463 SYNCHRONOUS,
8464 client_maker->MakeAckAndRstPacket(
8465 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8466 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568467
8468 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8469 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8470
8471 CreateSession();
8472
8473 request_.url = GURL("https://mail.example.org/");
8474 // Ensure that proxy authentication is attempted even
8475 // when the no authentication data flag is set.
8476 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8477 {
8478 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8479 HeadersHandler headers_handler;
8480 trans.SetBeforeHeadersSentCallback(
8481 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8482 base::Unretained(&headers_handler)));
8483 RunTransaction(&trans);
8484
8485 const HttpResponseInfo* response = trans.GetResponseInfo();
8486 ASSERT_TRUE(response != nullptr);
8487 ASSERT_TRUE(response->headers.get() != nullptr);
8488 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8489 response->headers->GetStatusLine());
8490 EXPECT_TRUE(response->headers->IsKeepAlive());
8491 EXPECT_EQ(407, response->headers->response_code());
8492 EXPECT_EQ(10, response->headers->GetContentLength());
8493 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588494 base::Optional<AuthChallengeInfo> auth_challenge =
8495 response->auth_challenge;
8496 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568497 EXPECT_TRUE(auth_challenge->is_proxy);
8498 EXPECT_EQ("https://proxy.example.org:70",
8499 auth_challenge->challenger.Serialize());
8500 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8501 EXPECT_EQ("basic", auth_challenge->scheme);
8502
8503 TestCompletionCallback callback;
8504 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8505 callback.callback());
8506 EXPECT_EQ(ERR_IO_PENDING, rv);
8507 EXPECT_EQ(OK, callback.WaitForResult());
8508
8509 response = trans.GetResponseInfo();
8510 ASSERT_TRUE(response != nullptr);
8511 ASSERT_TRUE(response->headers.get() != nullptr);
8512 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8513 response->headers->GetStatusLine());
8514 EXPECT_TRUE(response->headers->IsKeepAlive());
8515 EXPECT_EQ(407, response->headers->response_code());
8516 EXPECT_EQ(10, response->headers->GetContentLength());
8517 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588518 auth_challenge = response->auth_challenge;
8519 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568520 EXPECT_TRUE(auth_challenge->is_proxy);
8521 EXPECT_EQ("https://proxy.example.org:70",
8522 auth_challenge->challenger.Serialize());
8523 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8524 EXPECT_EQ("basic", auth_challenge->scheme);
8525 }
8526 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8527 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8528 // reused because it's not connected).
8529 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8530 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8531 }
8532}
8533
Yixin Wang385652a2018-02-16 02:37:238534TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8535 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8536 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568537 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238538 !client_headers_include_h2_stream_dependency_) {
8539 return;
8540 }
8541
8542 session_params_.origins_to_force_quic_on.insert(
8543 HostPortPair::FromString("mail.example.org:443"));
8544
Fan Yang32c5a112018-12-10 20:06:338545 const quic::QuicStreamId client_stream_0 =
8546 GetNthClientInitiatedBidirectionalStreamId(0);
8547 const quic::QuicStreamId client_stream_1 =
8548 GetNthClientInitiatedBidirectionalStreamId(1);
8549 const quic::QuicStreamId client_stream_2 =
8550 GetNthClientInitiatedBidirectionalStreamId(2);
8551 const quic::QuicStreamId push_stream_0 =
8552 GetNthServerInitiatedUnidirectionalStreamId(0);
8553 const quic::QuicStreamId push_stream_1 =
8554 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238555
8556 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528557 quic::QuicStreamOffset header_stream_offset = 0;
8558 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238559 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438560 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238561
8562 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438563 mock_quic_data.AddWrite(SYNCHRONOUS,
8564 ConstructClientRequestHeadersPacket(
8565 2, client_stream_0, true, true, HIGHEST,
8566 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8567 &header_stream_offset));
8568 mock_quic_data.AddWrite(SYNCHRONOUS,
8569 ConstructClientRequestHeadersPacket(
8570 3, client_stream_1, true, true, MEDIUM,
8571 GetRequestHeaders("GET", "https", "/1.jpg"),
8572 client_stream_0, &header_stream_offset));
8573 mock_quic_data.AddWrite(SYNCHRONOUS,
8574 ConstructClientRequestHeadersPacket(
8575 4, client_stream_2, true, true, MEDIUM,
8576 GetRequestHeaders("GET", "https", "/2.jpg"),
8577 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238578
8579 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438580 mock_quic_data.AddRead(
8581 ASYNC, ConstructServerResponseHeadersPacket(
8582 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8583 &server_header_offset));
8584 mock_quic_data.AddRead(
8585 ASYNC, ConstructServerResponseHeadersPacket(
8586 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8587 &server_header_offset));
8588 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8589 mock_quic_data.AddRead(
8590 ASYNC, ConstructServerResponseHeadersPacket(
8591 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8592 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238593
8594 // Server sends two push promises associated with |client_stream_0|; client
8595 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8596 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438597 mock_quic_data.AddRead(ASYNC,
8598 ConstructServerPushPromisePacket(
8599 4, client_stream_0, push_stream_0, false,
8600 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8601 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238602 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438603 SYNCHRONOUS,
8604 ConstructClientAckAndPriorityFramesPacket(
8605 6, false, 4, 3, 1,
8606 {{push_stream_0, client_stream_2,
8607 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8608 &header_stream_offset));
8609 mock_quic_data.AddRead(ASYNC,
8610 ConstructServerPushPromisePacket(
8611 5, client_stream_0, push_stream_1, false,
8612 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8613 &server_header_offset, &server_maker_));
8614 mock_quic_data.AddWrite(
8615 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238616 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8617 DEFAULT_PRIORITY, &header_stream_offset));
8618
8619 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438620 mock_quic_data.AddRead(
8621 ASYNC, ConstructServerResponseHeadersPacket(
8622 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8623 &server_header_offset));
8624 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8625 mock_quic_data.AddRead(
8626 ASYNC, ConstructServerResponseHeadersPacket(
8627 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8628 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238629
8630 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8631 // priority updates to match the request's priority. Client sends PRIORITY
8632 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438633 mock_quic_data.AddWrite(
8634 SYNCHRONOUS,
8635 ConstructClientAckAndPriorityFramesPacket(
8636 9, false, 7, 7, 1,
8637 {{push_stream_1, client_stream_2,
8638 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8639 {push_stream_0, client_stream_0,
8640 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8641 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238642
8643 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438644 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438645 mock_quic_data.AddRead(
8646 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418647 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438648 mock_quic_data.AddRead(
8649 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418650 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438651 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8652 mock_quic_data.AddRead(
8653 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418654 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438655 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438656 mock_quic_data.AddRead(
8657 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418658 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438659 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8660 mock_quic_data.AddRead(
8661 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418662 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238663
Yixin Wang385652a2018-02-16 02:37:238664 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8665 mock_quic_data.AddRead(ASYNC, 0); // EOF
8666 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8667
8668 // The non-alternate protocol job needs to hang in order to guarantee that
8669 // the alternate-protocol job will "win".
8670 AddHangingNonAlternateProtocolSocketData();
8671
8672 CreateSession();
8673
8674 request_.url = GURL("https://mail.example.org/0.jpg");
8675 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8676 TestCompletionCallback callback_0;
8677 EXPECT_EQ(ERR_IO_PENDING,
8678 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8679 base::RunLoop().RunUntilIdle();
8680
8681 request_.url = GURL("https://mail.example.org/1.jpg");
8682 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8683 TestCompletionCallback callback_1;
8684 EXPECT_EQ(ERR_IO_PENDING,
8685 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8686 base::RunLoop().RunUntilIdle();
8687
8688 request_.url = GURL("https://mail.example.org/2.jpg");
8689 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8690 TestCompletionCallback callback_2;
8691 EXPECT_EQ(ERR_IO_PENDING,
8692 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8693 base::RunLoop().RunUntilIdle();
8694
8695 // Client makes request that matches resource pushed in |pushed_stream_0|.
8696 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8697 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8698 TestCompletionCallback callback_3;
8699 EXPECT_EQ(ERR_IO_PENDING,
8700 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8701 base::RunLoop().RunUntilIdle();
8702
8703 EXPECT_TRUE(callback_0.have_result());
8704 EXPECT_EQ(OK, callback_0.WaitForResult());
8705 EXPECT_TRUE(callback_1.have_result());
8706 EXPECT_EQ(OK, callback_1.WaitForResult());
8707 EXPECT_TRUE(callback_2.have_result());
8708 EXPECT_EQ(OK, callback_2.WaitForResult());
8709
8710 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8711 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8712 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8713 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8714
8715 mock_quic_data.Resume();
8716 base::RunLoop().RunUntilIdle();
8717 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8718 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8719}
8720
[email protected]61a527782013-02-21 03:58:008721} // namespace test
8722} // namespace net