blob: ca519c5d65c5bbcc856ed6650ff70f4cd13c8fdf [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.
1571 std::string advertised_versions_list_str =
Nick Harper23290b82019-05-02 00:02:561572 GenerateQuicVersionsListForAltSvcHeader(quic::AllSupportedVersions());
zhongyief3f4ce52017-07-05 23:53:281573 std::string altsvc_header =
1574 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1575 advertised_versions_list_str.c_str());
1576 MockRead http_reads[] = {
1577 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1578 MockRead("hello world"),
1579 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1580 MockRead(ASYNC, OK)};
1581
Ryan Sleevib8d7ea02018-05-07 20:01:011582 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281583 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081584 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281585 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1586
1587 // Second request should be sent via QUIC as a new list of verions supported
1588 // by the client has been advertised by the server.
1589 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521590 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281591 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431592 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1593 mock_quic_data.AddWrite(
1594 SYNCHRONOUS,
1595 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331596 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431597 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431598 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331599 ASYNC, ConstructServerResponseHeadersPacket(
1600 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1601 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431602 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331603 mock_quic_data.AddRead(
1604 ASYNC, ConstructServerDataPacket(
1605 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411606 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431607 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281608 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1609 mock_quic_data.AddRead(ASYNC, 0); // EOF
1610
1611 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1612
1613 AddHangingNonAlternateProtocolSocketData();
1614
1615 CreateSession(supported_versions_);
1616
1617 SendRequestAndExpectHttpResponse("hello world");
1618 SendRequestAndExpectQuicResponse("hello!");
1619
1620 // Check alternative service list is updated with new versions.
1621 alt_svc_info_vector =
1622 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1623 EXPECT_EQ(1u, alt_svc_info_vector.size());
1624 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1625 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1626 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:561627 std::sort(
1628 supported_versions_.begin(), supported_versions_.end(),
1629 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
1630 return a.transport_version < b.transport_version;
1631 });
zhongyief3f4ce52017-07-05 23:53:281632 EXPECT_EQ(supported_versions_[0],
1633 alt_svc_info_vector[0].advertised_versions()[0]);
1634 EXPECT_EQ(supported_versions_[1],
1635 alt_svc_info_vector[0].advertised_versions()[1]);
1636}
1637
bncaccd4962017-04-06 21:00:261638// Regression test for https://crbug.com/546991.
1639// The server might not be able to serve a request on an alternative connection,
1640// and might send a 421 Misdirected Request response status to indicate this.
1641// HttpNetworkTransaction should reset the request and retry without using
1642// alternative services.
1643TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1644 // Set up alternative service to use QUIC.
1645 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1646 // that overrides |enable_alternative_services|.
1647 url::SchemeHostPort server(request_.url);
1648 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1649 443);
1650 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211651 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441652 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261653
davidbena4449722017-05-05 23:30:531654 // First try: The alternative job uses QUIC and reports an HTTP 421
1655 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1656 // paused at Connect(), so it will never exit the socket pool. This ensures
1657 // that the alternate job always wins the race and keeps whether the
1658 // |http_data| exits the socket pool before the main job is aborted
1659 // deterministic. The first main job gets aborted without the socket pool ever
1660 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261661 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521662 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361663 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431664 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1665 mock_quic_data.AddWrite(
1666 SYNCHRONOUS,
1667 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331668 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431669 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331670 mock_quic_data.AddRead(
1671 ASYNC, ConstructServerResponseHeadersPacket(
1672 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1673 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261674 mock_quic_data.AddRead(ASYNC, OK);
1675 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1676
davidbena4449722017-05-05 23:30:531677 // Second try: The main job uses TCP, and there is no alternate job. Once the
1678 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1679 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261680 // Note that if there was an alternative QUIC Job created for the second try,
1681 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1682 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531683 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1684 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1685 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1686 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1687 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1688 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011689 reads, writes);
bncaccd4962017-04-06 21:00:261690 socket_factory_.AddSocketDataProvider(&http_data);
1691 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1692
bncaccd4962017-04-06 21:00:261693 CreateSession();
1694 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531695
1696 // Run until |mock_quic_data| has failed and |http_data| has paused.
1697 TestCompletionCallback callback;
1698 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1700 base::RunLoop().RunUntilIdle();
1701
1702 // |mock_quic_data| must have run to completion.
1703 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1704 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1705
1706 // Now that the QUIC data has been consumed, unblock |http_data|.
1707 http_data.socket()->OnConnectComplete(MockConnect());
1708
1709 // The retry logic must hide the 421 status. The transaction succeeds on
1710 // |http_data|.
1711 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261712 CheckWasHttpResponse(&trans);
1713 CheckResponsePort(&trans, 443);
1714 CheckResponseData(&trans, "hello!");
1715}
1716
[email protected]1e960032013-12-20 19:00:201717TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411718 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571719 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301720
tbansalfdf5665b2015-09-21 22:46:401721 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521722 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361723 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431724 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401725 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401726 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371727 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361728 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431729 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301730 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401731 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431732 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401733
1734 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1735 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301736
1737 CreateSession();
1738
tbansal0f56a39a2016-04-07 22:03:381739 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401740 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161741 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401742 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161743 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011744 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1745 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381746 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531747
1748 NetErrorDetails details;
1749 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521750 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401751 }
[email protected]cebe3282013-05-22 23:49:301752}
1753
tbansalc8a94ea2015-11-02 23:58:511754TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1755 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411756 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571757 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511758
1759 MockRead http_reads[] = {
1760 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1761 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1762 MockRead(ASYNC, OK)};
1763
Ryan Sleevib8d7ea02018-05-07 20:01:011764 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511765 socket_factory_.AddSocketDataProvider(&data);
1766 SSLSocketDataProvider ssl(ASYNC, OK);
1767 socket_factory_.AddSSLSocketDataProvider(&ssl);
1768
1769 CreateSession();
1770
1771 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381772 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511773}
1774
bncc958faa2015-07-31 18:14:521775TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521776 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561777 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1778 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521779 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1780 MockRead(ASYNC, OK)};
1781
Ryan Sleevib8d7ea02018-05-07 20:01:011782 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521783 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081784 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561785 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521786
1787 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521788 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361789 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431790 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1791 mock_quic_data.AddWrite(
1792 SYNCHRONOUS,
1793 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331794 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431795 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431796 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331797 ASYNC, ConstructServerResponseHeadersPacket(
1798 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1799 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431800 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331801 mock_quic_data.AddRead(
1802 ASYNC, ConstructServerDataPacket(
1803 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411804 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431805 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521806 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591807 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521808
1809 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1810
rtennetib8e80fb2016-05-16 00:12:091811 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321812 CreateSession();
bncc958faa2015-07-31 18:14:521813
1814 SendRequestAndExpectHttpResponse("hello world");
1815 SendRequestAndExpectQuicResponse("hello!");
1816}
1817
zhongyia00ca012017-07-06 23:36:391818TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1819 // Both server advertises and client supports two QUIC versions.
1820 // Only |version_| is advertised and supported.
1821 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1822 // PacketMakers are using |version_|.
1823
1824 // Add support for another QUIC version besides |version_| on the client side.
1825 // Also find a different version advertised by the server.
Nick Harper23290b82019-05-02 00:02:561826 quic::ParsedQuicVersion advertised_version_2 = quic::UnsupportedQuicVersion();
1827 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391828 if (version == version_)
1829 continue;
1830 if (supported_versions_.size() != 2) {
1831 supported_versions_.push_back(version);
1832 continue;
1833 }
1834 advertised_version_2 = version;
1835 break;
1836 }
Nick Harper23290b82019-05-02 00:02:561837 DCHECK_NE(advertised_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391838
Nick Harper23290b82019-05-02 00:02:561839 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1840 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1841 advertised_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391842
1843 MockRead http_reads[] = {
1844 MockRead("HTTP/1.1 200 OK\r\n"),
1845 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1846 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1847 MockRead(ASYNC, OK)};
1848
Ryan Sleevib8d7ea02018-05-07 20:01:011849 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391850 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081851 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391852 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1853
1854 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521855 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391856 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431857 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1858 mock_quic_data.AddWrite(
1859 SYNCHRONOUS,
1860 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331861 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431862 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431863 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331864 ASYNC, ConstructServerResponseHeadersPacket(
1865 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1866 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431867 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331868 mock_quic_data.AddRead(
1869 ASYNC, ConstructServerDataPacket(
1870 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411871 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431872 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391873 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1874 mock_quic_data.AddRead(ASYNC, 0); // EOF
1875
1876 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1877
1878 AddHangingNonAlternateProtocolSocketData();
1879 CreateSession(supported_versions_);
1880
1881 SendRequestAndExpectHttpResponse("hello world");
1882 SendRequestAndExpectQuicResponse("hello!");
1883}
1884
1885TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1886 // Client and server mutually support more than one QUIC_VERSION.
1887 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1888 // which is verified as the PacketMakers are using |version_|.
1889
Nick Harper23290b82019-05-02 00:02:561890 quic::ParsedQuicVersion common_version_2 = quic::UnsupportedQuicVersion();
1891 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyia00ca012017-07-06 23:36:391892 if (version == version_)
1893 continue;
1894 common_version_2 = version;
1895 break;
1896 }
Nick Harper23290b82019-05-02 00:02:561897 DCHECK_NE(common_version_2, quic::UnsupportedQuicVersion());
zhongyia00ca012017-07-06 23:36:391898
1899 supported_versions_.push_back(
1900 common_version_2); // Supported but unpreferred.
1901
1902 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
Nick Harper23290b82019-05-02 00:02:561903 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1904 common_version_2.transport_version, version_.transport_version);
zhongyia00ca012017-07-06 23:36:391905
1906 MockRead http_reads[] = {
1907 MockRead("HTTP/1.1 200 OK\r\n"),
1908 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1909 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1910 MockRead(ASYNC, OK)};
1911
Ryan Sleevib8d7ea02018-05-07 20:01:011912 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391913 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081914 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391915 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1916
1917 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521918 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391919 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431920 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1921 mock_quic_data.AddWrite(
1922 SYNCHRONOUS,
1923 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331924 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431925 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431926 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331927 ASYNC, ConstructServerResponseHeadersPacket(
1928 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1929 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431930 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331931 mock_quic_data.AddRead(
1932 ASYNC, ConstructServerDataPacket(
1933 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411934 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431935 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391936 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1937 mock_quic_data.AddRead(ASYNC, 0); // EOF
1938
1939 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1940
1941 AddHangingNonAlternateProtocolSocketData();
1942 CreateSession(supported_versions_);
1943
1944 SendRequestAndExpectHttpResponse("hello world");
1945 SendRequestAndExpectQuicResponse("hello!");
1946}
1947
rchf47265dc2016-03-21 21:33:121948TEST_P(QuicNetworkTransactionTest,
1949 UseAlternativeServiceWithProbabilityForQuic) {
1950 MockRead http_reads[] = {
1951 MockRead("HTTP/1.1 200 OK\r\n"),
1952 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1953 MockRead("hello world"),
1954 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1955 MockRead(ASYNC, OK)};
1956
Ryan Sleevib8d7ea02018-05-07 20:01:011957 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121958 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081959 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121960 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1961
1962 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521963 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361964 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431965 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1966 mock_quic_data.AddWrite(
1967 SYNCHRONOUS,
1968 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331969 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431970 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431971 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331972 ASYNC, ConstructServerResponseHeadersPacket(
1973 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1974 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431975 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331976 mock_quic_data.AddRead(
1977 ASYNC, ConstructServerDataPacket(
1978 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411979 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431980 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121981 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1982 mock_quic_data.AddRead(ASYNC, 0); // EOF
1983
1984 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1985
rtennetib8e80fb2016-05-16 00:12:091986 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121987 CreateSession();
1988
1989 SendRequestAndExpectHttpResponse("hello world");
1990 SendRequestAndExpectQuicResponse("hello!");
1991}
1992
zhongyi3d4a55e72016-04-22 20:36:461993TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1994 MockRead http_reads[] = {
1995 MockRead("HTTP/1.1 200 OK\r\n"),
1996 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1997 MockRead("hello world"),
1998 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1999 MockRead(ASYNC, OK)};
2000
Ryan Sleevib8d7ea02018-05-07 20:01:012001 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:462002 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082003 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462004 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2005
2006 CreateSession();
bncb26024382016-06-29 02:39:452007 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:462008 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452009 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462010 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402011 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462012 session_->http_server_properties();
2013 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2014 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2015 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462016 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342017 2u,
2018 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452019 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342020 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462021}
2022
2023TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2024 MockRead http_reads[] = {
2025 MockRead("HTTP/1.1 200 OK\r\n"),
2026 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2027 MockRead("hello world"),
2028 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2029 MockRead(ASYNC, OK)};
2030
Ryan Sleevib8d7ea02018-05-07 20:01:012031 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082032 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462033
2034 socket_factory_.AddSocketDataProvider(&http_data);
2035 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2036 socket_factory_.AddSocketDataProvider(&http_data);
2037 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2038
2039 CreateSession();
2040
2041 // Send https request and set alternative services if response header
2042 // advertises alternative service for mail.example.org.
2043 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402044 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462045 session_->http_server_properties();
2046
2047 const url::SchemeHostPort https_server(request_.url);
2048 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342049 EXPECT_EQ(
2050 2u,
2051 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462052
2053 // Send http request to the same origin but with diffrent scheme, should not
2054 // use QUIC.
2055 request_.url = GURL("http://mail.example.org:443");
2056 SendRequestAndExpectHttpResponse("hello world");
2057}
2058
zhongyie537a002017-06-27 16:48:212059TEST_P(QuicNetworkTransactionTest,
2060 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442061 // Add support for another QUIC version besides |version_|.
Nick Harper23290b82019-05-02 00:02:562062 for (const quic::ParsedQuicVersion& version : quic::AllSupportedVersions()) {
zhongyi86838d52017-06-30 01:19:442063 if (version == version_)
2064 continue;
2065 supported_versions_.push_back(version);
2066 break;
2067 }
2068
zhongyie537a002017-06-27 16:48:212069 std::string advertised_versions_list_str =
Nick Harper23290b82019-05-02 00:02:562070 GenerateQuicVersionsListForAltSvcHeader(quic::AllSupportedVersions());
zhongyie537a002017-06-27 16:48:212071 std::string altsvc_header =
2072 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2073 advertised_versions_list_str.c_str());
2074 MockRead http_reads[] = {
2075 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2076 MockRead("hello world"),
2077 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2078 MockRead(ASYNC, OK)};
2079
Ryan Sleevib8d7ea02018-05-07 20:01:012080 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212081 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082082 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212083 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2084
2085 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522086 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212087 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432088 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2089 mock_quic_data.AddWrite(
2090 SYNCHRONOUS,
2091 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332092 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432093 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432094 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332095 ASYNC, ConstructServerResponseHeadersPacket(
2096 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2097 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432098 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332099 mock_quic_data.AddRead(
2100 ASYNC, ConstructServerDataPacket(
2101 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412102 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432103 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212104 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2105 mock_quic_data.AddRead(ASYNC, 0); // EOF
2106
2107 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2108
2109 AddHangingNonAlternateProtocolSocketData();
2110
zhongyi86838d52017-06-30 01:19:442111 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212112
2113 SendRequestAndExpectHttpResponse("hello world");
2114 SendRequestAndExpectQuicResponse("hello!");
2115
2116 // Check alternative service is set with only mutually supported versions.
2117 const url::SchemeHostPort https_server(request_.url);
2118 const AlternativeServiceInfoVector alt_svc_info_vector =
2119 session_->http_server_properties()->GetAlternativeServiceInfos(
2120 https_server);
2121 EXPECT_EQ(1u, alt_svc_info_vector.size());
2122 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2123 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2124 // Advertised versions will be lised in a sorted order.
Nick Harper23290b82019-05-02 00:02:562125 std::sort(
2126 supported_versions_.begin(), supported_versions_.end(),
2127 [](const quic::ParsedQuicVersion& a, const quic::ParsedQuicVersion& b) {
2128 return a.transport_version < b.transport_version;
2129 });
zhongyi86838d52017-06-30 01:19:442130 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212131 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442132 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212133 alt_svc_info_vector[0].advertised_versions()[1]);
2134}
2135
danzh3134c2562016-08-12 14:07:522136TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
Nick Harper23290b82019-05-02 00:02:562137 std::string altsvc_header = base::StringPrintf(
2138 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_.transport_version);
bnc8be55ebb2015-10-30 14:12:072139 MockRead http_reads[] = {
2140 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2141 MockRead("hello world"),
2142 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2143 MockRead(ASYNC, OK)};
2144
Ryan Sleevib8d7ea02018-05-07 20:01:012145 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072146 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082147 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072148 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2149
2150 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522151 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362152 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432153 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2154 mock_quic_data.AddWrite(
2155 SYNCHRONOUS,
2156 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332157 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432158 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432159 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332160 ASYNC, ConstructServerResponseHeadersPacket(
2161 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2162 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432163 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332164 mock_quic_data.AddRead(
2165 ASYNC, ConstructServerDataPacket(
2166 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412167 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432168 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072169 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592170 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072171
2172 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2173
rtennetib8e80fb2016-05-16 00:12:092174 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322175 CreateSession();
bnc8be55ebb2015-10-30 14:12:072176
2177 SendRequestAndExpectHttpResponse("hello world");
2178 SendRequestAndExpectQuicResponse("hello!");
2179}
2180
zhongyi6b5a3892016-03-12 04:46:202181TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Nick Harper23290b82019-05-02 00:02:562182 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholz6e4c5382018-06-21 23:00:092183 // Not available under version 99
2184 return;
2185 }
zhongyi6b5a3892016-03-12 04:46:202186 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522187 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362188 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432189 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2190 mock_quic_data.AddWrite(
2191 SYNCHRONOUS,
2192 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332193 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432194 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332195 mock_quic_data.AddRead(
2196 ASYNC, ConstructServerResponseHeadersPacket(
2197 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2198 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202199 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522200 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432201 mock_quic_data.AddRead(SYNCHRONOUS,
2202 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522203 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432204 "connection migration with port change only"));
2205 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432206 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332207 mock_quic_data.AddRead(
2208 SYNCHRONOUS, ConstructServerDataPacket(
2209 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412210 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332211 mock_quic_data.AddWrite(SYNCHRONOUS,
2212 ConstructClientAckAndRstPacket(
2213 4, GetNthClientInitiatedBidirectionalStreamId(0),
2214 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202215 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2216 mock_quic_data.AddRead(ASYNC, 0); // EOF
2217
2218 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2219
2220 // The non-alternate protocol job needs to hang in order to guarantee that
2221 // the alternate-protocol job will "win".
2222 AddHangingNonAlternateProtocolSocketData();
2223
2224 // In order for a new QUIC session to be established via alternate-protocol
2225 // without racing an HTTP connection, we need the host resolution to happen
2226 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2227 // connection to the the server, in this test we require confirmation
2228 // before encrypting so the HTTP job will still start.
2229 host_resolver_.set_synchronous_mode(true);
2230 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2231 "");
zhongyi6b5a3892016-03-12 04:46:202232
2233 CreateSession();
2234 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272235 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202236
bnc691fda62016-08-12 00:43:162237 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202238 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362239 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202241
2242 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522243 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012244 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202245
2246 // Check whether this transaction is correctly marked as received a go-away
2247 // because of migrating port.
2248 NetErrorDetails details;
2249 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162250 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202251 EXPECT_TRUE(details.quic_port_migration_detected);
2252}
2253
Zhongyi Shia6b68d112018-09-24 07:49:032254// This test verifies that a new QUIC connection will be attempted on the
2255// alternate network if the original QUIC connection fails with idle timeout
2256// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2257// alternate network as well, QUIC is marked as broken and the brokenness will
2258// not expire when default network changes.
2259TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2260 SetUpTestForRetryConnectionOnAlternateNetwork();
2261
2262 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032263 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032264
2265 // The request will initially go out over QUIC.
2266 MockQuicData quic_data;
2267 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2268 int packet_num = 1;
2269 quic_data.AddWrite(SYNCHRONOUS,
2270 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2271 // Retranmit the handshake messages.
2272 quic_data.AddWrite(SYNCHRONOUS,
2273 client_maker_.MakeDummyCHLOPacket(packet_num++));
2274 quic_data.AddWrite(SYNCHRONOUS,
2275 client_maker_.MakeDummyCHLOPacket(packet_num++));
2276 quic_data.AddWrite(SYNCHRONOUS,
2277 client_maker_.MakeDummyCHLOPacket(packet_num++));
2278 quic_data.AddWrite(SYNCHRONOUS,
2279 client_maker_.MakeDummyCHLOPacket(packet_num++));
2280 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562281 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032282 quic_data.AddWrite(SYNCHRONOUS,
2283 client_maker_.MakeDummyCHLOPacket(packet_num++));
2284 }
2285 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2286 quic_data.AddWrite(SYNCHRONOUS,
2287 client_maker_.MakeConnectionClosePacket(
2288 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2289 "No recent network activity."));
2290 quic_data.AddSocketDataToFactory(&socket_factory_);
2291
2292 // Add successful TCP data so that TCP job will succeed.
2293 MockWrite http_writes[] = {
2294 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2295 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2296 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2297
2298 MockRead http_reads[] = {
2299 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2300 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2301 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2302 SequencedSocketData http_data(http_reads, http_writes);
2303 socket_factory_.AddSocketDataProvider(&http_data);
2304 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2305
2306 // Add data for the second QUIC connection to fail.
2307 MockQuicData quic_data2;
2308 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2309 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2310 quic_data2.AddSocketDataToFactory(&socket_factory_);
2311
2312 // Resolve the host resolution synchronously.
2313 host_resolver_.set_synchronous_mode(true);
2314 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2315 "");
Zhongyi Shia6b68d112018-09-24 07:49:032316
2317 CreateSession();
2318 session_->quic_stream_factory()->set_require_confirmation(true);
2319 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032320 QuicStreamFactoryPeer::SetAlarmFactory(
2321 session_->quic_stream_factory(),
2322 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2323 &clock_));
2324 // Add alternate protocol mapping to race QUIC and TCP.
2325 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2326 // peer.
2327 AddQuicAlternateProtocolMapping(
2328 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2329
2330 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2331 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362332 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032333 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2334
2335 // Pump the message loop to get the request started.
2336 // Request will be served with TCP job.
2337 base::RunLoop().RunUntilIdle();
2338 EXPECT_THAT(callback.WaitForResult(), IsOk());
2339 CheckResponseData(&trans, "TCP succeeds");
2340
2341 // Fire the retransmission alarm, from this point, connection will idle
2342 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062343 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182344 quic_fix_time_of_first_packet_sent_after_receiving)) {
2345 quic_task_runner_->RunNextTask();
2346 }
Zhongyi Shia6b68d112018-09-24 07:49:032347 // Fast forward to idle timeout the original connection. A new connection will
2348 // be kicked off on the alternate network.
2349 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2350 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2351 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2352
2353 // Run the message loop to execute posted tasks, which will report job status.
2354 base::RunLoop().RunUntilIdle();
2355
2356 // Verify that QUIC is marked as broken.
2357 ExpectBrokenAlternateProtocolMapping();
2358
2359 // Deliver a message to notify the new network becomes default, the brokenness
2360 // will not expire as QUIC is broken on both networks.
2361 scoped_mock_change_notifier_->mock_network_change_notifier()
2362 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2363 ExpectBrokenAlternateProtocolMapping();
2364
2365 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2366 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2367}
2368
2369// This test verifies that a new QUIC connection will be attempted on the
2370// alternate network if the original QUIC connection fails with idle timeout
2371// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2372// alternate network, QUIC is marked as broken. The brokenness will expire when
2373// the default network changes.
2374TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2375 SetUpTestForRetryConnectionOnAlternateNetwork();
2376
2377 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032378 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032379
2380 // The request will initially go out over QUIC.
2381 MockQuicData quic_data;
2382 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2383 int packet_num = 1;
2384 quic_data.AddWrite(SYNCHRONOUS,
2385 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2386 // Retranmit the handshake messages.
2387 quic_data.AddWrite(SYNCHRONOUS,
2388 client_maker_.MakeDummyCHLOPacket(packet_num++));
2389 quic_data.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeDummyCHLOPacket(packet_num++));
2391 quic_data.AddWrite(SYNCHRONOUS,
2392 client_maker_.MakeDummyCHLOPacket(packet_num++));
2393 quic_data.AddWrite(SYNCHRONOUS,
2394 client_maker_.MakeDummyCHLOPacket(packet_num++));
2395 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
Nick Harper23290b82019-05-02 00:02:562396 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032397 quic_data.AddWrite(SYNCHRONOUS,
2398 client_maker_.MakeDummyCHLOPacket(packet_num++));
2399 }
2400 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2401 quic_data.AddWrite(SYNCHRONOUS,
2402 client_maker_.MakeConnectionClosePacket(
2403 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2404 "No recent network activity."));
2405 quic_data.AddSocketDataToFactory(&socket_factory_);
2406
2407 // Add successful TCP data so that TCP job will succeed.
2408 MockWrite http_writes[] = {
2409 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2410 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2411 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2412
2413 MockRead http_reads[] = {
2414 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2415 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2416 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2417 SequencedSocketData http_data(http_reads, http_writes);
2418 socket_factory_.AddSocketDataProvider(&http_data);
2419 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2420
2421 // Quic connection will be retried on the alternate network after the initial
2422 // one fails on the default network.
2423 MockQuicData quic_data2;
2424 quic::QuicStreamOffset header_stream_offset = 0;
2425 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2426 quic_data2.AddWrite(SYNCHRONOUS,
2427 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2428
2429 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2430 quic_data2.AddWrite(SYNCHRONOUS,
2431 ConstructInitialSettingsPacket(2, &header_stream_offset));
2432 quic_data2.AddSocketDataToFactory(&socket_factory_);
2433
2434 // Resolve the host resolution synchronously.
2435 host_resolver_.set_synchronous_mode(true);
2436 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2437 "");
Zhongyi Shia6b68d112018-09-24 07:49:032438
2439 CreateSession();
2440 session_->quic_stream_factory()->set_require_confirmation(true);
2441 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032442 QuicStreamFactoryPeer::SetAlarmFactory(
2443 session_->quic_stream_factory(),
2444 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2445 &clock_));
2446 // Add alternate protocol mapping to race QUIC and TCP.
2447 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2448 // peer.
2449 AddQuicAlternateProtocolMapping(
2450 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2451
2452 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2453 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362454 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2456
2457 // Pump the message loop to get the request started.
2458 // Request will be served with TCP job.
2459 base::RunLoop().RunUntilIdle();
2460 EXPECT_THAT(callback.WaitForResult(), IsOk());
2461 CheckResponseData(&trans, "TCP succeeds");
2462
2463 // Fire the retransmission alarm, after which connection will idle
2464 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062465 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182466 quic_fix_time_of_first_packet_sent_after_receiving)) {
2467 quic_task_runner_->RunNextTask();
2468 }
Zhongyi Shia6b68d112018-09-24 07:49:032469 // Fast forward to idle timeout the original connection. A new connection will
2470 // be kicked off on the alternate network.
2471 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2472 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2473 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2474
2475 // The second connection hasn't finish handshake, verify that QUIC is not
2476 // marked as broken.
2477 ExpectQuicAlternateProtocolMapping();
2478 // Explicitly confirm the handshake on the second connection.
2479 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2480 quic::QuicSession::HANDSHAKE_CONFIRMED);
2481 // Run message loop to execute posted tasks, which will notify JoController
2482 // about the orphaned job status.
2483 base::RunLoop().RunUntilIdle();
2484
2485 // Verify that QUIC is marked as broken.
2486 ExpectBrokenAlternateProtocolMapping();
2487
2488 // Deliver a message to notify the new network becomes default, the previous
2489 // brokenness will be clear as the brokenness is bond with old default
2490 // network.
2491 scoped_mock_change_notifier_->mock_network_change_notifier()
2492 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2493 ExpectQuicAlternateProtocolMapping();
2494
2495 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2496 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2497}
2498
2499// This test verifies that a new QUIC connection will be attempted on the
2500// alternate network if the original QUIC connection fails with idle timeout
2501// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2502// alternative network succeeds, QUIC is not marked as broken.
2503TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2504 SetUpTestForRetryConnectionOnAlternateNetwork();
2505
2506 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032507 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032508
2509 // The request will initially go out over QUIC.
2510 MockQuicData quic_data;
2511 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2512 int packet_num = 1;
2513 quic_data.AddWrite(SYNCHRONOUS,
2514 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2515 // Retranmit the handshake messages.
2516 quic_data.AddWrite(SYNCHRONOUS,
2517 client_maker_.MakeDummyCHLOPacket(packet_num++));
2518 quic_data.AddWrite(SYNCHRONOUS,
2519 client_maker_.MakeDummyCHLOPacket(packet_num++));
2520 quic_data.AddWrite(SYNCHRONOUS,
2521 client_maker_.MakeDummyCHLOPacket(packet_num++));
2522 quic_data.AddWrite(SYNCHRONOUS,
2523 client_maker_.MakeDummyCHLOPacket(packet_num++));
2524 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2525 // quic_fix_has_pending_crypto_data is introduced and enabled.
Nick Harper23290b82019-05-02 00:02:562526 if (version_.transport_version <= quic::QUIC_VERSION_39) {
Zhongyi Shia6b68d112018-09-24 07:49:032527 quic_data.AddWrite(SYNCHRONOUS,
2528 client_maker_.MakeDummyCHLOPacket(packet_num++));
2529 }
2530 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2531 quic_data.AddWrite(SYNCHRONOUS,
2532 client_maker_.MakeConnectionClosePacket(
2533 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2534 "No recent network activity."));
2535 quic_data.AddSocketDataToFactory(&socket_factory_);
2536
2537 // Add hanging TCP data so that TCP job will never succeeded.
2538 AddHangingNonAlternateProtocolSocketData();
2539
2540 // Quic connection will then be retried on the alternate network.
2541 MockQuicData quic_data2;
2542 quic::QuicStreamOffset header_stream_offset = 0;
2543 quic_data2.AddWrite(SYNCHRONOUS,
2544 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2545
Victor Vasiliev076657c2019-03-12 02:46:432546 const std::string body = "hello!";
2547 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412548
Zhongyi Shia6b68d112018-09-24 07:49:032549 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2550 quic_data2.AddWrite(SYNCHRONOUS,
2551 ConstructInitialSettingsPacket(2, &header_stream_offset));
2552 quic_data2.AddWrite(
2553 SYNCHRONOUS,
2554 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332555 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032556 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032557 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332558 ASYNC, ConstructServerResponseHeadersPacket(
2559 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2560 GetResponseHeaders("200 OK")));
2561 quic_data2.AddRead(
2562 ASYNC, ConstructServerDataPacket(
2563 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412564 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032565 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2566 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2567 quic_data2.AddSocketDataToFactory(&socket_factory_);
2568
2569 // Resolve the host resolution synchronously.
2570 host_resolver_.set_synchronous_mode(true);
2571 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2572 "");
Zhongyi Shia6b68d112018-09-24 07:49:032573
2574 CreateSession();
2575 session_->quic_stream_factory()->set_require_confirmation(true);
2576 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Zhongyi Shia6b68d112018-09-24 07:49:032577 QuicStreamFactoryPeer::SetAlarmFactory(
2578 session_->quic_stream_factory(),
2579 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2580 &clock_));
2581 // Add alternate protocol mapping to race QUIC and TCP.
2582 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2583 // peer.
2584 AddQuicAlternateProtocolMapping(
2585 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2586
2587 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2588 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362589 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032590 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2591
2592 // Pump the message loop to get the request started.
2593 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062594 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182595 quic_fix_time_of_first_packet_sent_after_receiving)) {
2596 quic_task_runner_->RunNextTask();
2597 }
Zhongyi Shia6b68d112018-09-24 07:49:032598
2599 // Fast forward to idle timeout the original connection. A new connection will
2600 // be kicked off on the alternate network.
2601 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2602 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2603 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2604
2605 // Verify that QUIC is not marked as broken.
2606 ExpectQuicAlternateProtocolMapping();
2607 // Explicitly confirm the handshake on the second connection.
2608 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2609 quic::QuicSession::HANDSHAKE_CONFIRMED);
2610
2611 // Read the response.
2612 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412613 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032614 // Verify that QUIC is not marked as broken.
2615 ExpectQuicAlternateProtocolMapping();
2616
2617 // Deliver a message to notify the new network becomes default.
2618 scoped_mock_change_notifier_->mock_network_change_notifier()
2619 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2620 ExpectQuicAlternateProtocolMapping();
2621 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2622 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2623}
2624
rch9ecde09b2017-04-08 00:18:232625// Verify that if a QUIC connection times out, the QuicHttpStream will
2626// return QUIC_PROTOCOL_ERROR.
2627TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482628 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412629 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232630
2631 // The request will initially go out over QUIC.
2632 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522633 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132634 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232635 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2636
2637 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032638 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432639 quic_data.AddWrite(SYNCHRONOUS,
2640 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332641 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2642 true, priority, GetRequestHeaders("GET", "https", "/"),
2643 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232644
2645 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522646 quic::QuicStreamOffset settings_offset = header_stream_offset;
2647 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432648 quic_data.AddWrite(SYNCHRONOUS,
2649 client_maker_.MakeInitialSettingsPacketAndSaveData(
2650 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232651 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522652 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562653 SYNCHRONOUS,
2654 client_maker_.MakeDataPacket(
2655 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2656 true, false, 0, request_data));
2657 // TLP 2
2658 quic_data.AddWrite(
2659 SYNCHRONOUS,
2660 client_maker_.MakeDataPacket(
2661 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2662 true, false, settings_offset, settings_data));
2663 // RTO 1
2664 quic_data.AddWrite(
2665 SYNCHRONOUS,
2666 client_maker_.MakeDataPacket(
2667 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2668 true, false, 0, request_data));
2669 quic_data.AddWrite(
2670 SYNCHRONOUS,
2671 client_maker_.MakeDataPacket(
2672 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2673 true, false, settings_offset, settings_data));
2674 // RTO 2
2675 quic_data.AddWrite(
2676 SYNCHRONOUS,
2677 client_maker_.MakeDataPacket(
2678 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2679 true, false, 0, request_data));
2680 quic_data.AddWrite(
2681 SYNCHRONOUS,
2682 client_maker_.MakeDataPacket(
2683 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2684 true, false, settings_offset, settings_data));
2685 // RTO 3
2686 quic_data.AddWrite(
2687 SYNCHRONOUS,
2688 client_maker_.MakeDataPacket(
2689 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2690 true, false, 0, request_data));
2691 quic_data.AddWrite(
2692 SYNCHRONOUS,
2693 client_maker_.MakeDataPacket(
2694 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2695 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232696
Zhongyi Shi32f2fd02018-04-16 18:23:432697 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522698 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432699 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222700
rch9ecde09b2017-04-08 00:18:232701 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2702 quic_data.AddRead(ASYNC, OK);
2703 quic_data.AddSocketDataToFactory(&socket_factory_);
2704
2705 // In order for a new QUIC session to be established via alternate-protocol
2706 // without racing an HTTP connection, we need the host resolution to happen
2707 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2708 // connection to the the server, in this test we require confirmation
2709 // before encrypting so the HTTP job will still start.
2710 host_resolver_.set_synchronous_mode(true);
2711 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2712 "");
rch9ecde09b2017-04-08 00:18:232713
2714 CreateSession();
2715 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232716 QuicStreamFactoryPeer::SetAlarmFactory(
2717 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192718 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552719 &clock_));
rch9ecde09b2017-04-08 00:18:232720
Ryan Hamilton9835e662018-08-02 05:36:272721 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232722
2723 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2724 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362725 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2727
2728 // Pump the message loop to get the request started.
2729 base::RunLoop().RunUntilIdle();
2730 // Explicitly confirm the handshake.
2731 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522732 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232733
2734 // Run the QUIC session to completion.
2735 quic_task_runner_->RunUntilIdle();
2736
2737 ExpectQuicAlternateProtocolMapping();
2738 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2739 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2740}
2741
2742// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2743// return QUIC_PROTOCOL_ERROR.
2744TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482745 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522746 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232747
2748 // The request will initially go out over QUIC.
2749 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522750 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132751 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232752 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2753
2754 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032755 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432756 quic_data.AddWrite(SYNCHRONOUS,
2757 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332758 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2759 true, priority, GetRequestHeaders("GET", "https", "/"),
2760 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232761
2762 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522763 quic::QuicStreamOffset settings_offset = header_stream_offset;
2764 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432765 quic_data.AddWrite(SYNCHRONOUS,
2766 client_maker_.MakeInitialSettingsPacketAndSaveData(
2767 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232768 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:522769 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562770 SYNCHRONOUS,
2771 client_maker_.MakeDataPacket(
2772 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2773 true, false, 0, request_data));
2774 // TLP 2
2775 quic_data.AddWrite(
2776 SYNCHRONOUS,
2777 client_maker_.MakeDataPacket(
2778 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2779 true, false, settings_offset, settings_data));
2780 // RTO 1
2781 quic_data.AddWrite(
2782 SYNCHRONOUS,
2783 client_maker_.MakeDataPacket(
2784 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2785 true, false, 0, request_data));
2786 quic_data.AddWrite(
2787 SYNCHRONOUS,
2788 client_maker_.MakeDataPacket(
2789 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2790 true, false, settings_offset, settings_data));
2791 // RTO 2
2792 quic_data.AddWrite(
2793 SYNCHRONOUS,
2794 client_maker_.MakeDataPacket(
2795 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2796 true, false, 0, request_data));
2797 quic_data.AddWrite(
2798 SYNCHRONOUS,
2799 client_maker_.MakeDataPacket(
2800 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2801 true, false, settings_offset, settings_data));
2802 // RTO 3
2803 quic_data.AddWrite(
2804 SYNCHRONOUS,
2805 client_maker_.MakeDataPacket(
2806 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2807 true, false, 0, request_data));
2808 quic_data.AddWrite(
2809 SYNCHRONOUS,
2810 client_maker_.MakeDataPacket(
2811 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2812 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232813 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522814 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562815 SYNCHRONOUS,
2816 client_maker_.MakeDataPacket(
2817 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2818 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:092819 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562820 SYNCHRONOUS,
2821 client_maker_.MakeDataPacket(
2822 12, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2823 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232824 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432825 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522826 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432827 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232828
2829 quic_data.AddRead(ASYNC, OK);
2830 quic_data.AddSocketDataToFactory(&socket_factory_);
2831
2832 // In order for a new QUIC session to be established via alternate-protocol
2833 // without racing an HTTP connection, we need the host resolution to happen
2834 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2835 // connection to the the server, in this test we require confirmation
2836 // before encrypting so the HTTP job will still start.
2837 host_resolver_.set_synchronous_mode(true);
2838 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2839 "");
rch9ecde09b2017-04-08 00:18:232840
2841 CreateSession();
2842 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232843 QuicStreamFactoryPeer::SetAlarmFactory(
2844 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192845 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552846 &clock_));
rch9ecde09b2017-04-08 00:18:232847
Ryan Hamilton9835e662018-08-02 05:36:272848 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232849
2850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2851 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362852 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2854
2855 // Pump the message loop to get the request started.
2856 base::RunLoop().RunUntilIdle();
2857 // Explicitly confirm the handshake.
2858 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522859 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232860
2861 // Run the QUIC session to completion.
2862 quic_task_runner_->RunUntilIdle();
2863
2864 ExpectQuicAlternateProtocolMapping();
2865 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2866 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2867}
2868
2869// Verify that if a QUIC connection RTOs, while there are no active streams
2870// QUIC will not be marked as broken.
2871TEST_P(QuicNetworkTransactionTest,
2872 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522873 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232874
2875 // The request will initially go out over QUIC.
2876 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522877 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132878 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232879 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2880
2881 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032882 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432883 quic_data.AddWrite(SYNCHRONOUS,
2884 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332885 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2886 true, priority, GetRequestHeaders("GET", "https", "/"),
2887 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232888
2889 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522890 quic::QuicStreamOffset settings_offset = header_stream_offset;
2891 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432892 quic_data.AddWrite(SYNCHRONOUS,
2893 client_maker_.MakeInitialSettingsPacketAndSaveData(
2894 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232895
Fan Yang32c5a112018-12-10 20:06:332896 quic_data.AddWrite(SYNCHRONOUS,
2897 client_maker_.MakeRstPacket(
2898 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2899 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232900 // TLP 1
Nick Harper23290b82019-05-02 00:02:562901 quic_data.AddWrite(
2902 SYNCHRONOUS,
2903 client_maker_.MakeDataPacket(
2904 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2905 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232906 // TLP 2
Nick Harper23290b82019-05-02 00:02:562907 quic_data.AddWrite(
2908 SYNCHRONOUS,
2909 client_maker_.MakeDataPacket(
2910 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2911 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232912 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332913 quic_data.AddWrite(SYNCHRONOUS,
2914 client_maker_.MakeRstPacket(
2915 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2916 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:562917 quic_data.AddWrite(
2918 SYNCHRONOUS,
2919 client_maker_.MakeDataPacket(
2920 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2921 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232922 // RTO 2
Nick Harper23290b82019-05-02 00:02:562923 quic_data.AddWrite(
2924 SYNCHRONOUS,
2925 client_maker_.MakeDataPacket(
2926 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2927 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332928 quic_data.AddWrite(SYNCHRONOUS,
2929 client_maker_.MakeRstPacket(
2930 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2931 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232932 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522933 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562934 SYNCHRONOUS,
2935 client_maker_.MakeDataPacket(
2936 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2937 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:092938 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562939 SYNCHRONOUS,
2940 client_maker_.MakeDataPacket(
2941 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2942 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232943 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432944 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332945 SYNCHRONOUS, client_maker_.MakeRstPacket(
2946 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2947 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522948 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:562949 SYNCHRONOUS,
2950 client_maker_.MakeDataPacket(
2951 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
2952 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232953 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432954 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522955 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432956 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232957
2958 quic_data.AddRead(ASYNC, OK);
2959 quic_data.AddSocketDataToFactory(&socket_factory_);
2960
2961 // In order for a new QUIC session to be established via alternate-protocol
2962 // without racing an HTTP connection, we need the host resolution to happen
2963 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2964 // connection to the the server, in this test we require confirmation
2965 // before encrypting so the HTTP job will still start.
2966 host_resolver_.set_synchronous_mode(true);
2967 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2968 "");
rch9ecde09b2017-04-08 00:18:232969
2970 CreateSession();
2971 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:232972 QuicStreamFactoryPeer::SetAlarmFactory(
2973 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192974 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552975 &clock_));
rch9ecde09b2017-04-08 00:18:232976
Ryan Hamilton9835e662018-08-02 05:36:272977 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232978
Jeremy Roman0579ed62017-08-29 15:56:192979 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232980 session_.get());
2981 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362982 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2984
2985 // Pump the message loop to get the request started.
2986 base::RunLoop().RunUntilIdle();
2987 // Explicitly confirm the handshake.
2988 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522989 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232990
2991 // Now cancel the request.
2992 trans.reset();
2993
2994 // Run the QUIC session to completion.
2995 quic_task_runner_->RunUntilIdle();
2996
2997 ExpectQuicAlternateProtocolMapping();
2998
2999 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3000}
3001
rch2f2991c2017-04-13 19:28:173002// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3003// the request fails with QUIC_PROTOCOL_ERROR.
3004TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:483005 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173006 // The request will initially go out over QUIC.
3007 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523008 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033009 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433010 quic_data.AddWrite(
3011 SYNCHRONOUS,
3012 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333013 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433014 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523015 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433016 quic_data.AddWrite(SYNCHRONOUS,
3017 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173018 // Peer sending data from an non-existing stream causes this end to raise
3019 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333020 quic_data.AddRead(
3021 ASYNC, ConstructServerRstPacket(
3022 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3023 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173024 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433025 quic_data.AddWrite(SYNCHRONOUS,
3026 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523027 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3028 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173029 quic_data.AddSocketDataToFactory(&socket_factory_);
3030
3031 // In order for a new QUIC session to be established via alternate-protocol
3032 // without racing an HTTP connection, we need the host resolution to happen
3033 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3034 // connection to the the server, in this test we require confirmation
3035 // before encrypting so the HTTP job will still start.
3036 host_resolver_.set_synchronous_mode(true);
3037 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3038 "");
rch2f2991c2017-04-13 19:28:173039
3040 CreateSession();
3041
Ryan Hamilton9835e662018-08-02 05:36:273042 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173043
3044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3045 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363046 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3048
3049 // Pump the message loop to get the request started.
3050 base::RunLoop().RunUntilIdle();
3051 // Explicitly confirm the handshake.
3052 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523053 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173054
3055 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3056
3057 // Run the QUIC session to completion.
3058 base::RunLoop().RunUntilIdle();
3059 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3060 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3061
3062 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3063 ExpectQuicAlternateProtocolMapping();
3064 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3065}
3066
rch9ecde09b2017-04-08 00:18:233067// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3068// connection times out, then QUIC will be marked as broken and the request
3069// retried over TCP.
3070TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413071 session_params_.mark_quic_broken_when_network_blackholes = true;
3072 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233073
3074 // The request will initially go out over QUIC.
3075 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523076 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133077 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233078 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3079
3080 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033081 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433082 quic_data.AddWrite(SYNCHRONOUS,
3083 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333084 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3085 true, priority, GetRequestHeaders("GET", "https", "/"),
3086 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233087
3088 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523089 quic::QuicStreamOffset settings_offset = header_stream_offset;
3090 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433091 quic_data.AddWrite(SYNCHRONOUS,
3092 client_maker_.MakeInitialSettingsPacketAndSaveData(
3093 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233094 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523095 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563096 SYNCHRONOUS,
3097 client_maker_.MakeDataPacket(
3098 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3099 true, false, 0, request_data));
3100 // TLP 2
3101 quic_data.AddWrite(
3102 SYNCHRONOUS,
3103 client_maker_.MakeDataPacket(
3104 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3105 true, false, settings_offset, settings_data));
3106 // RTO 1
3107 quic_data.AddWrite(
3108 SYNCHRONOUS,
3109 client_maker_.MakeDataPacket(
3110 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3111 true, false, 0, request_data));
3112 quic_data.AddWrite(
3113 SYNCHRONOUS,
3114 client_maker_.MakeDataPacket(
3115 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3116 true, false, settings_offset, settings_data));
3117 // RTO 2
3118 quic_data.AddWrite(
3119 SYNCHRONOUS,
3120 client_maker_.MakeDataPacket(
3121 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3122 true, false, 0, request_data));
3123 quic_data.AddWrite(
3124 SYNCHRONOUS,
3125 client_maker_.MakeDataPacket(
3126 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3127 true, false, settings_offset, settings_data));
3128 // RTO 3
3129 quic_data.AddWrite(
3130 SYNCHRONOUS,
3131 client_maker_.MakeDataPacket(
3132 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3133 true, false, 0, request_data));
3134 quic_data.AddWrite(
3135 SYNCHRONOUS,
3136 client_maker_.MakeDataPacket(
3137 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3138 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233139
Zhongyi Shi32f2fd02018-04-16 18:23:433140 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523141 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433142 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223143
rch9ecde09b2017-04-08 00:18:233144 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3145 quic_data.AddRead(ASYNC, OK);
3146 quic_data.AddSocketDataToFactory(&socket_factory_);
3147
3148 // After that fails, it will be resent via TCP.
3149 MockWrite http_writes[] = {
3150 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3151 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3152 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3153
3154 MockRead http_reads[] = {
3155 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3156 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3157 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013158 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233159 socket_factory_.AddSocketDataProvider(&http_data);
3160 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3161
3162 // In order for a new QUIC session to be established via alternate-protocol
3163 // without racing an HTTP connection, we need the host resolution to happen
3164 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3165 // connection to the the server, in this test we require confirmation
3166 // before encrypting so the HTTP job will still start.
3167 host_resolver_.set_synchronous_mode(true);
3168 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3169 "");
rch9ecde09b2017-04-08 00:18:233170
3171 CreateSession();
3172 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233173 QuicStreamFactoryPeer::SetAlarmFactory(
3174 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193175 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553176 &clock_));
rch9ecde09b2017-04-08 00:18:233177
Ryan Hamilton9835e662018-08-02 05:36:273178 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233179
3180 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3181 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363182 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3184
3185 // Pump the message loop to get the request started.
3186 base::RunLoop().RunUntilIdle();
3187 // Explicitly confirm the handshake.
3188 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523189 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233190
3191 // Run the QUIC session to completion.
3192 quic_task_runner_->RunUntilIdle();
3193 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3194
3195 // Let the transaction proceed which will result in QUIC being marked
3196 // as broken and the request falling back to TCP.
3197 EXPECT_THAT(callback.WaitForResult(), IsOk());
3198
3199 ExpectBrokenAlternateProtocolMapping();
3200 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3201 ASSERT_FALSE(http_data.AllReadDataConsumed());
3202
3203 // Read the response body over TCP.
3204 CheckResponseData(&trans, "hello world");
3205 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3206 ASSERT_TRUE(http_data.AllReadDataConsumed());
3207}
3208
rch2f2991c2017-04-13 19:28:173209// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3210// connection times out, then QUIC will be marked as broken and the request
3211// retried over TCP.
3212TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413213 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173214
3215 // The request will initially go out over QUIC.
3216 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523217 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133218 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173219 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3220
3221 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033222 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433223 quic_data.AddWrite(SYNCHRONOUS,
3224 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333225 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3226 true, priority, GetRequestHeaders("GET", "https", "/"),
3227 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173228
3229 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523230 quic::QuicStreamOffset settings_offset = header_stream_offset;
3231 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433232 quic_data.AddWrite(SYNCHRONOUS,
3233 client_maker_.MakeInitialSettingsPacketAndSaveData(
3234 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173235 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523236 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563237 SYNCHRONOUS,
3238 client_maker_.MakeDataPacket(
3239 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3240 true, false, 0, request_data));
3241 // TLP 2
3242 quic_data.AddWrite(
3243 SYNCHRONOUS,
3244 client_maker_.MakeDataPacket(
3245 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3246 true, false, settings_offset, settings_data));
3247 // RTO 1
3248 quic_data.AddWrite(
3249 SYNCHRONOUS,
3250 client_maker_.MakeDataPacket(
3251 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3252 true, false, 0, request_data));
3253 quic_data.AddWrite(
3254 SYNCHRONOUS,
3255 client_maker_.MakeDataPacket(
3256 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3257 true, false, settings_offset, settings_data));
3258 // RTO 2
3259 quic_data.AddWrite(
3260 SYNCHRONOUS,
3261 client_maker_.MakeDataPacket(
3262 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3263 true, false, 0, request_data));
3264 quic_data.AddWrite(
3265 SYNCHRONOUS,
3266 client_maker_.MakeDataPacket(
3267 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3268 true, false, settings_offset, settings_data));
3269 // RTO 3
3270 quic_data.AddWrite(
3271 SYNCHRONOUS,
3272 client_maker_.MakeDataPacket(
3273 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3274 true, false, 0, request_data));
3275 quic_data.AddWrite(
3276 SYNCHRONOUS,
3277 client_maker_.MakeDataPacket(
3278 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3279 true, false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173280
Zhongyi Shi32f2fd02018-04-16 18:23:433281 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523282 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433283 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223284
rch2f2991c2017-04-13 19:28:173285 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3286 quic_data.AddRead(ASYNC, OK);
3287 quic_data.AddSocketDataToFactory(&socket_factory_);
3288
3289 // After that fails, it will be resent via TCP.
3290 MockWrite http_writes[] = {
3291 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3292 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3293 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3294
3295 MockRead http_reads[] = {
3296 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3297 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3298 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013299 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173300 socket_factory_.AddSocketDataProvider(&http_data);
3301 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3302
3303 // In order for a new QUIC session to be established via alternate-protocol
3304 // without racing an HTTP connection, we need the host resolution to happen
3305 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3306 // connection to the the server, in this test we require confirmation
3307 // before encrypting so the HTTP job will still start.
3308 host_resolver_.set_synchronous_mode(true);
3309 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3310 "");
rch2f2991c2017-04-13 19:28:173311
3312 CreateSession();
3313 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch2f2991c2017-04-13 19:28:173314 QuicStreamFactoryPeer::SetAlarmFactory(
3315 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193316 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553317 &clock_));
rch2f2991c2017-04-13 19:28:173318
Ryan Hamilton9835e662018-08-02 05:36:273319 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173320
3321 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3322 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363323 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3325
3326 // Pump the message loop to get the request started.
3327 base::RunLoop().RunUntilIdle();
3328 // Explicitly confirm the handshake.
3329 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523330 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173331
3332 // Run the QUIC session to completion.
3333 quic_task_runner_->RunUntilIdle();
3334 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3335
3336 ExpectQuicAlternateProtocolMapping();
3337
3338 // Let the transaction proceed which will result in QUIC being marked
3339 // as broken and the request falling back to TCP.
3340 EXPECT_THAT(callback.WaitForResult(), IsOk());
3341
3342 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3343 ASSERT_FALSE(http_data.AllReadDataConsumed());
3344
3345 // Read the response body over TCP.
3346 CheckResponseData(&trans, "hello world");
3347 ExpectBrokenAlternateProtocolMapping();
3348 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3349 ASSERT_TRUE(http_data.AllReadDataConsumed());
3350}
3351
rch9ecde09b2017-04-08 00:18:233352// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3353// connection times out, then QUIC will be marked as broken but the request
3354// will not be retried over TCP.
3355TEST_P(QuicNetworkTransactionTest,
3356 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413357 session_params_.mark_quic_broken_when_network_blackholes = true;
3358 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233359
3360 // The request will initially go out over QUIC.
3361 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523362 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133363 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233364 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3365
3366 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033367 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433368 quic_data.AddWrite(SYNCHRONOUS,
3369 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333370 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3371 true, priority, GetRequestHeaders("GET", "https", "/"),
3372 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233373
3374 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523375 quic::QuicStreamOffset settings_offset = header_stream_offset;
3376 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433377 quic_data.AddWrite(SYNCHRONOUS,
3378 client_maker_.MakeInitialSettingsPacketAndSaveData(
3379 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233380
Zhongyi Shi32f2fd02018-04-16 18:23:433381 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333382 1, GetNthClientInitiatedBidirectionalStreamId(0),
3383 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433384 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523385 quic_data.AddWrite(
3386 SYNCHRONOUS,
3387 ConstructClientAckPacket(3, 1, 1, 1,
3388 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233389
3390 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523391 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563392 SYNCHRONOUS,
3393 client_maker_.MakeDataPacket(
3394 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3395 false, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233396 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093397 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563398 SYNCHRONOUS,
3399 client_maker_.MakeDataPacket(
3400 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3401 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233402 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523403 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563404 SYNCHRONOUS,
3405 client_maker_.MakeDataPacket(
3406 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3407 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093408 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563409 SYNCHRONOUS,
3410 client_maker_.MakeDataPacket(
3411 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3412 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233413 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523414 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563415 SYNCHRONOUS,
3416 client_maker_.MakeDataPacket(
3417 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3418 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093419 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563420 SYNCHRONOUS,
3421 client_maker_.MakeDataPacket(
3422 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3423 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233424 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523425 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563426 SYNCHRONOUS,
3427 client_maker_.MakeDataPacket(
3428 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3429 false, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093430 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563431 SYNCHRONOUS,
3432 client_maker_.MakeDataPacket(
3433 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3434 false, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233435
Michael Warres112212822018-12-26 17:51:063436 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183437 quic_fix_time_of_first_packet_sent_after_receiving)) {
3438 quic_data.AddWrite(
3439 SYNCHRONOUS,
3440 client_maker_.MakeAckAndConnectionClosePacket(
3441 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3442 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3443
3444 } else {
3445 quic_data.AddWrite(
3446 SYNCHRONOUS,
3447 client_maker_.MakeAckAndConnectionClosePacket(
3448 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3449 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3450 }
Fan Yang928f1632017-12-14 18:55:223451
rch9ecde09b2017-04-08 00:18:233452 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3453 quic_data.AddRead(ASYNC, OK);
3454 quic_data.AddSocketDataToFactory(&socket_factory_);
3455
3456 // In order for a new QUIC session to be established via alternate-protocol
3457 // without racing an HTTP connection, we need the host resolution to happen
3458 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3459 // connection to the the server, in this test we require confirmation
3460 // before encrypting so the HTTP job will still start.
3461 host_resolver_.set_synchronous_mode(true);
3462 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3463 "");
rch9ecde09b2017-04-08 00:18:233464
3465 CreateSession();
3466 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233467 QuicStreamFactoryPeer::SetAlarmFactory(
3468 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193469 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553470 &clock_));
rch9ecde09b2017-04-08 00:18:233471
Ryan Hamilton9835e662018-08-02 05:36:273472 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233473
3474 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3475 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363476 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233477 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3478
3479 // Pump the message loop to get the request started.
3480 base::RunLoop().RunUntilIdle();
3481 // Explicitly confirm the handshake.
3482 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523483 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233484
3485 // Pump the message loop to get the request started.
3486 base::RunLoop().RunUntilIdle();
3487
3488 // Run the QUIC session to completion.
3489 quic_task_runner_->RunUntilIdle();
3490 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3491
3492 // Let the transaction proceed which will result in QUIC being marked
3493 // as broken and the request falling back to TCP.
3494 EXPECT_THAT(callback.WaitForResult(), IsOk());
3495
3496 ExpectBrokenAlternateProtocolMapping();
3497 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3498
3499 std::string response_data;
3500 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3501 IsError(ERR_QUIC_PROTOCOL_ERROR));
3502}
3503
3504// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3505// connection RTOs, then QUIC will be marked as broken and the request retried
3506// over TCP.
3507TEST_P(QuicNetworkTransactionTest,
3508 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413509 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523510 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233511
3512 // The request will initially go out over QUIC.
3513 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523514 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133515 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233516 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3517
3518 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033519 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433520 quic_data.AddWrite(SYNCHRONOUS,
3521 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333522 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3523 true, priority, GetRequestHeaders("GET", "https", "/"),
3524 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233525
3526 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523527 quic::QuicStreamOffset settings_offset = header_stream_offset;
3528 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433529 quic_data.AddWrite(SYNCHRONOUS,
3530 client_maker_.MakeInitialSettingsPacketAndSaveData(
3531 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233532 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523533 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563534 SYNCHRONOUS,
3535 client_maker_.MakeDataPacket(
3536 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3537 true, false, 0, request_data));
3538 // TLP 2
3539 quic_data.AddWrite(
3540 SYNCHRONOUS,
3541 client_maker_.MakeDataPacket(
3542 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3543 true, false, settings_offset, settings_data));
3544 // RTO 1
3545 quic_data.AddWrite(
3546 SYNCHRONOUS,
3547 client_maker_.MakeDataPacket(
3548 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3549 true, false, 0, request_data));
3550 quic_data.AddWrite(
3551 SYNCHRONOUS,
3552 client_maker_.MakeDataPacket(
3553 6, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3554 true, false, settings_offset, settings_data));
3555 // RTO 2
3556 quic_data.AddWrite(
3557 SYNCHRONOUS,
3558 client_maker_.MakeDataPacket(
3559 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3560 true, false, 0, request_data));
3561 quic_data.AddWrite(
3562 SYNCHRONOUS,
3563 client_maker_.MakeDataPacket(
3564 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3565 true, false, settings_offset, settings_data));
3566 // RTO 3
3567 quic_data.AddWrite(
3568 SYNCHRONOUS,
3569 client_maker_.MakeDataPacket(
3570 9, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3571 true, false, 0, request_data));
3572 quic_data.AddWrite(
3573 SYNCHRONOUS,
3574 client_maker_.MakeDataPacket(
3575 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3576 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233577 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523578 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563579 SYNCHRONOUS,
3580 client_maker_.MakeDataPacket(
3581 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3582 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093583 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563584 SYNCHRONOUS,
3585 client_maker_.MakeDataPacket(
3586 12, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3587 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233588
Zhongyi Shi32f2fd02018-04-16 18:23:433589 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523590 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433591 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233592
3593 quic_data.AddRead(ASYNC, OK);
3594 quic_data.AddSocketDataToFactory(&socket_factory_);
3595
3596 // After that fails, it will be resent via TCP.
3597 MockWrite http_writes[] = {
3598 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3599 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3600 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3601
3602 MockRead http_reads[] = {
3603 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3604 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3605 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013606 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233607 socket_factory_.AddSocketDataProvider(&http_data);
3608 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3609
3610 // In order for a new QUIC session to be established via alternate-protocol
3611 // without racing an HTTP connection, we need the host resolution to happen
3612 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3613 // connection to the the server, in this test we require confirmation
3614 // before encrypting so the HTTP job will still start.
3615 host_resolver_.set_synchronous_mode(true);
3616 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3617 "");
rch9ecde09b2017-04-08 00:18:233618
3619 CreateSession();
3620 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233621 QuicStreamFactoryPeer::SetAlarmFactory(
3622 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193623 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553624 &clock_));
rch9ecde09b2017-04-08 00:18:233625
Ryan Hamilton9835e662018-08-02 05:36:273626 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233627
3628 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3629 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363630 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233631 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3632
3633 // Pump the message loop to get the request started.
3634 base::RunLoop().RunUntilIdle();
3635 // Explicitly confirm the handshake.
3636 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523637 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233638
3639 // Run the QUIC session to completion.
3640 quic_task_runner_->RunUntilIdle();
3641 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3642
3643 // Let the transaction proceed which will result in QUIC being marked
3644 // as broken and the request falling back to TCP.
3645 EXPECT_THAT(callback.WaitForResult(), IsOk());
3646
3647 ExpectBrokenAlternateProtocolMapping();
3648 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3649 ASSERT_FALSE(http_data.AllReadDataConsumed());
3650
3651 // Read the response body over TCP.
3652 CheckResponseData(&trans, "hello world");
3653 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3654 ASSERT_TRUE(http_data.AllReadDataConsumed());
3655}
3656
3657// Verify that if a QUIC connection RTOs, while there are no active streams
3658// QUIC will be marked as broken.
3659TEST_P(QuicNetworkTransactionTest,
3660 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413661 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523662 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233663
3664 // The request will initially go out over QUIC.
3665 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523666 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133667 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233668 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3669
3670 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033671 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433672 quic_data.AddWrite(SYNCHRONOUS,
3673 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333674 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3675 true, priority, GetRequestHeaders("GET", "https", "/"),
3676 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233677
3678 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523679 quic::QuicStreamOffset settings_offset = header_stream_offset;
3680 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433681 quic_data.AddWrite(SYNCHRONOUS,
3682 client_maker_.MakeInitialSettingsPacketAndSaveData(
3683 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233684
Fan Yang32c5a112018-12-10 20:06:333685 quic_data.AddWrite(SYNCHRONOUS,
3686 client_maker_.MakeRstPacket(
3687 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3688 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233689 // TLP 1
Nick Harper23290b82019-05-02 00:02:563690 quic_data.AddWrite(
3691 SYNCHRONOUS,
3692 client_maker_.MakeDataPacket(
3693 4, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3694 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233695 // TLP 2
Nick Harper23290b82019-05-02 00:02:563696 quic_data.AddWrite(
3697 SYNCHRONOUS,
3698 client_maker_.MakeDataPacket(
3699 5, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3700 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233701 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333702 quic_data.AddWrite(SYNCHRONOUS,
3703 client_maker_.MakeRstPacket(
3704 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3705 quic::QUIC_STREAM_CANCELLED));
Nick Harper23290b82019-05-02 00:02:563706 quic_data.AddWrite(
3707 SYNCHRONOUS,
3708 client_maker_.MakeDataPacket(
3709 7, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3710 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233711 // RTO 2
Nick Harper23290b82019-05-02 00:02:563712 quic_data.AddWrite(
3713 SYNCHRONOUS,
3714 client_maker_.MakeDataPacket(
3715 8, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3716 true, false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333717 quic_data.AddWrite(SYNCHRONOUS,
3718 client_maker_.MakeRstPacket(
3719 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3720 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233721 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523722 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563723 SYNCHRONOUS,
3724 client_maker_.MakeDataPacket(
3725 10, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3726 true, false, 0, request_data));
Ryan Hamilton47cf9d12018-10-17 04:33:093727 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563728 SYNCHRONOUS,
3729 client_maker_.MakeDataPacket(
3730 11, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3731 true, false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233732 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433733 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333734 SYNCHRONOUS, client_maker_.MakeRstPacket(
3735 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3736 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523737 quic_data.AddWrite(
Nick Harper23290b82019-05-02 00:02:563738 SYNCHRONOUS,
3739 client_maker_.MakeDataPacket(
3740 13, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
3741 true, false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233742 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433743 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523744 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433745 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233746
3747 quic_data.AddRead(ASYNC, OK);
3748 quic_data.AddSocketDataToFactory(&socket_factory_);
3749
3750 // In order for a new QUIC session to be established via alternate-protocol
3751 // without racing an HTTP connection, we need the host resolution to happen
3752 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3753 // connection to the the server, in this test we require confirmation
3754 // before encrypting so the HTTP job will still start.
3755 host_resolver_.set_synchronous_mode(true);
3756 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3757 "");
rch9ecde09b2017-04-08 00:18:233758
3759 CreateSession();
3760 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rch9ecde09b2017-04-08 00:18:233761 QuicStreamFactoryPeer::SetAlarmFactory(
3762 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193763 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553764 &clock_));
rch9ecde09b2017-04-08 00:18:233765
Ryan Hamilton9835e662018-08-02 05:36:273766 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233767
Jeremy Roman0579ed62017-08-29 15:56:193768 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233769 session_.get());
3770 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363771 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3773
3774 // Pump the message loop to get the request started.
3775 base::RunLoop().RunUntilIdle();
3776 // Explicitly confirm the handshake.
3777 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523778 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233779
3780 // Now cancel the request.
3781 trans.reset();
3782
3783 // Run the QUIC session to completion.
3784 quic_task_runner_->RunUntilIdle();
3785
3786 ExpectBrokenAlternateProtocolMapping();
3787
3788 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3789}
3790
rch2f2991c2017-04-13 19:28:173791// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3792// protocol error occurs after the handshake is confirmed, the request
3793// retried over TCP and the QUIC will be marked as broken.
3794TEST_P(QuicNetworkTransactionTest,
3795 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413796 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173797
3798 // The request will initially go out over QUIC.
3799 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523800 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033801 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433802 quic_data.AddWrite(
3803 SYNCHRONOUS,
3804 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333805 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433806 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523807 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433808 quic_data.AddWrite(SYNCHRONOUS,
3809 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173810 // Peer sending data from an non-existing stream causes this end to raise
3811 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333812 quic_data.AddRead(
3813 ASYNC, ConstructServerRstPacket(
3814 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3815 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173816 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433817 quic_data.AddWrite(SYNCHRONOUS,
3818 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523819 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3820 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173821 quic_data.AddSocketDataToFactory(&socket_factory_);
3822
3823 // After that fails, it will be resent via TCP.
3824 MockWrite http_writes[] = {
3825 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3826 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3827 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3828
3829 MockRead http_reads[] = {
3830 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3831 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3832 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013833 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173834 socket_factory_.AddSocketDataProvider(&http_data);
3835 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3836
3837 // In order for a new QUIC session to be established via alternate-protocol
3838 // without racing an HTTP connection, we need the host resolution to happen
3839 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3840 // connection to the the server, in this test we require confirmation
3841 // before encrypting so the HTTP job will still start.
3842 host_resolver_.set_synchronous_mode(true);
3843 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3844 "");
rch2f2991c2017-04-13 19:28:173845
3846 CreateSession();
3847
Ryan Hamilton9835e662018-08-02 05:36:273848 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173849
3850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3851 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363852 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173853 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3854
3855 // Pump the message loop to get the request started.
3856 base::RunLoop().RunUntilIdle();
3857 // Explicitly confirm the handshake.
3858 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523859 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173860
3861 // Run the QUIC session to completion.
3862 base::RunLoop().RunUntilIdle();
3863 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3864
3865 ExpectQuicAlternateProtocolMapping();
3866
3867 // Let the transaction proceed which will result in QUIC being marked
3868 // as broken and the request falling back to TCP.
3869 EXPECT_THAT(callback.WaitForResult(), IsOk());
3870
3871 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3872 ASSERT_FALSE(http_data.AllReadDataConsumed());
3873
3874 // Read the response body over TCP.
3875 CheckResponseData(&trans, "hello world");
3876 ExpectBrokenAlternateProtocolMapping();
3877 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3878 ASSERT_TRUE(http_data.AllReadDataConsumed());
3879}
3880
rch30943ee2017-06-12 21:28:443881// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3882// request is reset from, then QUIC will be marked as broken and the request
3883// retried over TCP.
3884TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443885 // The request will initially go out over QUIC.
3886 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523887 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133888 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443889 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3890
3891 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033892 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433893 quic_data.AddWrite(SYNCHRONOUS,
3894 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333895 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3896 true, priority, GetRequestHeaders("GET", "https", "/"),
3897 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443898
3899 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523900 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3901 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433902 quic_data.AddWrite(SYNCHRONOUS,
3903 client_maker_.MakeInitialSettingsPacketAndSaveData(
3904 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443905
Fan Yang32c5a112018-12-10 20:06:333906 quic_data.AddRead(ASYNC,
3907 ConstructServerRstPacket(
3908 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3909 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443910
3911 quic_data.AddRead(ASYNC, OK);
3912 quic_data.AddSocketDataToFactory(&socket_factory_);
3913
3914 // After that fails, it will be resent via TCP.
3915 MockWrite http_writes[] = {
3916 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3917 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3918 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3919
3920 MockRead http_reads[] = {
3921 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3922 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3923 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013924 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443925 socket_factory_.AddSocketDataProvider(&http_data);
3926 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3927
3928 // In order for a new QUIC session to be established via alternate-protocol
3929 // without racing an HTTP connection, we need the host resolution to happen
3930 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3931 // connection to the the server, in this test we require confirmation
3932 // before encrypting so the HTTP job will still start.
3933 host_resolver_.set_synchronous_mode(true);
3934 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3935 "");
rch30943ee2017-06-12 21:28:443936
3937 CreateSession();
3938
Ryan Hamilton9835e662018-08-02 05:36:273939 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443940
3941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3942 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363943 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3945
3946 // Pump the message loop to get the request started.
3947 base::RunLoop().RunUntilIdle();
3948 // Explicitly confirm the handshake.
3949 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523950 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443951
3952 // Run the QUIC session to completion.
3953 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3954
3955 ExpectQuicAlternateProtocolMapping();
3956
3957 // Let the transaction proceed which will result in QUIC being marked
3958 // as broken and the request falling back to TCP.
3959 EXPECT_THAT(callback.WaitForResult(), IsOk());
3960
3961 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3962 ASSERT_FALSE(http_data.AllReadDataConsumed());
3963
3964 // Read the response body over TCP.
3965 CheckResponseData(&trans, "hello world");
3966 ExpectBrokenAlternateProtocolMapping();
3967 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3968 ASSERT_TRUE(http_data.AllReadDataConsumed());
3969}
3970
Ryan Hamilton6c2a2a82017-12-15 02:06:283971// Verify that when an origin has two alt-svc advertisements, one local and one
3972// remote, that when the local is broken the request will go over QUIC via
3973// the remote Alt-Svc.
3974// This is a regression test for crbug/825646.
3975TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3976 session_params_.quic_allow_remote_alt_svc = true;
3977
3978 GURL origin1 = request_.url; // mail.example.org
3979 GURL origin2("https://www.example.org/");
3980 ASSERT_NE(origin1.host(), origin2.host());
3981
3982 scoped_refptr<X509Certificate> cert(
3983 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243984 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3985 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283986
3987 ProofVerifyDetailsChromium verify_details;
3988 verify_details.cert_verify_result.verified_cert = cert;
3989 verify_details.cert_verify_result.is_issued_by_known_root = true;
3990 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3991
3992 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523993 quic::QuicStreamOffset request_header_offset(0);
3994 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283995 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433996 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3997 mock_quic_data.AddWrite(
3998 SYNCHRONOUS,
3999 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334000 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434001 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4002 mock_quic_data.AddRead(
4003 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334004 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434005 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434006 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434007 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334008 ASYNC, ConstructServerDataPacket(
4009 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414010 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434011 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284012 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4013 mock_quic_data.AddRead(ASYNC, 0); // EOF
4014
4015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4016 MockQuicData mock_quic_data2;
4017 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4018 AddHangingNonAlternateProtocolSocketData();
4019
4020 CreateSession();
4021
4022 // Set up alternative service for |origin1|.
4023 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4024 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4025 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4026 AlternativeServiceInfoVector alternative_services;
4027 alternative_services.push_back(
4028 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4029 local_alternative, expiration,
4030 session_->params().quic_supported_versions));
4031 alternative_services.push_back(
4032 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4033 remote_alternative, expiration,
4034 session_->params().quic_supported_versions));
4035 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4036 alternative_services);
4037
4038 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4039
4040 SendRequestAndExpectQuicResponse("hello!");
4041}
4042
rch30943ee2017-06-12 21:28:444043// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4044// request is reset from, then QUIC will be marked as broken and the request
4045// retried over TCP. Then, subsequent requests will go over a new QUIC
4046// connection instead of going back to the broken QUIC connection.
4047// This is a regression tests for crbug/731303.
4048TEST_P(QuicNetworkTransactionTest,
4049 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344050 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444051
4052 GURL origin1 = request_.url;
4053 GURL origin2("https://www.example.org/");
4054 ASSERT_NE(origin1.host(), origin2.host());
4055
4056 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524057 quic::QuicStreamOffset request_header_offset(0);
4058 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444059
4060 scoped_refptr<X509Certificate> cert(
4061 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244062 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4063 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444064
4065 ProofVerifyDetailsChromium verify_details;
4066 verify_details.cert_verify_result.verified_cert = cert;
4067 verify_details.cert_verify_result.is_issued_by_known_root = true;
4068 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4069
4070 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434071 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444072 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434073 mock_quic_data.AddWrite(
4074 SYNCHRONOUS,
4075 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334076 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434077 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4078 mock_quic_data.AddRead(
4079 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334080 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434081 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434082 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434083 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334084 ASYNC, ConstructServerDataPacket(
4085 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414086 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434087 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444088
4089 // Second request will go over the pooled QUIC connection, but will be
4090 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054091 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174092 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4093 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054094 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174095 QuicTestPacketMaker server_maker2(
4096 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4097 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434098 mock_quic_data.AddWrite(
4099 SYNCHRONOUS,
4100 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334101 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434102 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334103 GetNthClientInitiatedBidirectionalStreamId(0),
4104 &request_header_offset));
4105 mock_quic_data.AddRead(
4106 ASYNC, ConstructServerRstPacket(
4107 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4108 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444109 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4110 mock_quic_data.AddRead(ASYNC, 0); // EOF
4111
4112 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4113
4114 // After that fails, it will be resent via TCP.
4115 MockWrite http_writes[] = {
4116 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4117 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4118 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4119
4120 MockRead http_reads[] = {
4121 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4122 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4123 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014124 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444125 socket_factory_.AddSocketDataProvider(&http_data);
4126 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4127
Ryan Hamilton6c2a2a82017-12-15 02:06:284128 // Then the next request to the second origin will be sent over TCP.
4129 socket_factory_.AddSocketDataProvider(&http_data);
4130 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444131
4132 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564133 QuicStreamFactoryPeer::SetAlarmFactory(
4134 session_->quic_stream_factory(),
4135 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4136 &clock_));
rch30943ee2017-06-12 21:28:444137
4138 // Set up alternative service for |origin1|.
4139 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244140 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214141 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244142 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444143 supported_versions_);
rch30943ee2017-06-12 21:28:444144
4145 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244146 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214147 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244148 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444149 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344150
rch30943ee2017-06-12 21:28:444151 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524152 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444153 SendRequestAndExpectQuicResponse("hello!");
4154
4155 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524156 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444157 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4158 request_.url = origin2;
4159 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284160 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244161 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284162 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244163 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444164
4165 // The third request should use a new QUIC connection, not the broken
4166 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284167 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444168}
4169
bnc8be55ebb2015-10-30 14:12:074170TEST_P(QuicNetworkTransactionTest,
4171 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
Nick Harper23290b82019-05-02 00:02:564172 std::string altsvc_header =
4173 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n",
4174 version_.transport_version - 1);
bnc8be55ebb2015-10-30 14:12:074175 MockRead http_reads[] = {
4176 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4177 MockRead("hello world"),
4178 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4179 MockRead(ASYNC, OK)};
4180
Ryan Sleevib8d7ea02018-05-07 20:01:014181 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074182 socket_factory_.AddSocketDataProvider(&http_data);
4183 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4184 socket_factory_.AddSocketDataProvider(&http_data);
4185 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4186
rch3f4b8452016-02-23 16:59:324187 CreateSession();
bnc8be55ebb2015-10-30 14:12:074188
4189 SendRequestAndExpectHttpResponse("hello world");
4190 SendRequestAndExpectHttpResponse("hello world");
4191}
4192
Xida Chen9bfe0b62018-04-24 19:52:214193// When multiple alternative services are advertised, HttpStreamFactory should
4194// select the alternative service which uses existing QUIC session if available.
4195// If no existing QUIC session can be used, use the first alternative service
4196// from the list.
zhongyi32569c62016-01-08 02:54:304197TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344198 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524199 MockRead http_reads[] = {
4200 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294201 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524202 MockRead("hello world"),
4203 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4204 MockRead(ASYNC, OK)};
4205
Ryan Sleevib8d7ea02018-05-07 20:01:014206 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524207 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084208 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564209 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524210
Ryan Hamilton8d9ee76e2018-05-29 23:52:524211 quic::QuicStreamOffset request_header_offset = 0;
4212 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304213 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294214 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304215 // alternative service list.
bncc958faa2015-07-31 18:14:524216 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364217 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434218 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4219 mock_quic_data.AddWrite(
4220 SYNCHRONOUS,
4221 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334222 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434223 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304224
4225 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294226 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4227 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434228 mock_quic_data.AddRead(
4229 ASYNC,
4230 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334231 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434232 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434233 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434234 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334235 ASYNC, ConstructServerDataPacket(
4236 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414237 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434238 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304239
4240 // Second QUIC request data.
4241 // Connection pooling, using existing session, no need to include version
4242 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584243 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334244 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4245 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4246 true, GetRequestHeaders("GET", "https", "/"),
4247 GetNthClientInitiatedBidirectionalStreamId(0),
4248 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434249 mock_quic_data.AddRead(
4250 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334251 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434252 GetResponseHeaders("200 OK"), &response_header_offset));
4253 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334254 ASYNC, ConstructServerDataPacket(
4255 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414256 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434257 mock_quic_data.AddWrite(
4258 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524259 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594260 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524261
4262 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4263
rtennetib8e80fb2016-05-16 00:12:094264 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324265 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564266 QuicStreamFactoryPeer::SetAlarmFactory(
4267 session_->quic_stream_factory(),
4268 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4269 &clock_));
bncc958faa2015-07-31 18:14:524270
4271 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304272
bnc359ed2a2016-04-29 20:43:454273 SendRequestAndExpectQuicResponse("hello!");
4274 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304275}
4276
tbansal6490783c2016-09-20 17:55:274277// Check that an existing QUIC connection to an alternative proxy server is
4278// used.
4279TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4280 base::HistogramTester histogram_tester;
4281
Ryan Hamilton8d9ee76e2018-05-29 23:52:524282 quic::QuicStreamOffset request_header_offset = 0;
4283 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274284 // First QUIC request data.
4285 // Open a session to foo.example.org:443 using the first entry of the
4286 // alternative service list.
4287 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364288 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434289 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4290 mock_quic_data.AddWrite(
4291 SYNCHRONOUS,
4292 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334293 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434294 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274295
4296 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434297 mock_quic_data.AddRead(
4298 ASYNC,
4299 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334300 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434301 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434302 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434303 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334304 ASYNC, ConstructServerDataPacket(
4305 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414306 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434307 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274308
4309 // Second QUIC request data.
4310 // Connection pooling, using existing session, no need to include version
4311 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274312 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334313 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4314 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4315 true, GetRequestHeaders("GET", "http", "/"),
4316 GetNthClientInitiatedBidirectionalStreamId(0),
4317 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434318 mock_quic_data.AddRead(
4319 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334320 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434321 GetResponseHeaders("200 OK"), &response_header_offset));
4322 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334323 ASYNC, ConstructServerDataPacket(
4324 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414325 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434326 mock_quic_data.AddWrite(
4327 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274328 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4329 mock_quic_data.AddRead(ASYNC, 0); // EOF
4330
4331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4332
4333 AddHangingNonAlternateProtocolSocketData();
4334
4335 TestProxyDelegate test_proxy_delegate;
4336
Lily Houghton8c2f97d2018-01-22 05:06:594337 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494338 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274339
4340 test_proxy_delegate.set_alternative_proxy_server(
4341 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524342 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274343
4344 request_.url = GURL("http://mail.example.org/");
4345
4346 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564347 QuicStreamFactoryPeer::SetAlarmFactory(
4348 session_->quic_stream_factory(),
4349 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4350 &clock_));
tbansal6490783c2016-09-20 17:55:274351
4352 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4353 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4354 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4355 1);
4356
4357 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4358 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4359 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4360 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4361 1);
4362}
4363
Ryan Hamilton8d9ee76e2018-05-29 23:52:524364// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454365// even if alternative service destination is different.
4366TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344367 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304368 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524369 quic::QuicStreamOffset request_header_offset(0);
4370 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454371
rch5cb522462017-04-25 20:18:364372 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434373 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454374 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434375 mock_quic_data.AddWrite(
4376 SYNCHRONOUS,
4377 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334378 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434379 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4380 mock_quic_data.AddRead(
4381 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334382 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434383 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434384 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434385 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334386 ASYNC, ConstructServerDataPacket(
4387 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414388 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434389 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304390
bnc359ed2a2016-04-29 20:43:454391 // Second request.
alyssar2adf3ac2016-05-03 17:12:584392 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334393 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4394 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4395 true, GetRequestHeaders("GET", "https", "/"),
4396 GetNthClientInitiatedBidirectionalStreamId(0),
4397 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434398 mock_quic_data.AddRead(
4399 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334400 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434401 GetResponseHeaders("200 OK"), &response_header_offset));
4402 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334403 ASYNC, ConstructServerDataPacket(
4404 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414405 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434406 mock_quic_data.AddWrite(
4407 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304408 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4409 mock_quic_data.AddRead(ASYNC, 0); // EOF
4410
4411 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454412
4413 AddHangingNonAlternateProtocolSocketData();
4414 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304415
rch3f4b8452016-02-23 16:59:324416 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564417 QuicStreamFactoryPeer::SetAlarmFactory(
4418 session_->quic_stream_factory(),
4419 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4420 &clock_));
zhongyi32569c62016-01-08 02:54:304421
bnc359ed2a2016-04-29 20:43:454422 const char destination1[] = "first.example.com";
4423 const char destination2[] = "second.example.com";
4424
4425 // Set up alternative service entry to destination1.
4426 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214427 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454428 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214429 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444430 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454431 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524432 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454433 SendRequestAndExpectQuicResponse("hello!");
4434
4435 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214436 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214437 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444438 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524439 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454440 // even though alternative service destination is different.
4441 SendRequestAndExpectQuicResponse("hello!");
4442}
4443
4444// Pool to existing session with matching destination and matching certificate
4445// even if origin is different, and even if the alternative service with
4446// matching destination is not the first one on the list.
4447TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344448 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454449 GURL origin1 = request_.url;
4450 GURL origin2("https://www.example.org/");
4451 ASSERT_NE(origin1.host(), origin2.host());
4452
4453 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524454 quic::QuicStreamOffset request_header_offset(0);
4455 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454456
rch5cb522462017-04-25 20:18:364457 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434458 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454459 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434460 mock_quic_data.AddWrite(
4461 SYNCHRONOUS,
4462 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334463 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434464 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4465 mock_quic_data.AddRead(
4466 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334467 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434468 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434469 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434470 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334471 ASYNC, ConstructServerDataPacket(
4472 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414473 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434474 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454475
4476 // Second request.
Yixin Wang079ad542018-01-11 04:06:054477 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174478 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4479 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054480 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174481 QuicTestPacketMaker server_maker2(
4482 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4483 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584484 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434485 SYNCHRONOUS,
4486 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334487 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434488 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334489 GetNthClientInitiatedBidirectionalStreamId(0),
4490 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434491 mock_quic_data.AddRead(
4492 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334493 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434494 GetResponseHeaders("200 OK"), &response_header_offset));
4495 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334496 ASYNC, ConstructServerDataPacket(
4497 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414498 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434499 mock_quic_data.AddWrite(
4500 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454501 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4502 mock_quic_data.AddRead(ASYNC, 0); // EOF
4503
4504 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4505
4506 AddHangingNonAlternateProtocolSocketData();
4507 AddHangingNonAlternateProtocolSocketData();
4508
4509 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564510 QuicStreamFactoryPeer::SetAlarmFactory(
4511 session_->quic_stream_factory(),
4512 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4513 &clock_));
bnc359ed2a2016-04-29 20:43:454514
4515 const char destination1[] = "first.example.com";
4516 const char destination2[] = "second.example.com";
4517
4518 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214519 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454520 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214521 http_server_properties_.SetQuicAlternativeService(
4522 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444523 supported_versions_);
bnc359ed2a2016-04-29 20:43:454524
4525 // Set up multiple alternative service entries for |origin2|,
4526 // the first one with a different destination as for |origin1|,
4527 // the second one with the same. The second one should be used,
4528 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214529 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454530 AlternativeServiceInfoVector alternative_services;
4531 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214532 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4533 alternative_service2, expiration,
4534 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454535 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214536 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4537 alternative_service1, expiration,
4538 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454539 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4540 alternative_services);
bnc359ed2a2016-04-29 20:43:454541 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524542 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454543 SendRequestAndExpectQuicResponse("hello!");
4544
4545 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524546 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454547 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584548
bnc359ed2a2016-04-29 20:43:454549 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304550}
4551
4552// Multiple origins have listed the same alternative services. When there's a
4553// existing QUIC session opened by a request to other origin,
4554// if the cert is valid, should select this QUIC session to make the request
4555// if this is also the first existing QUIC session.
4556TEST_P(QuicNetworkTransactionTest,
4557 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344558 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294559 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304560
rch9ae5b3b2016-02-11 00:36:294561 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304562 MockRead http_reads[] = {
4563 MockRead("HTTP/1.1 200 OK\r\n"),
4564 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294565 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304566 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4567 MockRead(ASYNC, OK)};
4568
Ryan Sleevib8d7ea02018-05-07 20:01:014569 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304570 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084571 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304572 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4573
4574 // HTTP data for request to mail.example.org.
4575 MockRead http_reads2[] = {
4576 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294577 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304578 MockRead("hello world from mail.example.org"),
4579 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4580 MockRead(ASYNC, OK)};
4581
Ryan Sleevib8d7ea02018-05-07 20:01:014582 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304583 socket_factory_.AddSocketDataProvider(&http_data2);
4584 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4585
Ryan Hamilton8d9ee76e2018-05-29 23:52:524586 quic::QuicStreamOffset request_header_offset = 0;
4587 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304588
Yixin Wang079ad542018-01-11 04:06:054589 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174590 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4591 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054592 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584593 server_maker_.set_hostname("www.example.org");
4594 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304595 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364596 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434597 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304598 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584599 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434600 SYNCHRONOUS,
4601 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334602 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434603 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4604
4605 mock_quic_data.AddRead(
4606 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334607 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434608 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434609 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334610 mock_quic_data.AddRead(
4611 ASYNC, ConstructServerDataPacket(
4612 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414613 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434614 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4615 // Second QUIC request data.
4616 mock_quic_data.AddWrite(
4617 SYNCHRONOUS,
4618 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334619 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434620 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334621 GetNthClientInitiatedBidirectionalStreamId(0),
4622 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434623 mock_quic_data.AddRead(
4624 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334625 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434626 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334627 mock_quic_data.AddRead(
4628 ASYNC, ConstructServerDataPacket(
4629 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414630 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434631 mock_quic_data.AddWrite(
4632 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304633 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4634 mock_quic_data.AddRead(ASYNC, 0); // EOF
4635
4636 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304637
rtennetib8e80fb2016-05-16 00:12:094638 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324639 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564640 QuicStreamFactoryPeer::SetAlarmFactory(
4641 session_->quic_stream_factory(),
4642 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4643 &clock_));
zhongyi32569c62016-01-08 02:54:304644
4645 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294646 request_.url = GURL("https://www.example.org/");
4647 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304648 request_.url = GURL("https://mail.example.org/");
4649 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4650
rch9ae5b3b2016-02-11 00:36:294651 // Open a QUIC session to mail.example.org:443 when making request
4652 // to mail.example.org.
4653 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454654 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304655
rch9ae5b3b2016-02-11 00:36:294656 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304657 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454658 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524659}
4660
4661TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524662 MockRead http_reads[] = {
4663 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564664 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524665 MockRead("hello world"),
4666 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4667 MockRead(ASYNC, OK)};
4668
Ryan Sleevib8d7ea02018-05-07 20:01:014669 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524670 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084671 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564672 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524673
rtennetib8e80fb2016-05-16 00:12:094674 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324675 CreateSession();
bncc958faa2015-07-31 18:14:524676
4677 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454678
4679 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344680 AlternativeServiceInfoVector alternative_service_info_vector =
4681 http_server_properties_.GetAlternativeServiceInfos(http_server);
4682 ASSERT_EQ(1u, alternative_service_info_vector.size());
4683 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544684 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344685 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4686 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4687 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524688}
4689
4690TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524691 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564692 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4693 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524694 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4695 MockRead(ASYNC, OK)};
4696
Ryan Sleevib8d7ea02018-05-07 20:01:014697 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524698 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084699 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564700 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524701
4702 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524703 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364704 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434705 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4706 mock_quic_data.AddWrite(
4707 SYNCHRONOUS,
4708 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334709 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434710 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434711 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334712 ASYNC, ConstructServerResponseHeadersPacket(
4713 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4714 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434715 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334716 mock_quic_data.AddRead(
4717 ASYNC, ConstructServerDataPacket(
4718 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414719 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434720 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524721 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4722 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524723
4724 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4725
rtennetib8e80fb2016-05-16 00:12:094726 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324727 CreateSession();
bncc958faa2015-07-31 18:14:524728
bnc3472afd2016-11-17 15:27:214729 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524730 HostPortPair::FromURL(request_.url));
4731 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4732 alternative_service);
4733 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4734 alternative_service));
4735
4736 SendRequestAndExpectHttpResponse("hello world");
4737 SendRequestAndExpectQuicResponse("hello!");
4738
mmenkee24011922015-12-17 22:12:594739 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524740
4741 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4742 alternative_service));
rchac7f35e2017-03-15 20:42:304743 EXPECT_NE(nullptr,
4744 http_server_properties_.GetServerNetworkStats(
4745 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524746}
4747
bncc958faa2015-07-31 18:14:524748TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524749 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564750 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4751 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524752 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4753 MockRead(ASYNC, OK)};
4754
Ryan Sleevib8d7ea02018-05-07 20:01:014755 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524756 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564757 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524758
4759 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524760 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364761 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434762 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4763 mock_quic_data.AddWrite(
4764 SYNCHRONOUS,
4765 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334766 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434767 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434768 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334769 ASYNC, ConstructServerResponseHeadersPacket(
4770 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4771 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434772 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334773 mock_quic_data.AddRead(
4774 ASYNC, ConstructServerDataPacket(
4775 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414776 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434777 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524778 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4779
4780 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4781
4782 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324783 CreateSession();
bncc958faa2015-07-31 18:14:524784
4785 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4786 SendRequestAndExpectHttpResponse("hello world");
4787}
4788
tbansalc3308d72016-08-27 10:25:044789// Tests that the connection to an HTTPS proxy is raced with an available
4790// alternative proxy server.
4791TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274792 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594793 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494794 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044795
4796 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524797 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364798 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434799 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4800 mock_quic_data.AddWrite(
4801 SYNCHRONOUS,
4802 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334803 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434804 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434805 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334806 ASYNC, ConstructServerResponseHeadersPacket(
4807 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4808 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434809 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334810 mock_quic_data.AddRead(
4811 ASYNC, ConstructServerDataPacket(
4812 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414813 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434814 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044815 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4816 mock_quic_data.AddRead(ASYNC, 0); // EOF
4817
4818 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4819
4820 // There is no need to set up main job, because no attempt will be made to
4821 // speak to the proxy over TCP.
4822 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044823 TestProxyDelegate test_proxy_delegate;
4824 const HostPortPair host_port_pair("mail.example.org", 443);
4825
4826 test_proxy_delegate.set_alternative_proxy_server(
4827 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524828 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044829 CreateSession();
4830 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4831
4832 // The main job needs to hang in order to guarantee that the alternative
4833 // proxy server job will "win".
4834 AddHangingNonAlternateProtocolSocketData();
4835
4836 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4837
4838 // Verify that the alternative proxy server is not marked as broken.
4839 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4840
4841 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594842 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274843
4844 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4845 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4846 1);
tbansalc3308d72016-08-27 10:25:044847}
4848
bnc1c196c6e2016-05-28 13:51:484849TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304850 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274851 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304852
4853 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564854 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294855 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564856 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304857
4858 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564859 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484860 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564861 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304862
Ryan Sleevib8d7ea02018-05-07 20:01:014863 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504864 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084865 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504866 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304867
4868 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454869 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304870 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454871 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304872 };
Ryan Sleevib8d7ea02018-05-07 20:01:014873 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504874 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304875
4876 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014877 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504878 socket_factory_.AddSocketDataProvider(&http_data2);
4879 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304880
bnc912a04b2016-04-20 14:19:504881 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304882
4883 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304884 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174885 ASSERT_TRUE(http_data.AllReadDataConsumed());
4886 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304887
4888 // Now run the second request in which the QUIC socket hangs,
4889 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304890 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454891 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304892
rch37de576c2015-05-17 20:28:174893 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4894 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454895 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304896}
4897
[email protected]1e960032013-12-20 19:00:204898TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204899 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524900 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:034901 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434902 mock_quic_data.AddWrite(
4903 SYNCHRONOUS,
4904 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334905 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434906 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434907 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334908 ASYNC, ConstructServerResponseHeadersPacket(
4909 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4910 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434911 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334912 mock_quic_data.AddRead(
4913 ASYNC, ConstructServerDataPacket(
4914 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414915 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434916 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504917 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594918 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484919
rcha5399e02015-04-21 19:32:044920 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484921
rtennetib8e80fb2016-05-16 00:12:094922 // The non-alternate protocol job needs to hang in order to guarantee that
4923 // the alternate-protocol job will "win".
4924 AddHangingNonAlternateProtocolSocketData();
4925
rch3f4b8452016-02-23 16:59:324926 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274927 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194928 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304929
4930 EXPECT_EQ(nullptr,
4931 http_server_properties_.GetServerNetworkStats(
4932 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484933}
4934
[email protected]1e960032013-12-20 19:00:204935TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204936 MockQuicData mock_quic_data;
Michael Warres167db3e2019-03-01 21:38:034937 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334938 mock_quic_data.AddWrite(
4939 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4940 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4941 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434942 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334943 ASYNC, ConstructServerResponseHeadersPacket(
4944 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4945 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434946 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334947 mock_quic_data.AddRead(
4948 ASYNC, ConstructServerDataPacket(
4949 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414950 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434951 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504952 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594953 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044954 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274955
4956 // In order for a new QUIC session to be established via alternate-protocol
4957 // without racing an HTTP connection, we need the host resolution to happen
4958 // synchronously.
4959 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294960 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564961 "");
[email protected]3a120a6b2013-06-25 01:08:274962
rtennetib8e80fb2016-05-16 00:12:094963 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324964 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274965 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274966 SendRequestAndExpectQuicResponse("hello!");
4967}
4968
[email protected]0fc924b2014-03-31 04:34:154969TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494970 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4971 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154972
4973 // Since we are using a proxy, the QUIC job will not succeed.
4974 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294975 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4976 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564977 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154978
4979 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564980 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484981 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564982 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154983
Ryan Sleevib8d7ea02018-05-07 20:01:014984 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154985 socket_factory_.AddSocketDataProvider(&http_data);
4986
4987 // In order for a new QUIC session to be established via alternate-protocol
4988 // without racing an HTTP connection, we need the host resolution to happen
4989 // synchronously.
4990 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294991 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564992 "");
[email protected]0fc924b2014-03-31 04:34:154993
rch9ae5b3b2016-02-11 00:36:294994 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324995 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274996 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154997 SendRequestAndExpectHttpResponse("hello world");
4998}
4999
[email protected]1e960032013-12-20 19:00:205000TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:205001 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525002 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365003 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435004 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5005 mock_quic_data.AddWrite(
5006 SYNCHRONOUS,
5007 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335008 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435009 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435010 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335011 ASYNC, ConstructServerResponseHeadersPacket(
5012 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5013 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435014 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335015 mock_quic_data.AddRead(
5016 ASYNC, ConstructServerDataPacket(
5017 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415018 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435019 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595020 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045021 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125022
rtennetib8e80fb2016-05-16 00:12:095023 // The non-alternate protocol job needs to hang in order to guarantee that
5024 // the alternate-protocol job will "win".
5025 AddHangingNonAlternateProtocolSocketData();
5026
[email protected]11c05872013-08-20 02:04:125027 // In order for a new QUIC session to be established via alternate-protocol
5028 // without racing an HTTP connection, we need the host resolution to happen
5029 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5030 // connection to the the server, in this test we require confirmation
5031 // before encrypting so the HTTP job will still start.
5032 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295033 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565034 "");
[email protected]11c05872013-08-20 02:04:125035
rch3f4b8452016-02-23 16:59:325036 CreateSession();
[email protected]11c05872013-08-20 02:04:125037 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275038 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125039
bnc691fda62016-08-12 00:43:165040 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125041 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365042 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125044
5045 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525046 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015047 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505048
bnc691fda62016-08-12 00:43:165049 CheckWasQuicResponse(&trans);
5050 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125051}
5052
Steven Valdez58097ec32018-07-16 18:29:045053TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5054 MockQuicData mock_quic_data;
5055 quic::QuicStreamOffset client_header_stream_offset = 0;
5056 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035057 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045058 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335059 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5060 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5061 true, GetRequestHeaders("GET", "https", "/"),
5062 &client_header_stream_offset));
5063 mock_quic_data.AddRead(
5064 ASYNC,
5065 ConstructServerResponseHeadersPacket(
5066 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5067 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5068 mock_quic_data.AddWrite(SYNCHRONOUS,
5069 ConstructClientAckAndRstPacket(
5070 2, GetNthClientInitiatedBidirectionalStreamId(0),
5071 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045072
5073 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5074
5075 spdy::SpdySettingsIR settings_frame;
5076 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5077 quic::kDefaultMaxUncompressedHeaderSize);
5078 spdy::SpdySerializedFrame spdy_frame(
5079 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5080 mock_quic_data.AddWrite(
5081 SYNCHRONOUS,
5082 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565083 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5084 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045085 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5086 client_header_stream_offset += spdy_frame.size();
5087
5088 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335089 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5090 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5091 true, GetRequestHeaders("GET", "https", "/"),
5092 GetNthClientInitiatedBidirectionalStreamId(0),
5093 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045094 mock_quic_data.AddRead(
5095 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335096 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045097 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:435098 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045099 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335100 ASYNC, ConstructServerDataPacket(
5101 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415102 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045103 mock_quic_data.AddWrite(
5104 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5105 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5106 mock_quic_data.AddRead(ASYNC, 0); // EOF
5107
5108 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5109
5110 // In order for a new QUIC session to be established via alternate-protocol
5111 // without racing an HTTP connection, we need the host resolution to happen
5112 // synchronously.
5113 host_resolver_.set_synchronous_mode(true);
5114 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5115 "");
Steven Valdez58097ec32018-07-16 18:29:045116
5117 AddHangingNonAlternateProtocolSocketData();
5118 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275119 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565120 QuicStreamFactoryPeer::SetAlarmFactory(
5121 session_->quic_stream_factory(),
5122 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5123 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045124
5125 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5126 TestCompletionCallback callback;
5127 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5128 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5129
5130 // Confirm the handshake after the 425 Too Early.
5131 base::RunLoop().RunUntilIdle();
5132
5133 // The handshake hasn't been confirmed yet, so the retry should not have
5134 // succeeded.
5135 EXPECT_FALSE(callback.have_result());
5136
5137 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5138 quic::QuicSession::HANDSHAKE_CONFIRMED);
5139
5140 EXPECT_THAT(callback.WaitForResult(), IsOk());
5141 CheckWasQuicResponse(&trans);
5142 CheckResponseData(&trans, "hello!");
5143}
5144
5145TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5146 MockQuicData mock_quic_data;
5147 quic::QuicStreamOffset client_header_stream_offset = 0;
5148 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035149 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045150 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335151 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5152 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5153 true, GetRequestHeaders("GET", "https", "/"),
5154 &client_header_stream_offset));
5155 mock_quic_data.AddRead(
5156 ASYNC,
5157 ConstructServerResponseHeadersPacket(
5158 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5159 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5160 mock_quic_data.AddWrite(SYNCHRONOUS,
5161 ConstructClientAckAndRstPacket(
5162 2, GetNthClientInitiatedBidirectionalStreamId(0),
5163 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045164
5165 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5166
5167 spdy::SpdySettingsIR settings_frame;
5168 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5169 quic::kDefaultMaxUncompressedHeaderSize);
5170 spdy::SpdySerializedFrame spdy_frame(
5171 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5172 mock_quic_data.AddWrite(
5173 SYNCHRONOUS,
5174 client_maker_.MakeDataPacket(
Nick Harper23290b82019-05-02 00:02:565175 3, quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
5176 false, false, client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045177 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5178 client_header_stream_offset += spdy_frame.size();
5179
5180 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335181 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5182 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5183 true, GetRequestHeaders("GET", "https", "/"),
5184 GetNthClientInitiatedBidirectionalStreamId(0),
5185 &client_header_stream_offset));
5186 mock_quic_data.AddRead(
5187 ASYNC,
5188 ConstructServerResponseHeadersPacket(
5189 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5190 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5191 mock_quic_data.AddWrite(SYNCHRONOUS,
5192 ConstructClientAckAndRstPacket(
5193 5, GetNthClientInitiatedBidirectionalStreamId(1),
5194 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045195 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5196 mock_quic_data.AddRead(ASYNC, 0); // EOF
5197
5198 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5199
5200 // In order for a new QUIC session to be established via alternate-protocol
5201 // without racing an HTTP connection, we need the host resolution to happen
5202 // synchronously.
5203 host_resolver_.set_synchronous_mode(true);
5204 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5205 "");
Steven Valdez58097ec32018-07-16 18:29:045206
5207 AddHangingNonAlternateProtocolSocketData();
5208 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275209 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565210 QuicStreamFactoryPeer::SetAlarmFactory(
5211 session_->quic_stream_factory(),
5212 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5213 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045214
5215 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5216 TestCompletionCallback callback;
5217 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5219
5220 // Confirm the handshake after the 425 Too Early.
5221 base::RunLoop().RunUntilIdle();
5222
5223 // The handshake hasn't been confirmed yet, so the retry should not have
5224 // succeeded.
5225 EXPECT_FALSE(callback.have_result());
5226
5227 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5228 quic::QuicSession::HANDSHAKE_CONFIRMED);
5229
5230 EXPECT_THAT(callback.WaitForResult(), IsOk());
5231 const HttpResponseInfo* response = trans.GetResponseInfo();
5232 ASSERT_TRUE(response != nullptr);
5233 ASSERT_TRUE(response->headers.get() != nullptr);
5234 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5235 EXPECT_TRUE(response->was_fetched_via_spdy);
5236 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565237 EXPECT_EQ(
5238 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5239 response->connection_info);
Steven Valdez58097ec32018-07-16 18:29:045240}
5241
zhongyica364fbb2015-12-12 03:39:125242TEST_P(QuicNetworkTransactionTest,
5243 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485244 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125245 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525246 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365247 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435248 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5249 mock_quic_data.AddWrite(
5250 SYNCHRONOUS,
5251 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335252 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435253 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125254 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525255 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435256 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125257 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5258
5259 // The non-alternate protocol job needs to hang in order to guarantee that
5260 // the alternate-protocol job will "win".
5261 AddHangingNonAlternateProtocolSocketData();
5262
5263 // In order for a new QUIC session to be established via alternate-protocol
5264 // without racing an HTTP connection, we need the host resolution to happen
5265 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5266 // connection to the the server, in this test we require confirmation
5267 // before encrypting so the HTTP job will still start.
5268 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295269 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125270 "");
zhongyica364fbb2015-12-12 03:39:125271
rch3f4b8452016-02-23 16:59:325272 CreateSession();
zhongyica364fbb2015-12-12 03:39:125273 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275274 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125275
bnc691fda62016-08-12 00:43:165276 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125277 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365278 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015279 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125280
5281 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525282 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015283 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125284
5285 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525286 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125287
bnc691fda62016-08-12 00:43:165288 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125289 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525290 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5291 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125292}
5293
5294TEST_P(QuicNetworkTransactionTest,
5295 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485296 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125297 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525298 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365299 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435300 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5301 mock_quic_data.AddWrite(
5302 SYNCHRONOUS,
5303 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335304 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435305 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215306 // Peer sending data from an non-existing stream causes this end to raise
5307 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335308 mock_quic_data.AddRead(
5309 ASYNC, ConstructServerRstPacket(
5310 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5311 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215312 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525313 mock_quic_data.AddWrite(
5314 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5315 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5316 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125317 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5318
5319 // The non-alternate protocol job needs to hang in order to guarantee that
5320 // the alternate-protocol job will "win".
5321 AddHangingNonAlternateProtocolSocketData();
5322
5323 // In order for a new QUIC session to be established via alternate-protocol
5324 // without racing an HTTP connection, we need the host resolution to happen
5325 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5326 // connection to the the server, in this test we require confirmation
5327 // before encrypting so the HTTP job will still start.
5328 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295329 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125330 "");
zhongyica364fbb2015-12-12 03:39:125331
rch3f4b8452016-02-23 16:59:325332 CreateSession();
zhongyica364fbb2015-12-12 03:39:125333 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275334 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125335
bnc691fda62016-08-12 00:43:165336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125337 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365338 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015339 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125340
5341 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525342 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015343 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125344 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525345 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125346
bnc691fda62016-08-12 00:43:165347 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525348 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125349}
5350
rchcd5f1c62016-06-23 02:43:485351TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5352 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525353 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365354 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435355 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5356 mock_quic_data.AddWrite(
5357 SYNCHRONOUS,
5358 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335359 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435360 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485361 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335362 mock_quic_data.AddRead(
5363 ASYNC, ConstructServerResponseHeadersPacket(
5364 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5365 GetResponseHeaders("200 OK")));
5366 mock_quic_data.AddRead(
5367 ASYNC, ConstructServerRstPacket(
5368 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5369 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435370 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485371 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5372 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5373
5374 // The non-alternate protocol job needs to hang in order to guarantee that
5375 // the alternate-protocol job will "win".
5376 AddHangingNonAlternateProtocolSocketData();
5377
5378 // In order for a new QUIC session to be established via alternate-protocol
5379 // without racing an HTTP connection, we need the host resolution to happen
5380 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5381 // connection to the the server, in this test we require confirmation
5382 // before encrypting so the HTTP job will still start.
5383 host_resolver_.set_synchronous_mode(true);
5384 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5385 "");
rchcd5f1c62016-06-23 02:43:485386
5387 CreateSession();
5388 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275389 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485390
bnc691fda62016-08-12 00:43:165391 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485392 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365393 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015394 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485395
5396 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525397 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485398 // Read the headers.
robpercival214763f2016-07-01 23:27:015399 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485400
bnc691fda62016-08-12 00:43:165401 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485402 ASSERT_TRUE(response != nullptr);
5403 ASSERT_TRUE(response->headers.get() != nullptr);
5404 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5405 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525406 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:565407 EXPECT_EQ(
5408 QuicHttpStream::ConnectionInfoFromQuicVersion(version_.transport_version),
5409 response->connection_info);
rchcd5f1c62016-06-23 02:43:485410
5411 std::string response_data;
bnc691fda62016-08-12 00:43:165412 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485413}
5414
5415TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485416 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485417 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525418 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365419 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435420 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5421 mock_quic_data.AddWrite(
5422 SYNCHRONOUS,
5423 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335424 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435425 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335426 mock_quic_data.AddRead(
5427 ASYNC, ConstructServerRstPacket(
5428 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5429 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485430 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5431 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5432
5433 // The non-alternate protocol job needs to hang in order to guarantee that
5434 // the alternate-protocol job will "win".
5435 AddHangingNonAlternateProtocolSocketData();
5436
5437 // In order for a new QUIC session to be established via alternate-protocol
5438 // without racing an HTTP connection, we need the host resolution to happen
5439 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5440 // connection to the the server, in this test we require confirmation
5441 // before encrypting so the HTTP job will still start.
5442 host_resolver_.set_synchronous_mode(true);
5443 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5444 "");
rchcd5f1c62016-06-23 02:43:485445
5446 CreateSession();
5447 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275448 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485449
bnc691fda62016-08-12 00:43:165450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485451 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365452 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485454
5455 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525456 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485457 // Read the headers.
robpercival214763f2016-07-01 23:27:015458 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485459}
5460
[email protected]1e960032013-12-20 19:00:205461TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305462 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525463 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585464 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305465 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505466 MockRead(ASYNC, close->data(), close->length()),
5467 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5468 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305469 };
Ryan Sleevib8d7ea02018-05-07 20:01:015470 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305471 socket_factory_.AddSocketDataProvider(&quic_data);
5472
5473 // Main job which will succeed even though the alternate job fails.
5474 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025475 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5476 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5477 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305478
Ryan Sleevib8d7ea02018-05-07 20:01:015479 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305480 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565481 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305482
rch3f4b8452016-02-23 16:59:325483 CreateSession();
David Schinazic8281052019-01-24 06:14:175484 AddQuicAlternateProtocolMapping(
5485 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195486 SendRequestAndExpectHttpResponse("hello from http");
5487 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305488}
5489
[email protected]1e960032013-12-20 19:00:205490TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595491 // Alternate-protocol job
5492 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025493 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595494 };
Ryan Sleevib8d7ea02018-05-07 20:01:015495 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595496 socket_factory_.AddSocketDataProvider(&quic_data);
5497
5498 // Main job which will succeed even though the alternate job fails.
5499 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025500 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5501 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5502 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595503
Ryan Sleevib8d7ea02018-05-07 20:01:015504 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595505 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565506 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595507
rch3f4b8452016-02-23 16:59:325508 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595509
Ryan Hamilton9835e662018-08-02 05:36:275510 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195511 SendRequestAndExpectHttpResponse("hello from http");
5512 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595513}
5514
[email protected]00c159f2014-05-21 22:38:165515TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535516 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165517 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025518 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165519 };
Ryan Sleevib8d7ea02018-05-07 20:01:015520 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165521 socket_factory_.AddSocketDataProvider(&quic_data);
5522
[email protected]eb71ab62014-05-23 07:57:535523 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165524 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025525 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165526 };
5527
Ryan Sleevib8d7ea02018-05-07 20:01:015528 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165529 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5530 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565531 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165532
rtennetib8e80fb2016-05-16 00:12:095533 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325534 CreateSession();
[email protected]00c159f2014-05-21 22:38:165535
Ryan Hamilton9835e662018-08-02 05:36:275536 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165537 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165538 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165539 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5541 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165542 ExpectQuicAlternateProtocolMapping();
5543}
5544
Zhongyi Shia0cef1082017-08-25 01:49:505545TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5546 // Tests that TCP job is delayed and QUIC job does not require confirmation
5547 // if QUIC was recently supported on the same IP on start.
5548
5549 // Set QUIC support on the last IP address, which is same with the local IP
5550 // address. Require confirmation mode will be turned off immediately when
5551 // local IP address is sorted out after we configure the UDP socket.
5552 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5553
5554 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525555 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035556 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435557 mock_quic_data.AddWrite(
5558 SYNCHRONOUS,
5559 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335560 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435561 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435562 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335563 ASYNC, ConstructServerResponseHeadersPacket(
5564 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5565 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435566 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335567 mock_quic_data.AddRead(
5568 ASYNC, ConstructServerDataPacket(
5569 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415570 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435571 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505572 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5573 mock_quic_data.AddRead(ASYNC, 0); // EOF
5574
5575 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5576 // No HTTP data is mocked as TCP job never starts in this case.
5577
5578 CreateSession();
5579 // QuicStreamFactory by default requires confirmation on construction.
5580 session_->quic_stream_factory()->set_require_confirmation(true);
5581
Ryan Hamilton9835e662018-08-02 05:36:275582 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505583
5584 // Stall host resolution so that QUIC job will not succeed synchronously.
5585 // Socket will not be configured immediately and QUIC support is not sorted
5586 // out, TCP job will still be delayed as server properties indicates QUIC
5587 // support on last IP address.
5588 host_resolver_.set_synchronous_mode(false);
5589
5590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5591 TestCompletionCallback callback;
5592 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5593 IsError(ERR_IO_PENDING));
5594 // Complete host resolution in next message loop so that QUIC job could
5595 // proceed.
5596 base::RunLoop().RunUntilIdle();
5597 EXPECT_THAT(callback.WaitForResult(), IsOk());
5598
5599 CheckWasQuicResponse(&trans);
5600 CheckResponseData(&trans, "hello!");
5601}
5602
5603TEST_P(QuicNetworkTransactionTest,
5604 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5605 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5606 // was recently supported on a different IP address on start.
5607
5608 // Set QUIC support on the last IP address, which is different with the local
5609 // IP address. Require confirmation mode will remain when local IP address is
5610 // sorted out after we configure the UDP socket.
5611 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5612
5613 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525614 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505615 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435616 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5617 mock_quic_data.AddWrite(
5618 SYNCHRONOUS,
5619 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335620 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435621 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435622 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335623 ASYNC, ConstructServerResponseHeadersPacket(
5624 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5625 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435626 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335627 mock_quic_data.AddRead(
5628 ASYNC, ConstructServerDataPacket(
5629 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415630 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435631 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505632 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5633 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5634 // No HTTP data is mocked as TCP job will be delayed and never starts.
5635
5636 CreateSession();
5637 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275638 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505639
5640 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5641 // Socket will not be configured immediately and QUIC support is not sorted
5642 // out, TCP job will still be delayed as server properties indicates QUIC
5643 // support on last IP address.
5644 host_resolver_.set_synchronous_mode(false);
5645
5646 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5647 TestCompletionCallback callback;
5648 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5649 IsError(ERR_IO_PENDING));
5650
5651 // Complete host resolution in next message loop so that QUIC job could
5652 // proceed.
5653 base::RunLoop().RunUntilIdle();
5654 // Explicitly confirm the handshake so that QUIC job could succeed.
5655 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525656 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505657 EXPECT_THAT(callback.WaitForResult(), IsOk());
5658
5659 CheckWasQuicResponse(&trans);
5660 CheckResponseData(&trans, "hello!");
5661}
5662
Ryan Hamilton75f197262017-08-17 14:00:075663TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5664 // Test that NetErrorDetails is correctly populated, even if the
5665 // handshake has not yet been confirmed and no stream has been created.
5666
5667 // QUIC job will pause. When resumed, it will fail.
5668 MockQuicData mock_quic_data;
5669 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5670 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5671 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5672
5673 // Main job will also fail.
5674 MockRead http_reads[] = {
5675 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5676 };
5677
Ryan Sleevib8d7ea02018-05-07 20:01:015678 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075679 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5680 socket_factory_.AddSocketDataProvider(&http_data);
5681 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5682
5683 AddHangingNonAlternateProtocolSocketData();
5684 CreateSession();
5685 // Require handshake confirmation to ensure that no QUIC streams are
5686 // created, and to ensure that the TCP job does not wait for the QUIC
5687 // job to fail before it starts.
5688 session_->quic_stream_factory()->set_require_confirmation(true);
5689
Ryan Hamilton9835e662018-08-02 05:36:275690 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075691 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5692 TestCompletionCallback callback;
5693 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5695 // Allow the TCP job to fail.
5696 base::RunLoop().RunUntilIdle();
5697 // Now let the QUIC job fail.
5698 mock_quic_data.Resume();
5699 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5700 ExpectQuicAlternateProtocolMapping();
5701 NetErrorDetails details;
5702 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525703 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075704}
5705
[email protected]1e960032013-12-20 19:00:205706TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455707 // Alternate-protocol job
5708 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025709 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455710 };
Ryan Sleevib8d7ea02018-05-07 20:01:015711 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455712 socket_factory_.AddSocketDataProvider(&quic_data);
5713
[email protected]c92c1b52014-05-31 04:16:065714 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015715 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065716 socket_factory_.AddSocketDataProvider(&quic_data2);
5717
[email protected]4d283b32013-10-17 12:57:275718 // Final job that will proceed when the QUIC job fails.
5719 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025720 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5721 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5722 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275723
Ryan Sleevib8d7ea02018-05-07 20:01:015724 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275725 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565726 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275727
rtennetiafccbc062016-05-16 18:21:145728 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325729 CreateSession();
[email protected]77c6c162013-08-17 02:57:455730
Ryan Hamilton9835e662018-08-02 05:36:275731 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455732
[email protected]4d283b32013-10-17 12:57:275733 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455734
5735 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275736
rch37de576c2015-05-17 20:28:175737 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5738 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455739}
5740
[email protected]93b31772014-06-19 08:03:355741TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035742 // Alternate-protocol job
5743 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595744 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035745 };
Ryan Sleevib8d7ea02018-05-07 20:01:015746 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035747 socket_factory_.AddSocketDataProvider(&quic_data);
5748
5749 // Main job that will proceed when the QUIC job fails.
5750 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025751 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5752 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5753 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035754
Ryan Sleevib8d7ea02018-05-07 20:01:015755 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035756 socket_factory_.AddSocketDataProvider(&http_data);
5757
rtennetib8e80fb2016-05-16 00:12:095758 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325759 CreateSession();
[email protected]65768442014-06-06 23:37:035760
Ryan Hamilton9835e662018-08-02 05:36:275761 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035762
5763 SendRequestAndExpectHttpResponse("hello from http");
5764}
5765
[email protected]eb71ab62014-05-23 07:57:535766TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335767 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015768 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495769 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335770 socket_factory_.AddSocketDataProvider(&quic_data);
5771
5772 // Main job which will succeed even though the alternate job fails.
5773 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025774 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5775 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5776 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335777
Ryan Sleevib8d7ea02018-05-07 20:01:015778 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335779 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565780 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335781
rch3f4b8452016-02-23 16:59:325782 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275783 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335784 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535785
5786 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335787}
5788
[email protected]4fee9672014-01-08 14:47:155789TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155790 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175791 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5792 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045793 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155794
5795 // When the QUIC connection fails, we will try the request again over HTTP.
5796 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485797 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565798 MockRead("hello world"),
5799 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5800 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155801
Ryan Sleevib8d7ea02018-05-07 20:01:015802 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155803 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565804 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155805
5806 // In order for a new QUIC session to be established via alternate-protocol
5807 // without racing an HTTP connection, we need the host resolution to happen
5808 // synchronously.
5809 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295810 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565811 "");
[email protected]4fee9672014-01-08 14:47:155812
rch3f4b8452016-02-23 16:59:325813 CreateSession();
David Schinazic8281052019-01-24 06:14:175814 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5815 AddQuicAlternateProtocolMapping(
5816 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155817 SendRequestAndExpectHttpResponse("hello world");
5818}
5819
tbansalc3308d72016-08-27 10:25:045820// For an alternative proxy that supports QUIC, test that the request is
5821// successfully fetched by the main job when the alternate proxy job encounters
5822// an error.
5823TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5824 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5825}
5826TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5827 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5828}
5829TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5830 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5831}
5832TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5833 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5834}
5835TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5836 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5837}
5838TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5839 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5840}
5841TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5842 TestAlternativeProxy(ERR_IO_PENDING);
5843}
5844TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5845 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5846}
5847
5848TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5849 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175850 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5851 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335852 mock_quic_data.AddWrite(
5853 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5854 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5855 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435856 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045857 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5858
5859 // When the QUIC connection fails, we will try the request again over HTTP.
5860 MockRead http_reads[] = {
5861 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5862 MockRead("hello world"),
5863 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5864 MockRead(ASYNC, OK)};
5865
Ryan Sleevib8d7ea02018-05-07 20:01:015866 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045867 socket_factory_.AddSocketDataProvider(&http_data);
5868 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5869
5870 TestProxyDelegate test_proxy_delegate;
5871 const HostPortPair host_port_pair("myproxy.org", 443);
5872 test_proxy_delegate.set_alternative_proxy_server(
5873 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5874 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5875
Ramin Halavatica8d5252018-03-12 05:33:495876 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5877 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525878 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045879 request_.url = GURL("http://mail.example.org/");
5880
5881 // In order for a new QUIC session to be established via alternate-protocol
5882 // without racing an HTTP connection, we need the host resolution to happen
5883 // synchronously.
5884 host_resolver_.set_synchronous_mode(true);
5885 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045886
5887 CreateSession();
David Schinazic8281052019-01-24 06:14:175888 crypto_client_stream_factory_.set_handshake_mode(
5889 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045890 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595891 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165892 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045893}
5894
bnc508835902015-05-12 20:10:295895TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585896 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385897 EXPECT_FALSE(
5898 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295899 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525900 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365901 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435902 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5903 mock_quic_data.AddWrite(
5904 SYNCHRONOUS,
5905 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335906 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435907 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435908 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335909 ASYNC, ConstructServerResponseHeadersPacket(
5910 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5911 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435912 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335913 mock_quic_data.AddRead(
5914 ASYNC, ConstructServerDataPacket(
5915 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415916 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435917 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505918 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295919 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5920
bncb07c05532015-05-14 19:07:205921 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095922 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325923 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275924 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295925 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385926 EXPECT_TRUE(
5927 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295928}
5929
zhongyi363c91c2017-03-23 23:16:085930// TODO(zhongyi): disabled this broken test as it was not testing the correct
5931// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5932TEST_P(QuicNetworkTransactionTest,
5933 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275934 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595935 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495936 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045937
5938 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045939
5940 test_proxy_delegate.set_alternative_proxy_server(
5941 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525942 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045943
5944 request_.url = GURL("http://mail.example.org/");
5945
5946 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5947 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015948 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045949 socket_factory_.AddSocketDataProvider(&socket_data);
5950
5951 // The non-alternate protocol job needs to hang in order to guarantee that
5952 // the alternate-protocol job will "win".
5953 AddHangingNonAlternateProtocolSocketData();
5954
5955 CreateSession();
5956 request_.method = "POST";
5957 ChunkedUploadDataStream upload_data(0);
5958 upload_data.AppendData("1", 1, true);
5959
5960 request_.upload_data_stream = &upload_data;
5961
5962 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5963 TestCompletionCallback callback;
5964 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5966 EXPECT_NE(OK, callback.WaitForResult());
5967
5968 // Verify that the alternative proxy server is not marked as broken.
5969 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5970
5971 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595972 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275973
5974 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5975 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5976 1);
tbansalc3308d72016-08-27 10:25:045977}
5978
rtenneti56977812016-01-15 19:26:565979TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415980 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575981 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565982
5983 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5984 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015985 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565986 socket_factory_.AddSocketDataProvider(&socket_data);
5987
rtennetib8e80fb2016-05-16 00:12:095988 // The non-alternate protocol job needs to hang in order to guarantee that
5989 // the alternate-protocol job will "win".
5990 AddHangingNonAlternateProtocolSocketData();
5991
rtenneti56977812016-01-15 19:26:565992 CreateSession();
5993 request_.method = "POST";
5994 ChunkedUploadDataStream upload_data(0);
5995 upload_data.AppendData("1", 1, true);
5996
5997 request_.upload_data_stream = &upload_data;
5998
bnc691fda62016-08-12 00:43:165999 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566000 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166001 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016002 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566003 EXPECT_NE(OK, callback.WaitForResult());
6004}
6005
rche11300ef2016-09-02 01:44:286006TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486007 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286008 ScopedMockNetworkChangeNotifier network_change_notifier;
6009 MockNetworkChangeNotifier* mock_ncn =
6010 network_change_notifier.mock_network_change_notifier();
6011 mock_ncn->ForceNetworkHandlesSupported();
6012 mock_ncn->SetConnectedNetworksList(
6013 {kDefaultNetworkForTests, kNewNetworkForTests});
6014
mmenke6ddfbea2017-05-31 21:48:416015 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286016 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316017 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286018
6019 MockQuicData socket_data;
6020 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526021 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436022 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336023 socket_data.AddWrite(
6024 SYNCHRONOUS,
6025 ConstructClientRequestHeadersPacket(
6026 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6027 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286028 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6029 socket_data.AddSocketDataToFactory(&socket_factory_);
6030
6031 MockQuicData socket_data2;
6032 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6033 socket_data2.AddSocketDataToFactory(&socket_factory_);
6034
6035 // The non-alternate protocol job needs to hang in order to guarantee that
6036 // the alternate-protocol job will "win".
6037 AddHangingNonAlternateProtocolSocketData();
6038
6039 CreateSession();
6040 request_.method = "POST";
6041 ChunkedUploadDataStream upload_data(0);
6042
6043 request_.upload_data_stream = &upload_data;
6044
rdsmith1d343be52016-10-21 20:37:506045 std::unique_ptr<HttpNetworkTransaction> trans(
6046 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286047 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506048 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286049 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6050
6051 base::RunLoop().RunUntilIdle();
6052 upload_data.AppendData("1", 1, true);
6053 base::RunLoop().RunUntilIdle();
6054
6055 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506056 trans.reset();
rche11300ef2016-09-02 01:44:286057 session_.reset();
6058}
6059
Ryan Hamilton4b3574532017-10-30 20:17:256060TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6061 session_params_.origins_to_force_quic_on.insert(
6062 HostPortPair::FromString("mail.example.org:443"));
6063
6064 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526065 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436066 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256067 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336068 socket_data.AddWrite(
6069 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6070 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6071 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436072 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336073 ASYNC, ConstructServerResponseHeadersPacket(
6074 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6075 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436076 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336077 socket_data.AddRead(
6078 ASYNC, ConstructServerDataPacket(
6079 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416080 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436081 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256082 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166083 socket_data.AddWrite(
6084 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6085 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6086 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256087
6088 socket_data.AddSocketDataToFactory(&socket_factory_);
6089
6090 CreateSession();
6091
6092 SendRequestAndExpectQuicResponse("hello!");
6093 session_.reset();
6094}
6095
6096TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6097 session_params_.origins_to_force_quic_on.insert(
6098 HostPortPair::FromString("mail.example.org:443"));
6099
6100 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526101 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436102 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256103 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336104 socket_data.AddWrite(
6105 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6106 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6107 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436108 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336109 ASYNC, ConstructServerResponseHeadersPacket(
6110 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6111 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436112 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336113 socket_data.AddRead(
6114 ASYNC, ConstructServerDataPacket(
6115 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416116 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436117 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256118 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166119 socket_data.AddWrite(
6120 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6121 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6122 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256123
6124 socket_data.AddSocketDataToFactory(&socket_factory_);
6125
6126 CreateSession();
6127
6128 SendRequestAndExpectQuicResponse("hello!");
6129 session_.reset();
6130}
6131
Ryan Hamilton9edcf1a2017-11-22 05:55:176132TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486133 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256134 session_params_.origins_to_force_quic_on.insert(
6135 HostPortPair::FromString("mail.example.org:443"));
6136
6137 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526138 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256139 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436140 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176141 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256142 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6143 }
6144 socket_data.AddSocketDataToFactory(&socket_factory_);
6145
6146 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176147 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176148 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6149 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256150
Ryan Hamilton8d9ee76e2018-05-29 23:52:526151 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256152 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6153 TestCompletionCallback callback;
6154 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176156 while (!callback.have_result()) {
6157 base::RunLoop().RunUntilIdle();
6158 quic_task_runner_->RunUntilIdle();
6159 }
6160 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256161 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176162 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6163 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6164 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526165 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6166 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256167}
6168
Ryan Hamilton9edcf1a2017-11-22 05:55:176169TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486170 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256171 session_params_.origins_to_force_quic_on.insert(
6172 HostPortPair::FromString("mail.example.org:443"));
6173
6174 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526175 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256176 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436177 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176178 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256179 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6180 }
6181 socket_data.AddSocketDataToFactory(&socket_factory_);
6182
6183 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176184 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
Ryan Hamilton9edcf1a2017-11-22 05:55:176185 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6186 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256187
Ryan Hamilton8d9ee76e2018-05-29 23:52:526188 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256189 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6190 TestCompletionCallback callback;
6191 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6192 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176193 while (!callback.have_result()) {
6194 base::RunLoop().RunUntilIdle();
6195 quic_task_runner_->RunUntilIdle();
6196 }
6197 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256198 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176199 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6200 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6201 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526202 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6203 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256204}
6205
Cherie Shi7596de632018-02-22 07:28:186206TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486207 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186208 session_params_.origins_to_force_quic_on.insert(
6209 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436210 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526211 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6212 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186213
6214 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526215 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186216 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436217 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186218 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6219 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526220 socket_data.AddWrite(
6221 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6222 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186223 socket_data.AddSocketDataToFactory(&socket_factory_);
6224
6225 CreateSession();
6226
6227 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6228 TestCompletionCallback callback;
6229 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6231 base::RunLoop().RunUntilIdle();
6232 ASSERT_TRUE(callback.have_result());
6233 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6234 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6235 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6236}
6237
ckrasic769733c2016-06-30 00:42:136238// Adds coverage to catch regression such as https://crbug.com/622043
6239TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416240 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136241 HostPortPair::FromString("mail.example.org:443"));
6242
6243 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526244 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236245 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436246 mock_quic_data.AddWrite(
6247 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6248 &header_stream_offset));
6249 mock_quic_data.AddWrite(
6250 SYNCHRONOUS,
6251 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336252 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6253 true, true, GetRequestHeaders("GET", "https", "/"),
6254 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526255 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436256 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336257 ASYNC, ConstructServerPushPromisePacket(
6258 1, GetNthClientInitiatedBidirectionalStreamId(0),
6259 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6260 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6261 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576262 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566263 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336264 mock_quic_data.AddWrite(SYNCHRONOUS,
6265 ConstructClientPriorityPacket(
6266 client_packet_number++, false,
6267 GetNthServerInitiatedUnidirectionalStreamId(0),
6268 GetNthClientInitiatedBidirectionalStreamId(0),
6269 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576270 }
Zhongyi Shi32f2fd02018-04-16 18:23:436271 mock_quic_data.AddRead(
6272 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336273 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436274 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576275 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436276 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6277 mock_quic_data.AddRead(
6278 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336279 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6280 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436281 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436282 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336283 ASYNC, ConstructServerDataPacket(
6284 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416285 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576286 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436287 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436288 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436289 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336290 ASYNC, ConstructServerDataPacket(
6291 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416292 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336293 mock_quic_data.AddWrite(SYNCHRONOUS,
6294 ConstructClientAckAndRstPacket(
6295 client_packet_number++,
6296 GetNthServerInitiatedUnidirectionalStreamId(0),
6297 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136298 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6299 mock_quic_data.AddRead(ASYNC, 0); // EOF
6300 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6301
6302 // The non-alternate protocol job needs to hang in order to guarantee that
6303 // the alternate-protocol job will "win".
6304 AddHangingNonAlternateProtocolSocketData();
6305
6306 CreateSession();
6307
6308 // PUSH_PROMISE handling in the http layer gets exercised here.
6309 SendRequestAndExpectQuicResponse("hello!");
6310
6311 request_.url = GURL("https://mail.example.org/pushed.jpg");
6312 SendRequestAndExpectQuicResponse("and hello!");
6313
6314 // Check that the NetLog was filled reasonably.
6315 TestNetLogEntry::List entries;
6316 net_log_.GetEntries(&entries);
6317 EXPECT_LT(0u, entries.size());
6318
6319 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6320 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006321 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6322 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136323 EXPECT_LT(0, pos);
6324}
6325
rch56ec40a2017-06-23 14:48:446326// Regression test for http://crbug.com/719461 in which a promised stream
6327// is closed before the pushed headers arrive, but after the connection
6328// is closed and before the callbacks are executed.
6329TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486330 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446331 session_params_.origins_to_force_quic_on.insert(
6332 HostPortPair::FromString("mail.example.org:443"));
6333
6334 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526335 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236336 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446337 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436338 mock_quic_data.AddWrite(
6339 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6340 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446341 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436342 mock_quic_data.AddWrite(
6343 SYNCHRONOUS,
6344 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336345 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6346 true, true, GetRequestHeaders("GET", "https", "/"),
6347 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526348 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446349 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436350 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336351 ASYNC, ConstructServerPushPromisePacket(
6352 1, GetNthClientInitiatedBidirectionalStreamId(0),
6353 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6354 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6355 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576356 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566357 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336358 mock_quic_data.AddWrite(SYNCHRONOUS,
6359 ConstructClientPriorityPacket(
6360 client_packet_number++, false,
6361 GetNthServerInitiatedUnidirectionalStreamId(0),
6362 GetNthClientInitiatedBidirectionalStreamId(0),
6363 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576364 }
rch56ec40a2017-06-23 14:48:446365 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436366 mock_quic_data.AddRead(
6367 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336368 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436369 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446370 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576371 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436372 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446373 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436374 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436375 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336376 ASYNC, ConstructServerDataPacket(
6377 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416378 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446379 // Write error for the third request.
6380 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6381 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6382 mock_quic_data.AddRead(ASYNC, 0); // EOF
6383 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6384
6385 CreateSession();
6386
6387 // Send a request which triggers a push promise from the server.
6388 SendRequestAndExpectQuicResponse("hello!");
6389
6390 // Start a push transaction that will be cancelled after the connection
6391 // is closed, but before the callback is executed.
6392 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196393 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446394 session_.get());
6395 TestCompletionCallback callback2;
6396 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6398 base::RunLoop().RunUntilIdle();
6399
6400 // Cause the connection to close on a write error.
6401 HttpRequestInfo request3;
6402 request3.method = "GET";
6403 request3.url = GURL("https://mail.example.org/");
6404 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106405 request3.traffic_annotation =
6406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446407 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6408 TestCompletionCallback callback3;
6409 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6410 IsError(ERR_IO_PENDING));
6411
6412 base::RunLoop().RunUntilIdle();
6413
6414 // When |trans2| is destroyed, the underlying stream will be closed.
6415 EXPECT_FALSE(callback2.have_result());
6416 trans2 = nullptr;
6417
6418 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6419}
6420
ckrasicda193a82016-07-09 00:39:366421TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416422 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366423 HostPortPair::FromString("mail.example.org:443"));
6424
6425 MockQuicData mock_quic_data;
6426
Ryan Hamilton8d9ee76e2018-05-29 23:52:526427 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416428 int write_packet_index = 1;
6429 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6430 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366431
Victor Vasiliev076657c2019-03-12 02:46:436432 std::string header = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:566433 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416434 mock_quic_data.AddWrite(
6435 SYNCHRONOUS,
6436 ConstructClientRequestHeadersAndDataFramesPacket(
6437 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6438 true, true, DEFAULT_PRIORITY,
6439 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6440 {"1"}));
6441 } else {
6442 mock_quic_data.AddWrite(
6443 SYNCHRONOUS,
6444 ConstructClientRequestHeadersAndDataFramesPacket(
6445 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6446 true, true, DEFAULT_PRIORITY,
6447 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6448 {header, "1"}));
6449 }
ckrasicda193a82016-07-09 00:39:366450
Zhongyi Shi32f2fd02018-04-16 18:23:436451 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336452 ASYNC, ConstructServerResponseHeadersPacket(
6453 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6454 GetResponseHeaders("200 OK")));
6455
Victor Vasiliev076657c2019-03-12 02:46:436456 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336457 mock_quic_data.AddRead(
6458 ASYNC, ConstructServerDataPacket(
6459 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416460 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366461
Renjief49758b2019-01-11 23:32:416462 mock_quic_data.AddWrite(
6463 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366464
6465 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6466 mock_quic_data.AddRead(ASYNC, 0); // EOF
6467 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6468
6469 // The non-alternate protocol job needs to hang in order to guarantee that
6470 // the alternate-protocol job will "win".
6471 AddHangingNonAlternateProtocolSocketData();
6472
6473 CreateSession();
6474 request_.method = "POST";
6475 ChunkedUploadDataStream upload_data(0);
6476 upload_data.AppendData("1", 1, true);
6477
6478 request_.upload_data_stream = &upload_data;
6479
6480 SendRequestAndExpectQuicResponse("hello!");
6481}
6482
allada71b2efb2016-09-09 04:57:486483class QuicURLRequestContext : public URLRequestContext {
6484 public:
6485 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6486 MockClientSocketFactory* socket_factory)
6487 : storage_(this) {
6488 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076489 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046490 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486491 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046492 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596493 storage_.set_proxy_resolution_service(
6494 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076495 storage_.set_ssl_config_service(
6496 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486497 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116498 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486499 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076500 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046501 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486502 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046503 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6504 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6505 false));
allada71b2efb2016-09-09 04:57:486506 }
6507
6508 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6509
6510 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6511
6512 private:
6513 MockClientSocketFactory* socket_factory_;
6514 URLRequestContextStorage storage_;
6515};
6516
6517TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416518 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486519 HostPortPair::FromString("mail.example.org:443"));
6520
6521 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526522 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366523 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436524 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136525 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486526 headers["user-agent"] = "";
6527 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336528 mock_quic_data.AddWrite(
6529 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6530 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6531 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486532
Ryan Hamilton8d9ee76e2018-05-29 23:52:526533 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336534 mock_quic_data.AddRead(
6535 ASYNC,
6536 ConstructServerResponseHeadersPacket(
6537 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6538 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486539
Victor Vasiliev076657c2019-03-12 02:46:436540 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366541 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336542 ASYNC, ConstructServerDataPacket(
6543 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6544 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436545 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486546
6547 mock_quic_data.AddRead(ASYNC, 0); // EOF
6548
6549 CreateSession();
6550
6551 TestDelegate delegate;
6552 QuicURLRequestContext quic_url_request_context(std::move(session_),
6553 &socket_factory_);
6554
6555 mock_quic_data.AddSocketDataToFactory(
6556 &quic_url_request_context.socket_factory());
6557 TestNetworkDelegate network_delegate;
6558 quic_url_request_context.set_network_delegate(&network_delegate);
6559
6560 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296561 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6562 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486563 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6564 &ssl_data_);
6565
6566 request->Start();
Wez2a31b222018-06-07 22:07:156567 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486568
6569 EXPECT_LT(0, request->GetTotalSentBytes());
6570 EXPECT_LT(0, request->GetTotalReceivedBytes());
6571 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6572 request->GetTotalSentBytes());
6573 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6574 request->GetTotalReceivedBytes());
6575 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6576 request->raw_header_size());
Wez0e717112018-06-18 23:09:226577
6578 // Pump the message loop to allow all data to be consumed.
6579 base::RunLoop().RunUntilIdle();
6580
allada71b2efb2016-09-09 04:57:486581 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6582 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6583}
6584
6585TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416586 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486587 HostPortPair::FromString("mail.example.org:443"));
6588
6589 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526590 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236591 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436592 mock_quic_data.AddWrite(
6593 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6594 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136595 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486596 headers["user-agent"] = "";
6597 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436598 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336599 SYNCHRONOUS,
6600 ConstructClientRequestHeadersPacket(
6601 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6602 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486603
Ryan Hamilton8d9ee76e2018-05-29 23:52:526604 quic::QuicStreamOffset server_header_offset = 0;
6605 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486606
Zhongyi Shi32f2fd02018-04-16 18:23:436607 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336608 ASYNC, ConstructServerPushPromisePacket(
6609 1, GetNthClientInitiatedBidirectionalStreamId(0),
6610 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6611 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6612 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486613
Yixin Wangb470bc882018-02-15 18:43:576614 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:566615 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336616 mock_quic_data.AddWrite(SYNCHRONOUS,
6617 ConstructClientPriorityPacket(
6618 client_packet_number++, false,
6619 GetNthServerInitiatedUnidirectionalStreamId(0),
6620 GetNthClientInitiatedBidirectionalStreamId(0),
6621 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576622 }
6623
allada71b2efb2016-09-09 04:57:486624 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436625 mock_quic_data.AddRead(
6626 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336627 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436628 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486629 expected_raw_header_response_size =
6630 server_header_offset - expected_raw_header_response_size;
6631
Yixin Wangb470bc882018-02-15 18:43:576632 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436633 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486634
ckrasicbf2f59c2017-05-04 23:54:366635 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436636 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336637 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6638 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436639 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436640 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336641 ASYNC, ConstructServerDataPacket(
6642 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416643 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486644
Yixin Wangb470bc882018-02-15 18:43:576645 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436646 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436647 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366648 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336649 ASYNC, ConstructServerDataPacket(
6650 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416651 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486652
Zhongyi Shi32f2fd02018-04-16 18:23:436653 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486654
6655 CreateSession();
6656
6657 TestDelegate delegate;
6658 QuicURLRequestContext quic_url_request_context(std::move(session_),
6659 &socket_factory_);
6660
6661 mock_quic_data.AddSocketDataToFactory(
6662 &quic_url_request_context.socket_factory());
6663 TestNetworkDelegate network_delegate;
6664 quic_url_request_context.set_network_delegate(&network_delegate);
6665
6666 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296667 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6668 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486669 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6670 &ssl_data_);
6671
6672 request->Start();
Wez2a31b222018-06-07 22:07:156673 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486674
6675 EXPECT_LT(0, request->GetTotalSentBytes());
6676 EXPECT_LT(0, request->GetTotalReceivedBytes());
6677 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6678 request->GetTotalSentBytes());
6679 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6680 request->GetTotalReceivedBytes());
6681 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6682 request->raw_header_size());
Wez0e717112018-06-18 23:09:226683
6684 // Pump the message loop to allow all data to be consumed.
6685 base::RunLoop().RunUntilIdle();
6686
allada71b2efb2016-09-09 04:57:486687 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6688 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6689}
6690
Yixin Wang10f477ed2017-11-21 04:20:206691TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6692 session_params_.quic_host_whitelist.insert("mail.example.org");
6693
6694 MockRead http_reads[] = {
6695 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6696 MockRead("hello world"),
6697 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6698 MockRead(ASYNC, OK)};
6699
Ryan Sleevib8d7ea02018-05-07 20:01:016700 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206701 socket_factory_.AddSocketDataProvider(&http_data);
6702 AddCertificate(&ssl_data_);
6703 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6704
6705 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526706 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206707 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436708 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6709 mock_quic_data.AddWrite(
6710 SYNCHRONOUS,
6711 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336712 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436713 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436714 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336715 ASYNC, ConstructServerResponseHeadersPacket(
6716 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6717 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436718 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336719 mock_quic_data.AddRead(
6720 ASYNC, ConstructServerDataPacket(
6721 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416722 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436723 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206724 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6725 mock_quic_data.AddRead(ASYNC, 0); // EOF
6726
6727 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6728
6729 AddHangingNonAlternateProtocolSocketData();
6730 CreateSession();
6731
6732 SendRequestAndExpectHttpResponse("hello world");
6733 SendRequestAndExpectQuicResponse("hello!");
6734}
6735
6736TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6737 session_params_.quic_host_whitelist.insert("mail.example.com");
6738
6739 MockRead http_reads[] = {
6740 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6741 MockRead("hello world"),
6742 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6743 MockRead(ASYNC, OK)};
6744
Ryan Sleevib8d7ea02018-05-07 20:01:016745 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206746 socket_factory_.AddSocketDataProvider(&http_data);
6747 AddCertificate(&ssl_data_);
6748 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6749 socket_factory_.AddSocketDataProvider(&http_data);
6750 AddCertificate(&ssl_data_);
6751 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6752
6753 AddHangingNonAlternateProtocolSocketData();
6754 CreateSession();
6755
6756 SendRequestAndExpectHttpResponse("hello world");
6757 SendRequestAndExpectHttpResponse("hello world");
6758}
6759
bnc359ed2a2016-04-29 20:43:456760class QuicNetworkTransactionWithDestinationTest
6761 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016762 public ::testing::WithParamInterface<PoolingTestParams>,
6763 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456764 protected:
6765 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556766 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056767 client_headers_include_h2_stream_dependency_(
6768 GetParam().client_headers_include_h2_stream_dependency),
Nick Harper23290b82019-05-02 00:02:566769 supported_versions_(quic::test::SupportedVersions(version_)),
bnc359ed2a2016-04-29 20:43:456770 destination_type_(GetParam().destination_type),
6771 cert_transparency_verifier_(new MultiLogCTVerifier()),
6772 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596773 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116774 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456775 random_generator_(0),
6776 ssl_data_(ASYNC, OK) {}
6777
6778 void SetUp() override {
6779 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556780 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456781
mmenke6ddfbea2017-05-31 21:48:416782 HttpNetworkSession::Params session_params;
6783 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346784 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446785 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056786 session_params.quic_headers_include_h2_stream_dependency =
6787 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416788
6789 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456790
Ryan Hamilton8d9ee76e2018-05-29 23:52:526791 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416792 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456793
6794 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276795 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416796 session_context.quic_crypto_client_stream_factory =
6797 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456798
mmenke6ddfbea2017-05-31 21:48:416799 session_context.quic_random = &random_generator_;
6800 session_context.client_socket_factory = &socket_factory_;
6801 session_context.host_resolver = &host_resolver_;
6802 session_context.cert_verifier = &cert_verifier_;
6803 session_context.transport_security_state = &transport_security_state_;
6804 session_context.cert_transparency_verifier =
6805 cert_transparency_verifier_.get();
6806 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6807 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456808 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416809 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596810 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416811 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6812 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456813
mmenke6ddfbea2017-05-31 21:48:416814 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456815 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456816 }
6817
6818 void TearDown() override {
6819 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6820 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556821 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456822 PlatformTest::TearDown();
6823 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556824 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406825 session_.reset();
bnc359ed2a2016-04-29 20:43:456826 }
6827
zhongyie537a002017-06-27 16:48:216828 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456829 HostPortPair destination;
6830 switch (destination_type_) {
6831 case SAME_AS_FIRST:
6832 destination = HostPortPair(origin1_, 443);
6833 break;
6834 case SAME_AS_SECOND:
6835 destination = HostPortPair(origin2_, 443);
6836 break;
6837 case DIFFERENT:
6838 destination = HostPortPair(kDifferentHostname, 443);
6839 break;
6840 }
bnc3472afd2016-11-17 15:27:216841 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456842 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216843 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456844 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446845 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456846 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526847 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236848 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526849 quic::QuicStreamId stream_id,
6850 bool should_include_version,
6851 quic::QuicStreamOffset* offset,
6852 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486853 return ConstructClientRequestHeadersPacket(
6854 packet_number, stream_id, should_include_version, 0, offset, maker);
6855 }
bnc359ed2a2016-04-29 20:43:456856
Ryan Hamilton8d9ee76e2018-05-29 23:52:526857 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236858 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526859 quic::QuicStreamId stream_id,
6860 bool should_include_version,
6861 quic::QuicStreamId parent_stream_id,
6862 quic::QuicStreamOffset* offset,
6863 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136864 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456865 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136866 spdy::SpdyHeaderBlock headers(
6867 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456868 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6869 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486870 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456871 }
6872
Ryan Hamilton8d9ee76e2018-05-29 23:52:526873 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236874 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526875 quic::QuicStreamId stream_id,
6876 bool should_include_version,
6877 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586878 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456879 packet_number, stream_id, should_include_version, nullptr, maker);
6880 }
6881
Ryan Hamilton8d9ee76e2018-05-29 23:52:526882 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236883 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526884 quic::QuicStreamId stream_id,
6885 quic::QuicStreamOffset* offset,
6886 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136887 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456888 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266889 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456890 }
6891
Ryan Hamilton8d9ee76e2018-05-29 23:52:526892 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236893 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526894 quic::QuicStreamId stream_id,
6895 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586896 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6897 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456898 }
6899
Ryan Hamilton8d9ee76e2018-05-29 23:52:526900 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236901 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526902 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456903 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436904 std::string header = "";
Nick Harper23290b82019-05-02 00:02:566905 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:416906 quic::HttpEncoder encoder;
6907 std::unique_ptr<char[]> buffer;
6908 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436909 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416910 }
bnc359ed2a2016-04-29 20:43:456911 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416912 header + "hello");
bnc359ed2a2016-04-29 20:43:456913 }
6914
Ryan Hamilton8d9ee76e2018-05-29 23:52:526915 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236916 uint64_t packet_number,
6917 uint64_t largest_received,
6918 uint64_t smallest_received,
6919 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456920 QuicTestPacketMaker* maker) {
6921 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496922 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456923 }
6924
Ryan Hamilton8d9ee76e2018-05-29 23:52:526925 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236926 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526927 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376928 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366929 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376930 }
6931
bnc359ed2a2016-04-29 20:43:456932 void AddRefusedSocketData() {
6933 std::unique_ptr<StaticSocketDataProvider> refused_data(
6934 new StaticSocketDataProvider());
6935 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6936 refused_data->set_connect_data(refused_connect);
6937 socket_factory_.AddSocketDataProvider(refused_data.get());
6938 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6939 }
6940
6941 void AddHangingSocketData() {
6942 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6943 new StaticSocketDataProvider());
6944 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6945 hanging_data->set_connect_data(hanging_connect);
6946 socket_factory_.AddSocketDataProvider(hanging_data.get());
6947 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6948 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6949 }
6950
6951 bool AllDataConsumed() {
6952 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6953 if (!socket_data_ptr->AllReadDataConsumed() ||
6954 !socket_data_ptr->AllWriteDataConsumed()) {
6955 return false;
6956 }
6957 }
6958 return true;
6959 }
6960
6961 void SendRequestAndExpectQuicResponse(const std::string& host) {
6962 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6963 HttpRequestInfo request;
6964 std::string url("https://");
6965 url.append(host);
6966 request.url = GURL(url);
6967 request.load_flags = 0;
6968 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106969 request.traffic_annotation =
6970 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456971 TestCompletionCallback callback;
6972 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016973 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456974
6975 std::string response_data;
robpercival214763f2016-07-01 23:27:016976 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456977 EXPECT_EQ("hello", response_data);
6978
6979 const HttpResponseInfo* response = trans.GetResponseInfo();
6980 ASSERT_TRUE(response != nullptr);
6981 ASSERT_TRUE(response->headers.get() != nullptr);
6982 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6983 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526984 EXPECT_TRUE(response->was_alpn_negotiated);
Nick Harper23290b82019-05-02 00:02:566985 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(
6986 version_.transport_version),
bnc359ed2a2016-04-29 20:43:456987 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376988 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456989 }
6990
Fan Yang32c5a112018-12-10 20:06:336991 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:566992 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
6993 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:366994 }
6995
Ryan Hamilton8d9ee76e2018-05-29 23:52:526996 quic::MockClock clock_;
Nick Harper23290b82019-05-02 00:02:566997 const quic::ParsedQuicVersion version_;
Yixin Wang079ad542018-01-11 04:06:056998 const bool client_headers_include_h2_stream_dependency_;
Nick Harper23290b82019-05-02 00:02:566999 quic::ParsedQuicVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457000 DestinationType destination_type_;
7001 std::string origin1_;
7002 std::string origin2_;
7003 std::unique_ptr<HttpNetworkSession> session_;
7004 MockClientSocketFactory socket_factory_;
7005 MockHostResolver host_resolver_;
7006 MockCertVerifier cert_verifier_;
7007 TransportSecurityState transport_security_state_;
7008 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237009 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457010 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077011 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597012 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457013 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527014 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457015 HttpServerPropertiesImpl http_server_properties_;
7016 BoundTestNetLog net_log_;
7017 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7018 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7019 static_socket_data_provider_vector_;
7020 SSLSocketDataProvider ssl_data_;
7021};
7022
Victor Costane635086f2019-01-27 05:20:307023INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7024 QuicNetworkTransactionWithDestinationTest,
7025 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457026
7027// A single QUIC request fails because the certificate does not match the origin
7028// hostname, regardless of whether it matches the alternative service hostname.
7029TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7030 if (destination_type_ == DIFFERENT)
7031 return;
7032
7033 GURL url("https://mail.example.com/");
7034 origin1_ = url.host();
7035
7036 // Not used for requests, but this provides a test case where the certificate
7037 // is valid for the hostname of the alternative service.
7038 origin2_ = "mail.example.org";
7039
zhongyie537a002017-06-27 16:48:217040 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457041
7042 scoped_refptr<X509Certificate> cert(
7043 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247044 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7045 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457046
7047 ProofVerifyDetailsChromium verify_details;
7048 verify_details.cert_verify_result.verified_cert = cert;
7049 verify_details.cert_verify_result.is_issued_by_known_root = true;
7050 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7051
7052 MockQuicData mock_quic_data;
7053 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7054 mock_quic_data.AddRead(ASYNC, 0);
7055
7056 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7057
7058 AddRefusedSocketData();
7059
7060 HttpRequestInfo request;
7061 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107062 request.traffic_annotation =
7063 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457064
7065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7066 TestCompletionCallback callback;
7067 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017068 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457069
7070 EXPECT_TRUE(AllDataConsumed());
7071}
7072
7073// First request opens QUIC session to alternative service. Second request
7074// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527075// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457076TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7077 origin1_ = "mail.example.org";
7078 origin2_ = "news.example.org";
7079
zhongyie537a002017-06-27 16:48:217080 SetQuicAlternativeService(origin1_);
7081 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457082
7083 scoped_refptr<X509Certificate> cert(
7084 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247085 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7086 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7087 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457088
7089 ProofVerifyDetailsChromium verify_details;
7090 verify_details.cert_verify_result.verified_cert = cert;
7091 verify_details.cert_verify_result.is_issued_by_known_root = true;
7092 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7093
Yixin Wang079ad542018-01-11 04:06:057094 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177095 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7096 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057097 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177098 QuicTestPacketMaker server_maker(
7099 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7100 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457101
Ryan Hamilton8d9ee76e2018-05-29 23:52:527102 quic::QuicStreamOffset request_header_offset(0);
7103 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457104
7105 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057106 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437107 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057108 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337109 mock_quic_data.AddWrite(
7110 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7111 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7112 &request_header_offset, &client_maker));
7113 mock_quic_data.AddRead(ASYNC,
7114 ConstructServerResponseHeadersPacket(
7115 1, GetNthClientInitiatedBidirectionalStreamId(0),
7116 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437117 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337118 ASYNC,
7119 ConstructServerDataPacket(
7120 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437121 mock_quic_data.AddWrite(SYNCHRONOUS,
7122 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457123
Yixin Wang079ad542018-01-11 04:06:057124 client_maker.set_hostname(origin2_);
7125 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457126
Zhongyi Shi32f2fd02018-04-16 18:23:437127 mock_quic_data.AddWrite(
7128 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337129 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7130 GetNthClientInitiatedBidirectionalStreamId(0),
7131 &request_header_offset, &client_maker));
7132 mock_quic_data.AddRead(ASYNC,
7133 ConstructServerResponseHeadersPacket(
7134 3, GetNthClientInitiatedBidirectionalStreamId(1),
7135 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437136 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337137 ASYNC,
7138 ConstructServerDataPacket(
7139 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437140 mock_quic_data.AddWrite(SYNCHRONOUS,
7141 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457142 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7143 mock_quic_data.AddRead(ASYNC, 0); // EOF
7144
7145 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7146
7147 AddHangingSocketData();
7148 AddHangingSocketData();
7149
Nick Harpereb483e12019-05-14 00:18:097150 scoped_refptr<TestTaskRunner> quic_task_runner(new TestTaskRunner(&clock_));
Fan Yangc9e00dc2018-10-09 14:17:567151 QuicStreamFactoryPeer::SetAlarmFactory(
7152 session_->quic_stream_factory(),
Nick Harpereb483e12019-05-14 00:18:097153 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner.get(),
Fan Yangc9e00dc2018-10-09 14:17:567154 &clock_));
7155
bnc359ed2a2016-04-29 20:43:457156 SendRequestAndExpectQuicResponse(origin1_);
7157 SendRequestAndExpectQuicResponse(origin2_);
7158
7159 EXPECT_TRUE(AllDataConsumed());
7160}
7161
7162// First request opens QUIC session to alternative service. Second request does
7163// not pool to it, even though destination matches, because certificate is not
7164// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527165// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457166TEST_P(QuicNetworkTransactionWithDestinationTest,
7167 DoNotPoolIfCertificateInvalid) {
7168 origin1_ = "news.example.org";
7169 origin2_ = "mail.example.com";
7170
zhongyie537a002017-06-27 16:48:217171 SetQuicAlternativeService(origin1_);
7172 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457173
7174 scoped_refptr<X509Certificate> cert1(
7175 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247176 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7177 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7178 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457179
7180 scoped_refptr<X509Certificate> cert2(
7181 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247182 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7183 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457184
7185 ProofVerifyDetailsChromium verify_details1;
7186 verify_details1.cert_verify_result.verified_cert = cert1;
7187 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7188 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7189
7190 ProofVerifyDetailsChromium verify_details2;
7191 verify_details2.cert_verify_result.verified_cert = cert2;
7192 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7193 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7194
Yixin Wang079ad542018-01-11 04:06:057195 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177196 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7197 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057198 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177199 QuicTestPacketMaker server_maker1(
7200 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7201 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457202
7203 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527204 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457205 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437206 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7207 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337208 mock_quic_data1.AddWrite(
7209 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7210 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7211 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437212 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337213 ASYNC,
7214 ConstructServerResponseHeadersPacket(
7215 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437216 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337217 ASYNC,
7218 ConstructServerDataPacket(
7219 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437220 mock_quic_data1.AddWrite(
7221 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457222 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7223 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7224
7225 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7226
Yixin Wang079ad542018-01-11 04:06:057227 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177228 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7229 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057230 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177231 QuicTestPacketMaker server_maker2(
7232 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7233 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457234
7235 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527236 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457237 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437238 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7239 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337240 mock_quic_data2.AddWrite(
7241 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7242 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7243 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437244 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337245 ASYNC,
7246 ConstructServerResponseHeadersPacket(
7247 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437248 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337249 ASYNC,
7250 ConstructServerDataPacket(
7251 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437252 mock_quic_data2.AddWrite(
7253 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457254 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7255 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7256
7257 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7258
bnc359ed2a2016-04-29 20:43:457259 SendRequestAndExpectQuicResponse(origin1_);
7260 SendRequestAndExpectQuicResponse(origin2_);
7261
7262 EXPECT_TRUE(AllDataConsumed());
7263}
7264
ckrasicdee37572017-04-06 22:42:277265// crbug.com/705109 - this confirms that matching request with a body
7266// triggers a crash (pre-fix).
7267TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417268 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277269 HostPortPair::FromString("mail.example.org:443"));
7270
7271 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527272 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237273 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437274 mock_quic_data.AddWrite(
7275 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7276 &header_stream_offset));
7277 mock_quic_data.AddWrite(
7278 SYNCHRONOUS,
7279 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337280 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7281 true, true, GetRequestHeaders("GET", "https", "/"),
7282 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527283 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437284 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337285 ASYNC, ConstructServerPushPromisePacket(
7286 1, GetNthClientInitiatedBidirectionalStreamId(0),
7287 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7288 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7289 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577290 if (client_headers_include_h2_stream_dependency_ &&
Nick Harper23290b82019-05-02 00:02:567291 version_.transport_version >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337292 mock_quic_data.AddWrite(SYNCHRONOUS,
7293 ConstructClientPriorityPacket(
7294 client_packet_number++, false,
7295 GetNthServerInitiatedUnidirectionalStreamId(0),
7296 GetNthClientInitiatedBidirectionalStreamId(0),
7297 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577298 }
Zhongyi Shi32f2fd02018-04-16 18:23:437299 mock_quic_data.AddRead(
7300 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337301 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437302 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577303 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437304 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7305 mock_quic_data.AddRead(
7306 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337307 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7308 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437309 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437310 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337311 ASYNC, ConstructServerDataPacket(
7312 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417313 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577314 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437315 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417316
Victor Vasiliev076657c2019-03-12 02:46:437317 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437318 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337319 ASYNC, ConstructServerDataPacket(
7320 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417321 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277322
7323 // Because the matching request has a body, we will see the push
7324 // stream get cancelled, and the matching request go out on the
7325 // wire.
Fan Yang32c5a112018-12-10 20:06:337326 mock_quic_data.AddWrite(SYNCHRONOUS,
7327 ConstructClientAckAndRstPacket(
7328 client_packet_number++,
7329 GetNthServerInitiatedUnidirectionalStreamId(0),
7330 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277331 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437332 std::string header3 = ConstructDataHeader(1);
Nick Harper23290b82019-05-02 00:02:567333 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417334 mock_quic_data.AddWrite(
7335 SYNCHRONOUS,
7336 ConstructClientRequestHeadersAndDataFramesPacket(
7337 client_packet_number++,
7338 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7339 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7340 GetNthServerInitiatedUnidirectionalStreamId(0),
7341 &header_stream_offset, nullptr, {kBody}));
7342 } else {
7343 mock_quic_data.AddWrite(
7344 SYNCHRONOUS,
7345 ConstructClientRequestHeadersAndDataFramesPacket(
7346 client_packet_number++,
7347 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7348 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7349 GetNthServerInitiatedUnidirectionalStreamId(0),
7350 &header_stream_offset, nullptr, {header3, kBody}));
7351 }
ckrasicdee37572017-04-06 22:42:277352
7353 // We see the same response as for the earlier pushed and cancelled
7354 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437355 mock_quic_data.AddRead(
7356 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337357 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437358 GetResponseHeaders("200 OK"), &server_header_offset));
7359 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337360 ASYNC, ConstructServerDataPacket(
7361 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417362 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277363
Yixin Wangb470bc882018-02-15 18:43:577364 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437365 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277366 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7367 mock_quic_data.AddRead(ASYNC, 0); // EOF
7368 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7369
7370 // The non-alternate protocol job needs to hang in order to guarantee that
7371 // the alternate-protocol job will "win".
7372 AddHangingNonAlternateProtocolSocketData();
7373
7374 CreateSession();
7375
7376 // PUSH_PROMISE handling in the http layer gets exercised here.
7377 SendRequestAndExpectQuicResponse("hello!");
7378
7379 request_.url = GURL("https://mail.example.org/pushed.jpg");
7380 ChunkedUploadDataStream upload_data(0);
7381 upload_data.AppendData("1", 1, true);
7382 request_.upload_data_stream = &upload_data;
7383 SendRequestAndExpectQuicResponse("and hello!");
7384}
7385
Bence Béky7538a952018-02-01 16:59:527386// Regression test for https://crbug.com/797825: If pushed headers describe a
7387// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7388// not be called (otherwise a DCHECK fails).
7389TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137390 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527391 pushed_request_headers[":authority"] = "";
7392 pushed_request_headers[":method"] = "GET";
7393 pushed_request_headers[":path"] = "/";
7394 pushed_request_headers[":scheme"] = "nosuchscheme";
7395
7396 session_params_.origins_to_force_quic_on.insert(
7397 HostPortPair::FromString("mail.example.org:443"));
7398
7399 MockQuicData mock_quic_data;
7400
Ryan Hamilton8d9ee76e2018-05-29 23:52:527401 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527402 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437403 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7404 mock_quic_data.AddWrite(
7405 SYNCHRONOUS,
7406 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337407 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437408 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527409
Ryan Hamilton8d9ee76e2018-05-29 23:52:527410 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337411 mock_quic_data.AddRead(
7412 ASYNC, ConstructServerPushPromisePacket(
7413 1, GetNthClientInitiatedBidirectionalStreamId(0),
7414 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7415 std::move(pushed_request_headers), &server_header_offset,
7416 &server_maker_));
7417 mock_quic_data.AddWrite(SYNCHRONOUS,
7418 ConstructClientRstPacket(
7419 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7420 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527421
Zhongyi Shi32f2fd02018-04-16 18:23:437422 mock_quic_data.AddRead(
7423 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337424 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437425 GetResponseHeaders("200 OK"), &server_header_offset));
7426 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527427
Zhongyi Shi32f2fd02018-04-16 18:23:437428 mock_quic_data.AddRead(
7429 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337430 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7431 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437432 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437433 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337434 ASYNC, ConstructServerDataPacket(
7435 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417436 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437437 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527438
7439 mock_quic_data.AddRead(ASYNC, 0);
7440 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7441
7442 // The non-alternate protocol job needs to hang in order to guarantee that
7443 // the alternate-protocol job will "win".
7444 AddHangingNonAlternateProtocolSocketData();
7445
7446 CreateSession();
7447
7448 // PUSH_PROMISE handling in the http layer gets exercised here.
7449 SendRequestAndExpectQuicResponse("hello!");
7450
7451 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7452 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7453}
7454
Yixin Wang46a273ec302018-01-23 17:59:567455// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147456TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567457 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147458 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567459 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497460 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567461
7462 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527463 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567464 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357465 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337466 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357467 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7468 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047469 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7470 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357471 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337472 mock_quic_data.AddRead(
7473 ASYNC, ConstructServerResponseHeadersPacket(
7474 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7475 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567476
7477 const char get_request[] =
7478 "GET / HTTP/1.1\r\n"
7479 "Host: mail.example.org\r\n"
7480 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437481 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567482 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417483 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357484 SYNCHRONOUS,
7485 ConstructClientAckAndDataPacket(
7486 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7487 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417488 } else {
7489 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417490 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357491 ConstructClientAckAndMultipleDataFramesPacket(
7492 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437493 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417494 }
7495
Yixin Wang46a273ec302018-01-23 17:59:567496 const char get_response[] =
7497 "HTTP/1.1 200 OK\r\n"
7498 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437499 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437500 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337501 ASYNC, ConstructServerDataPacket(
7502 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437503 0, header2 + std::string(get_response)));
7504 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337505 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417506 SYNCHRONOUS, ConstructServerDataPacket(
7507 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7508 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437509 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357510 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567511 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7512
7513 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417514 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357515 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7516 quic::QUIC_STREAM_CANCELLED,
7517 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567518
7519 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7520
7521 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7522
7523 CreateSession();
7524
7525 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097526 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567527 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7528 HeadersHandler headers_handler;
7529 trans.SetBeforeHeadersSentCallback(
7530 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7531 base::Unretained(&headers_handler)));
7532 RunTransaction(&trans);
7533 CheckWasHttpResponse(&trans);
7534 CheckResponsePort(&trans, 70);
7535 CheckResponseData(&trans, "0123456789");
7536 EXPECT_TRUE(headers_handler.was_proxied());
7537 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7538
7539 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7540 // proxy socket to disconnect.
7541 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7542
7543 base::RunLoop().RunUntilIdle();
7544 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7545 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7546}
7547
7548// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147549TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567550 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147551 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567552 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497553 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567554
7555 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527556 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567557 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357558 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337559 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357560 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7561 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047562 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7563 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357564 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337565 mock_quic_data.AddRead(
7566 ASYNC, ConstructServerResponseHeadersPacket(
7567 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7568 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567569
7570 SpdyTestUtil spdy_util;
7571
Ryan Hamilton0239aac2018-05-19 00:03:137572 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567573 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437574 std::string header = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567575 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417576 mock_quic_data.AddWrite(
7577 SYNCHRONOUS,
7578 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357579 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7580 false, 0,
Renjief49758b2019-01-11 23:32:417581 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7582 } else {
7583 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417584 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357585 ConstructClientAckAndMultipleDataFramesPacket(
7586 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7587 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437588 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417589 }
Ryan Hamilton0239aac2018-05-19 00:03:137590 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567591 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437592 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437593 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337594 ASYNC,
7595 ConstructServerDataPacket(
7596 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437597 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567598
Ryan Hamilton0239aac2018-05-19 00:03:137599 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197600 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437601 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437602 mock_quic_data.AddRead(
7603 SYNCHRONOUS,
7604 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337605 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417606 resp_frame.size() + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437607 header3 + std::string(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357608 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567609 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7610
7611 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437612 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357613 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7614 quic::QUIC_STREAM_CANCELLED,
7615 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567616
7617 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7618
7619 SSLSocketDataProvider ssl_data(ASYNC, OK);
7620 ssl_data.next_proto = kProtoHTTP2;
7621 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7622
7623 CreateSession();
7624
7625 request_.url = GURL("https://mail.example.org/");
7626 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7627 HeadersHandler headers_handler;
7628 trans.SetBeforeHeadersSentCallback(
7629 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7630 base::Unretained(&headers_handler)));
7631 RunTransaction(&trans);
7632 CheckWasSpdyResponse(&trans);
7633 CheckResponsePort(&trans, 70);
7634 CheckResponseData(&trans, "0123456789");
7635 EXPECT_TRUE(headers_handler.was_proxied());
7636 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7637
Wez0e717112018-06-18 23:09:227638 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7639 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567640 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7641
7642 base::RunLoop().RunUntilIdle();
7643 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7644 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7645}
7646
7647// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7648// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147649TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567650 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147651 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567652 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497653 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567654
7655 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527656 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417657 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567658 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417659 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7660 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337661 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417662 SYNCHRONOUS,
7663 ConstructClientRequestHeadersPacket(
7664 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
Matt Menke6e879bd2019-03-18 17:26:047665 true, false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7666 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjief49758b2019-01-11 23:32:417667 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337668 mock_quic_data.AddRead(
7669 ASYNC, ConstructServerResponseHeadersPacket(
7670 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7671 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567672
Ryan Hamilton8d9ee76e2018-05-29 23:52:527673 quic::QuicStreamOffset client_data_offset = 0;
7674 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567675 const char get_request_1[] =
7676 "GET / HTTP/1.1\r\n"
7677 "Host: mail.example.org\r\n"
7678 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437679 std::string header = ConstructDataHeader(strlen(get_request_1));
Nick Harper23290b82019-05-02 00:02:567680 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417681 mock_quic_data.AddWrite(
7682 SYNCHRONOUS,
7683 ConstructClientAckAndDataPacket(
7684 write_packet_index++, false,
7685 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7686 client_data_offset, quic::QuicStringPiece(get_request_1)));
7687 } else {
7688 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417689 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357690 ConstructClientAckAndMultipleDataFramesPacket(
7691 write_packet_index++, false,
7692 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
Victor Vasiliev076657c2019-03-12 02:46:437693 client_data_offset, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417694 }
7695
7696 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567697
7698 const char get_response_1[] =
7699 "HTTP/1.1 200 OK\r\n"
7700 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437701 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437702 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437703 ASYNC, ConstructServerDataPacket(
7704 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7705 server_data_offset, header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417706 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567707
Victor Vasiliev076657c2019-03-12 02:46:437708 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337709 mock_quic_data.AddRead(
7710 SYNCHRONOUS,
7711 ConstructServerDataPacket(
7712 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437713 server_data_offset, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417714 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567715
Renjief49758b2019-01-11 23:32:417716 mock_quic_data.AddWrite(
7717 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567718
7719 const char get_request_2[] =
7720 "GET /2 HTTP/1.1\r\n"
7721 "Host: mail.example.org\r\n"
7722 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437723 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Nick Harper23290b82019-05-02 00:02:567724 if (version_.transport_version == quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417725 mock_quic_data.AddWrite(
7726 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357727 ConstructClientMultipleDataFramesPacket(
7728 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7729 false, false, client_data_offset,
Victor Vasiliev076657c2019-03-12 02:46:437730 {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357731 client_data_offset += header4.length() + strlen(get_request_2);
7732 } else {
7733 mock_quic_data.AddWrite(
7734 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417735 ConstructClientDataPacket(write_packet_index++,
7736 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357737 false, false, client_data_offset,
7738 quic::QuicStringPiece(get_request_2)));
7739 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417740 }
Yixin Wang46a273ec302018-01-23 17:59:567741
7742 const char get_response_2[] =
7743 "HTTP/1.1 200 OK\r\n"
7744 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437745 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437746 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437747 ASYNC, ConstructServerDataPacket(
7748 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7749 server_data_offset, header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417750 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567751
Victor Vasiliev076657c2019-03-12 02:46:437752 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527753 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337754 SYNCHRONOUS,
7755 ConstructServerDataPacket(
7756 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437757 server_data_offset, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417758 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567759
Renjief49758b2019-01-11 23:32:417760 mock_quic_data.AddWrite(
7761 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567762 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7763
Renjief49758b2019-01-11 23:32:417764 mock_quic_data.AddWrite(
7765 SYNCHRONOUS,
7766 ConstructClientRstPacket(
7767 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7768 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567769
7770 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7771
7772 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7773
7774 CreateSession();
7775
7776 request_.url = GURL("https://mail.example.org/");
7777 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7778 HeadersHandler headers_handler_1;
7779 trans_1.SetBeforeHeadersSentCallback(
7780 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7781 base::Unretained(&headers_handler_1)));
7782 RunTransaction(&trans_1);
7783 CheckWasHttpResponse(&trans_1);
7784 CheckResponsePort(&trans_1, 70);
7785 CheckResponseData(&trans_1, "0123456789");
7786 EXPECT_TRUE(headers_handler_1.was_proxied());
7787 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7788
7789 request_.url = GURL("https://mail.example.org/2");
7790 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7791 HeadersHandler headers_handler_2;
7792 trans_2.SetBeforeHeadersSentCallback(
7793 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7794 base::Unretained(&headers_handler_2)));
7795 RunTransaction(&trans_2);
7796 CheckWasHttpResponse(&trans_2);
7797 CheckResponsePort(&trans_2, 70);
7798 CheckResponseData(&trans_2, "0123456");
7799 EXPECT_TRUE(headers_handler_2.was_proxied());
7800 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7801
7802 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7803 // proxy socket to disconnect.
7804 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7805
7806 base::RunLoop().RunUntilIdle();
7807 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7808 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7809}
7810
7811// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7812// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7813// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147814TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567815 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147816 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567817 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497818 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567819
7820 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527821 quic::QuicStreamOffset client_header_stream_offset = 0;
7822 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357823 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7824 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567825
7826 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337827 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357828 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7829 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047830 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7831 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:357832 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437833 mock_quic_data.AddRead(
7834 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337835 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437836 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567837
7838 // GET request, response, and data over QUIC tunnel for first request
7839 const char get_request[] =
7840 "GET / HTTP/1.1\r\n"
7841 "Host: mail.example.org\r\n"
7842 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437843 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:567844 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417845 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357846 SYNCHRONOUS,
7847 ConstructClientAckAndDataPacket(
7848 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7849 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417850 } else {
7851 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417852 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357853 ConstructClientAckAndMultipleDataFramesPacket(
7854 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437855 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417856 }
7857
Yixin Wang46a273ec302018-01-23 17:59:567858 const char get_response[] =
7859 "HTTP/1.1 200 OK\r\n"
7860 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437861 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567862 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337863 ASYNC, ConstructServerDataPacket(
7864 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437865 0, header2 + std::string(get_response)));
7866 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337867 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417868 SYNCHRONOUS, ConstructServerDataPacket(
7869 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7870 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437871 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357872 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567873
7874 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437875 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:047876 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7877 5, GetNthClientInitiatedBidirectionalStreamId(1), false,
7878 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
7879 ConnectRequestHeaders("different.example.org:443"),
7880 GetNthClientInitiatedBidirectionalStreamId(0),
7881 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437882 mock_quic_data.AddRead(
7883 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337884 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437885 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567886
7887 // GET request, response, and data over QUIC tunnel for second request
7888 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137889 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567890 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437891 std::string header4 = ConstructDataHeader(get_frame.size());
Nick Harper23290b82019-05-02 00:02:567892 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:417893 mock_quic_data.AddWrite(
7894 SYNCHRONOUS,
7895 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357896 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7897 false, 0,
Renjief49758b2019-01-11 23:32:417898 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7899 } else {
7900 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417901 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357902 ConstructClientAckAndMultipleDataFramesPacket(
7903 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7904 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437905 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417906 }
Yixin Wang46a273ec302018-01-23 17:59:567907
Ryan Hamilton0239aac2018-05-19 00:03:137908 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567909 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437910 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437911 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337912 ASYNC,
7913 ConstructServerDataPacket(
7914 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437915 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567916
Ryan Hamilton0239aac2018-05-19 00:03:137917 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197918 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437919 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437920 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437921 ASYNC, ConstructServerDataPacket(
7922 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7923 resp_frame.size() + header5.length(),
7924 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567925
Renjied172e812019-01-16 05:12:357926 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567927 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7928
7929 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417930 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357931 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7932 quic::QUIC_STREAM_CANCELLED,
7933 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567934 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437935 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357936 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7937 quic::QUIC_STREAM_CANCELLED,
7938 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567939
7940 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7941
7942 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7943
7944 SSLSocketDataProvider ssl_data(ASYNC, OK);
7945 ssl_data.next_proto = kProtoHTTP2;
7946 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7947
7948 CreateSession();
7949
7950 request_.url = GURL("https://mail.example.org/");
7951 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7952 HeadersHandler headers_handler_1;
7953 trans_1.SetBeforeHeadersSentCallback(
7954 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7955 base::Unretained(&headers_handler_1)));
7956 RunTransaction(&trans_1);
7957 CheckWasHttpResponse(&trans_1);
7958 CheckResponsePort(&trans_1, 70);
7959 CheckResponseData(&trans_1, "0123456789");
7960 EXPECT_TRUE(headers_handler_1.was_proxied());
7961 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7962
7963 request_.url = GURL("https://different.example.org/");
7964 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7965 HeadersHandler headers_handler_2;
7966 trans_2.SetBeforeHeadersSentCallback(
7967 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7968 base::Unretained(&headers_handler_2)));
7969 RunTransaction(&trans_2);
7970 CheckWasSpdyResponse(&trans_2);
7971 CheckResponsePort(&trans_2, 70);
7972 CheckResponseData(&trans_2, "0123456");
7973 EXPECT_TRUE(headers_handler_2.was_proxied());
7974 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7975
7976 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7977 // proxy socket to disconnect.
7978 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7979
7980 base::RunLoop().RunUntilIdle();
7981 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7982 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7983}
7984
7985// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147986TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567987 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147988 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567989 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497990 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567991
7992 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527993 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567994 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437995 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527996 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337997 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7998 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:047999 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8000 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338001 &header_stream_offset));
8002 mock_quic_data.AddRead(
8003 ASYNC, ConstructServerResponseHeadersPacket(
8004 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8005 GetResponseHeaders("500")));
8006 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8007 mock_quic_data.AddWrite(SYNCHRONOUS,
8008 ConstructClientAckAndRstPacket(
8009 3, GetNthClientInitiatedBidirectionalStreamId(0),
8010 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568011
8012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8013
8014 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8015
8016 CreateSession();
8017
8018 request_.url = GURL("https://mail.example.org/");
8019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8020 HeadersHandler headers_handler;
8021 trans.SetBeforeHeadersSentCallback(
8022 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8023 base::Unretained(&headers_handler)));
8024 TestCompletionCallback callback;
8025 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8026 EXPECT_EQ(ERR_IO_PENDING, rv);
8027 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8028 EXPECT_EQ(false, headers_handler.was_proxied());
8029
8030 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8031 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8032}
8033
8034// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148035TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568036 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148037 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568038 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498039 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568040
8041 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528042 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568043 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438044 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338045 mock_quic_data.AddWrite(
8046 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8047 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048048 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8049 ConnectRequestHeaders("mail.example.org:443"), 0,
Fan Yang32c5a112018-12-10 20:06:338050 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568051 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8052
8053 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8054
8055 CreateSession();
8056
8057 request_.url = GURL("https://mail.example.org/");
8058 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8059 HeadersHandler headers_handler;
8060 trans.SetBeforeHeadersSentCallback(
8061 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8062 base::Unretained(&headers_handler)));
8063 TestCompletionCallback callback;
8064 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8065 EXPECT_EQ(ERR_IO_PENDING, rv);
8066 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8067
8068 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8069 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8070}
8071
8072// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8073// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148074TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568075 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148076 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568077 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498078 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568079
8080 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528081 quic::QuicStreamOffset client_header_stream_offset = 0;
8082 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358083 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8084 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338085 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358086 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8087 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048088 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8089 ConnectRequestHeaders("mail.example.org:443"), 0,
Renjied172e812019-01-16 05:12:358090 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438091 mock_quic_data.AddRead(
8092 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338093 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438094 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358095 mock_quic_data.AddWrite(SYNCHRONOUS,
8096 ConstructClientAckAndRstPacket(
8097 3, GetNthClientInitiatedBidirectionalStreamId(0),
8098 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568099
Zhongyi Shi32f2fd02018-04-16 18:23:438100 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358101 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8102 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
Matt Menke6e879bd2019-03-18 17:26:048103 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8104 ConnectRequestHeaders("mail.example.org:443"),
Renjied172e812019-01-16 05:12:358105 GetNthClientInitiatedBidirectionalStreamId(0),
8106 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438107 mock_quic_data.AddRead(
8108 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338109 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438110 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568111
8112 const char get_request[] =
8113 "GET / HTTP/1.1\r\n"
8114 "Host: mail.example.org\r\n"
8115 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438116 std::string header = ConstructDataHeader(strlen(get_request));
Nick Harper23290b82019-05-02 00:02:568117 if (version_.transport_version != quic::QUIC_VERSION_99) {
Renjief49758b2019-01-11 23:32:418118 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358119 SYNCHRONOUS,
8120 ConstructClientAckAndDataPacket(
8121 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8122 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418123 } else {
8124 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418125 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358126 ConstructClientAckAndMultipleDataFramesPacket(
8127 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Victor Vasiliev076657c2019-03-12 02:46:438128 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418129 }
Yixin Wang46a273ec302018-01-23 17:59:568130 const char get_response[] =
8131 "HTTP/1.1 200 OK\r\n"
8132 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438133 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438134 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338135 ASYNC, ConstructServerDataPacket(
8136 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438137 0, header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528138
Victor Vasiliev076657c2019-03-12 02:46:438139 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338140 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418141 SYNCHRONOUS, ConstructServerDataPacket(
8142 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8143 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:438144 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:358145 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568146 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8147
8148 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418149 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358150 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8151 quic::QUIC_STREAM_CANCELLED,
8152 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568153
8154 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8155
8156 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8157 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8158
8159 SSLSocketDataProvider ssl_data(ASYNC, OK);
8160 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8161
8162 CreateSession();
8163
8164 request_.url = GURL("https://mail.example.org/");
8165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8166 HeadersHandler headers_handler;
8167 trans.SetBeforeHeadersSentCallback(
8168 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8169 base::Unretained(&headers_handler)));
8170 TestCompletionCallback callback;
8171 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8172 EXPECT_EQ(ERR_IO_PENDING, rv);
8173 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8174
8175 rv = trans.RestartIgnoringLastError(callback.callback());
8176 EXPECT_EQ(ERR_IO_PENDING, rv);
8177 EXPECT_EQ(OK, callback.WaitForResult());
8178
8179 CheckWasHttpResponse(&trans);
8180 CheckResponsePort(&trans, 70);
8181 CheckResponseData(&trans, "0123456789");
8182 EXPECT_EQ(true, headers_handler.was_proxied());
8183 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8184
8185 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8186 // proxy socket to disconnect.
8187 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8188
8189 base::RunLoop().RunUntilIdle();
8190 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8191 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8192}
8193
8194// Checks if a request's specified "user-agent" header shows up correctly in the
8195// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148196TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008197 const char kConfiguredUserAgent[] = "Configured User-Agent";
8198 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568199 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148200 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568201 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498202 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568203
8204 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528205 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568206 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438207 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568208
Ryan Hamilton0239aac2018-05-19 00:03:138209 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008210 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338211 mock_quic_data.AddWrite(
8212 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8213 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
Matt Menke6e879bd2019-03-18 17:26:048214 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8215 std::move(headers), 0, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568216 // Return an error, so the transaction stops here (this test isn't interested
8217 // in the rest).
8218 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8219
8220 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8221
Matt Menked732ea42019-03-08 12:05:008222 StaticHttpUserAgentSettings http_user_agent_settings(
8223 std::string() /* accept_language */, kConfiguredUserAgent);
8224 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568225 CreateSession();
8226
8227 request_.url = GURL("https://mail.example.org/");
8228 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008229 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8231 HeadersHandler headers_handler;
8232 trans.SetBeforeHeadersSentCallback(
8233 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8234 base::Unretained(&headers_handler)));
8235 TestCompletionCallback callback;
8236 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8237 EXPECT_EQ(ERR_IO_PENDING, rv);
8238 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8239
8240 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8241 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8242}
8243
Yixin Wang00fc44c2018-01-23 21:12:208244// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8245// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148246TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208247 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148248 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208249 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498250 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208251
8252 const RequestPriority request_priority = MEDIUM;
8253
8254 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528255 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208256 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438257 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8258 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048259 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8260 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8261 false, HttpProxyConnectJob::kH2QuicTunnelPriority,
8262 ConnectRequestHeaders("mail.example.org:443"), 0,
8263 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208264 // Return an error, so the transaction stops here (this test isn't interested
8265 // in the rest).
8266 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8267
8268 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8269
8270 CreateSession();
8271
8272 request_.url = GURL("https://mail.example.org/");
8273 HttpNetworkTransaction trans(request_priority, session_.get());
8274 TestCompletionCallback callback;
8275 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8276 EXPECT_EQ(ERR_IO_PENDING, rv);
8277 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8278
8279 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8280 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8281}
8282
Matt Menkeedaf3b82019-03-14 21:39:448283// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8284// HTTP/2 stream dependency and weights given the request priority.
8285TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8286 session_params_.enable_quic = true;
8287 session_params_.enable_quic_proxies_for_https_urls = true;
8288 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8289 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8290
8291 const RequestPriority kRequestPriority = MEDIUM;
8292 const RequestPriority kRequestPriority2 = LOWEST;
8293
8294 MockQuicData mock_quic_data;
8295 quic::QuicStreamOffset header_stream_offset = 0;
8296 mock_quic_data.AddWrite(
8297 ASYNC, ConstructInitialSettingsPacket(1, &header_stream_offset));
8298 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8299 // This should never be reached.
8300 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8301 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8302
8303 // Second connection attempt just fails - result doesn't really matter.
8304 MockQuicData mock_quic_data2;
8305 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8306 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8307
8308 int original_max_sockets_per_group =
8309 ClientSocketPoolManager::max_sockets_per_group(
8310 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8311 ClientSocketPoolManager::set_max_sockets_per_group(
8312 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8313 int original_max_sockets_per_pool =
8314 ClientSocketPoolManager::max_sockets_per_pool(
8315 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8316 ClientSocketPoolManager::set_max_sockets_per_pool(
8317 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8318 CreateSession();
8319
8320 request_.url = GURL("https://mail.example.org/");
8321 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8322 TestCompletionCallback callback;
8323 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8324 EXPECT_EQ(ERR_IO_PENDING, rv);
8325
8326 HttpRequestInfo request2;
8327 request2.url = GURL("https://mail.example.org/some/other/path/");
8328 request2.traffic_annotation =
8329 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8330
8331 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8332 TestCompletionCallback callback2;
8333 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8334 EXPECT_EQ(ERR_IO_PENDING, rv2);
8335
8336 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8337 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8338
8339 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8340
8341 ClientSocketPoolManager::set_max_sockets_per_pool(
8342 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8343 original_max_sockets_per_pool);
8344 ClientSocketPoolManager::set_max_sockets_per_group(
8345 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8346 original_max_sockets_per_group);
8347}
8348
Yixin Wang46a273ec302018-01-23 17:59:568349// Test the request-challenge-retry sequence for basic auth, over a QUIC
8350// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148351TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568352 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8353 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Yixin Wang46a273ec302018-01-23 17:59:568354
8355 std::unique_ptr<QuicTestPacketMaker> client_maker;
8356 std::unique_ptr<QuicTestPacketMaker> server_maker;
8357
8358 // On the second pass, the body read of the auth challenge is synchronous, so
8359 // IsConnectedAndIdle returns false. The socket should still be drained and
8360 // reused. See http://crbug.com/544255.
8361 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338362 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178363 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8364 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338365 client_headers_include_h2_stream_dependency_));
8366 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178367 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8368 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568369
8370 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148371 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568372 proxy_resolution_service_ =
8373 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498374 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568375
8376 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528377 quic::QuicStreamOffset client_header_stream_offset = 0;
8378 quic::QuicStreamOffset server_header_stream_offset = 0;
8379 quic::QuicStreamOffset client_data_offset = 0;
8380 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568381
Zhongyi Shi32f2fd02018-04-16 18:23:438382 mock_quic_data.AddWrite(SYNCHRONOUS,
8383 client_maker->MakeInitialSettingsPacket(
8384 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568385
8386 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438387 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568388 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338389 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
Matt Menke6e879bd2019-03-18 17:26:048390 ConvertRequestPriorityToQuicPriority(
8391 HttpProxyConnectJob::kH2QuicTunnelPriority),
Yixin Wang46a273ec302018-01-23 17:59:568392 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8393 &client_header_stream_offset));
8394
Ryan Hamilton0239aac2018-05-19 00:03:138395 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568396 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8397 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8398 headers["content-length"] = "10";
8399 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438400 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338401 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8402 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568403
8404 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438405 mock_quic_data.AddRead(
8406 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338407 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8408 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568409 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438410 mock_quic_data.AddRead(
8411 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338412 2, GetNthClientInitiatedBidirectionalStreamId(0),
8413 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568414 }
8415 server_data_offset += 10;
8416
Zhongyi Shi32f2fd02018-04-16 18:23:438417 mock_quic_data.AddWrite(SYNCHRONOUS,
8418 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568419
8420 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338421 SYNCHRONOUS,
8422 client_maker->MakeRstPacket(
8423 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188424 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8425 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568426
8427 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8428 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8429 mock_quic_data.AddWrite(
Matt Menke6e879bd2019-03-18 17:26:048430 SYNCHRONOUS,
8431 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8432 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8433 ConvertRequestPriorityToQuicPriority(
8434 HttpProxyConnectJob::kH2QuicTunnelPriority),
8435 std::move(headers), GetNthClientInitiatedBidirectionalStreamId(0),
8436 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568437
8438 // Response to wrong password
8439 headers =
8440 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8441 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8442 headers["content-length"] = "10";
8443 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438444 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338445 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8446 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568447 mock_quic_data.AddRead(SYNCHRONOUS,
8448 ERR_IO_PENDING); // No more data to read
8449
Fan Yang32c5a112018-12-10 20:06:338450 mock_quic_data.AddWrite(
8451 SYNCHRONOUS,
8452 client_maker->MakeAckAndRstPacket(
8453 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8454 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568455
8456 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8457 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8458
8459 CreateSession();
8460
8461 request_.url = GURL("https://mail.example.org/");
8462 // Ensure that proxy authentication is attempted even
8463 // when the no authentication data flag is set.
8464 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8465 {
8466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8467 HeadersHandler headers_handler;
8468 trans.SetBeforeHeadersSentCallback(
8469 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8470 base::Unretained(&headers_handler)));
8471 RunTransaction(&trans);
8472
8473 const HttpResponseInfo* response = trans.GetResponseInfo();
8474 ASSERT_TRUE(response != nullptr);
8475 ASSERT_TRUE(response->headers.get() != nullptr);
8476 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8477 response->headers->GetStatusLine());
8478 EXPECT_TRUE(response->headers->IsKeepAlive());
8479 EXPECT_EQ(407, response->headers->response_code());
8480 EXPECT_EQ(10, response->headers->GetContentLength());
8481 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588482 base::Optional<AuthChallengeInfo> auth_challenge =
8483 response->auth_challenge;
8484 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568485 EXPECT_TRUE(auth_challenge->is_proxy);
8486 EXPECT_EQ("https://proxy.example.org:70",
8487 auth_challenge->challenger.Serialize());
8488 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8489 EXPECT_EQ("basic", auth_challenge->scheme);
8490
8491 TestCompletionCallback callback;
8492 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8493 callback.callback());
8494 EXPECT_EQ(ERR_IO_PENDING, rv);
8495 EXPECT_EQ(OK, callback.WaitForResult());
8496
8497 response = trans.GetResponseInfo();
8498 ASSERT_TRUE(response != nullptr);
8499 ASSERT_TRUE(response->headers.get() != nullptr);
8500 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8501 response->headers->GetStatusLine());
8502 EXPECT_TRUE(response->headers->IsKeepAlive());
8503 EXPECT_EQ(407, response->headers->response_code());
8504 EXPECT_EQ(10, response->headers->GetContentLength());
8505 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:588506 auth_challenge = response->auth_challenge;
8507 ASSERT_TRUE(auth_challenge.has_value());
Yixin Wang46a273ec302018-01-23 17:59:568508 EXPECT_TRUE(auth_challenge->is_proxy);
8509 EXPECT_EQ("https://proxy.example.org:70",
8510 auth_challenge->challenger.Serialize());
8511 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8512 EXPECT_EQ("basic", auth_challenge->scheme);
8513 }
8514 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8515 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8516 // reused because it's not connected).
8517 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8518 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8519 }
8520}
8521
Yixin Wang385652a2018-02-16 02:37:238522TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8523 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8524 // in HEADERS frames for requests and PRIORITY frames).
Nick Harper23290b82019-05-02 00:02:568525 if (version_.transport_version < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238526 !client_headers_include_h2_stream_dependency_) {
8527 return;
8528 }
8529
8530 session_params_.origins_to_force_quic_on.insert(
8531 HostPortPair::FromString("mail.example.org:443"));
8532
Fan Yang32c5a112018-12-10 20:06:338533 const quic::QuicStreamId client_stream_0 =
8534 GetNthClientInitiatedBidirectionalStreamId(0);
8535 const quic::QuicStreamId client_stream_1 =
8536 GetNthClientInitiatedBidirectionalStreamId(1);
8537 const quic::QuicStreamId client_stream_2 =
8538 GetNthClientInitiatedBidirectionalStreamId(2);
8539 const quic::QuicStreamId push_stream_0 =
8540 GetNthServerInitiatedUnidirectionalStreamId(0);
8541 const quic::QuicStreamId push_stream_1 =
8542 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238543
8544 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528545 quic::QuicStreamOffset header_stream_offset = 0;
8546 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238547 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438548 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238549
8550 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438551 mock_quic_data.AddWrite(SYNCHRONOUS,
8552 ConstructClientRequestHeadersPacket(
8553 2, client_stream_0, true, true, HIGHEST,
8554 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8555 &header_stream_offset));
8556 mock_quic_data.AddWrite(SYNCHRONOUS,
8557 ConstructClientRequestHeadersPacket(
8558 3, client_stream_1, true, true, MEDIUM,
8559 GetRequestHeaders("GET", "https", "/1.jpg"),
8560 client_stream_0, &header_stream_offset));
8561 mock_quic_data.AddWrite(SYNCHRONOUS,
8562 ConstructClientRequestHeadersPacket(
8563 4, client_stream_2, true, true, MEDIUM,
8564 GetRequestHeaders("GET", "https", "/2.jpg"),
8565 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238566
8567 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438568 mock_quic_data.AddRead(
8569 ASYNC, ConstructServerResponseHeadersPacket(
8570 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8571 &server_header_offset));
8572 mock_quic_data.AddRead(
8573 ASYNC, ConstructServerResponseHeadersPacket(
8574 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8575 &server_header_offset));
8576 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8577 mock_quic_data.AddRead(
8578 ASYNC, ConstructServerResponseHeadersPacket(
8579 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8580 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238581
8582 // Server sends two push promises associated with |client_stream_0|; client
8583 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8584 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438585 mock_quic_data.AddRead(ASYNC,
8586 ConstructServerPushPromisePacket(
8587 4, client_stream_0, push_stream_0, false,
8588 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8589 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238590 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438591 SYNCHRONOUS,
8592 ConstructClientAckAndPriorityFramesPacket(
8593 6, false, 4, 3, 1,
8594 {{push_stream_0, client_stream_2,
8595 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8596 &header_stream_offset));
8597 mock_quic_data.AddRead(ASYNC,
8598 ConstructServerPushPromisePacket(
8599 5, client_stream_0, push_stream_1, false,
8600 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8601 &server_header_offset, &server_maker_));
8602 mock_quic_data.AddWrite(
8603 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238604 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8605 DEFAULT_PRIORITY, &header_stream_offset));
8606
8607 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438608 mock_quic_data.AddRead(
8609 ASYNC, ConstructServerResponseHeadersPacket(
8610 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8611 &server_header_offset));
8612 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8613 mock_quic_data.AddRead(
8614 ASYNC, ConstructServerResponseHeadersPacket(
8615 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8616 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238617
8618 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8619 // priority updates to match the request's priority. Client sends PRIORITY
8620 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438621 mock_quic_data.AddWrite(
8622 SYNCHRONOUS,
8623 ConstructClientAckAndPriorityFramesPacket(
8624 9, false, 7, 7, 1,
8625 {{push_stream_1, client_stream_2,
8626 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8627 {push_stream_0, client_stream_0,
8628 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8629 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238630
8631 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438632 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438633 mock_quic_data.AddRead(
8634 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418635 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438636 mock_quic_data.AddRead(
8637 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418638 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438639 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8640 mock_quic_data.AddRead(
8641 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418642 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438643 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438644 mock_quic_data.AddRead(
8645 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418646 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438647 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8648 mock_quic_data.AddRead(
8649 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418650 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238651
Yixin Wang385652a2018-02-16 02:37:238652 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8653 mock_quic_data.AddRead(ASYNC, 0); // EOF
8654 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8655
8656 // The non-alternate protocol job needs to hang in order to guarantee that
8657 // the alternate-protocol job will "win".
8658 AddHangingNonAlternateProtocolSocketData();
8659
8660 CreateSession();
8661
8662 request_.url = GURL("https://mail.example.org/0.jpg");
8663 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8664 TestCompletionCallback callback_0;
8665 EXPECT_EQ(ERR_IO_PENDING,
8666 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8667 base::RunLoop().RunUntilIdle();
8668
8669 request_.url = GURL("https://mail.example.org/1.jpg");
8670 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8671 TestCompletionCallback callback_1;
8672 EXPECT_EQ(ERR_IO_PENDING,
8673 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8674 base::RunLoop().RunUntilIdle();
8675
8676 request_.url = GURL("https://mail.example.org/2.jpg");
8677 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8678 TestCompletionCallback callback_2;
8679 EXPECT_EQ(ERR_IO_PENDING,
8680 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8681 base::RunLoop().RunUntilIdle();
8682
8683 // Client makes request that matches resource pushed in |pushed_stream_0|.
8684 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8685 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8686 TestCompletionCallback callback_3;
8687 EXPECT_EQ(ERR_IO_PENDING,
8688 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8689 base::RunLoop().RunUntilIdle();
8690
8691 EXPECT_TRUE(callback_0.have_result());
8692 EXPECT_EQ(OK, callback_0.WaitForResult());
8693 EXPECT_TRUE(callback_1.have_result());
8694 EXPECT_EQ(OK, callback_1.WaitForResult());
8695 EXPECT_TRUE(callback_2.have_result());
8696 EXPECT_EQ(OK, callback_2.WaitForResult());
8697
8698 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8699 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8700 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8701 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8702
8703 mock_quic_data.Resume();
8704 base::RunLoop().RunUntilIdle();
8705 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8706 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8707}
8708
[email protected]61a527782013-02-21 03:58:008709} // namespace test
8710} // namespace net