blob: a9a38c46bd225912c3891345c64545d9b37f9775 [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"
33#include "net/http/http_server_properties_impl.h"
34#include "net/http/http_stream.h"
35#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1936#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1137#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0038#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5139#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4640#include "net/log/test_net_log_entry.h"
41#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0343#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4044#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0845#include "net/quic/crypto/proof_verifier_chromium.h"
46#include "net/quic/mock_crypto_client_stream_factory.h"
47#include "net/quic/mock_quic_data.h"
48#include "net/quic/quic_chromium_alarm_factory.h"
49#include "net/quic/quic_http_stream.h"
50#include "net/quic/quic_http_utils.h"
51#include "net/quic/quic_stream_factory_peer.h"
52#include "net/quic/quic_test_packet_maker.h"
53#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0054#include "net/socket/client_socket_factory.h"
55#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2156#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2857#include "net/socket/socket_performance_watcher.h"
58#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0059#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5860#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5761#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2962#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0163#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4364#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0165#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5166#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
67#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
68#include "net/third_party/quiche/src/quic/core/quic_framer.h"
69#include "net/third_party/quiche/src/quic/core/quic_utils.h"
70#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
71#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
72#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
73#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
74#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
75#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
76#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
77#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1478#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
79#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2980#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:0081#include "net/url_request/static_http_user_agent_settings.h"
allada71b2efb2016-09-09 04:57:4882#include "net/url_request/url_request.h"
83#include "net/url_request/url_request_job_factory_impl.h"
84#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0185#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0086#include "testing/gtest/include/gtest/gtest.h"
87#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4688#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0089
Reilly Grant89a7e512018-01-20 01:57:1690using ::testing::ElementsAre;
91using ::testing::Key;
92
bnc508835902015-05-12 20:10:2993namespace net {
94namespace test {
[email protected]61a527782013-02-21 03:58:0095
96namespace {
97
bnc359ed2a2016-04-29 20:43:4598enum DestinationType {
99 // In pooling tests with two requests for different origins to the same
100 // destination, the destination should be
101 SAME_AS_FIRST, // the same as the first origin,
102 SAME_AS_SECOND, // the same as the second origin, or
103 DIFFERENT, // different from both.
104};
105
rchf114d982015-10-21 01:34:56106static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52107 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12108static const char kQuicAlternativeServiceWithProbabilityHeader[] =
109 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56110static const char kQuicAlternativeServiceDifferentPortHeader[] =
111 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20112
rch9ae5b3b2016-02-11 00:36:29113const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45114const char kDifferentHostname[] = "different.example.com";
115
116// Run QuicNetworkTransactionWithDestinationTest instances with all value
117// combinations of version and destination_type.
118struct PoolingTestParams {
119 friend std::ostream& operator<<(std::ostream& os,
120 const PoolingTestParams& p) {
121 os << "{ version: " << QuicVersionToString(p.version)
122 << ", destination_type: ";
123 switch (p.destination_type) {
124 case SAME_AS_FIRST:
125 os << "SAME_AS_FIRST";
126 break;
127 case SAME_AS_SECOND:
128 os << "SAME_AS_SECOND";
129 break;
130 case DIFFERENT:
131 os << "DIFFERENT";
132 break;
133 }
Yixin Wang079ad542018-01-11 04:06:05134 os << ", client_headers_include_h2_stream_dependency: "
135 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45136 os << " }";
137 return os;
138 }
139
Ryan Hamilton8d9ee76e2018-05-29 23:52:52140 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45141 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05142 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45143};
144
zhongyie537a002017-06-27 16:48:21145std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52146 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21147 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52148 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21149 if (!result.empty())
150 result.append(",");
Raul Tambre8c1981dd2019-02-08 02:22:26151 result.append(base::NumberToString(version));
zhongyie537a002017-06-27 16:48:21152 }
153 return result;
154}
155
bnc359ed2a2016-04-29 20:43:45156std::vector<PoolingTestParams> GetPoolingTestParams() {
157 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52158 quic::QuicTransportVersionVector all_supported_versions =
159 quic::AllSupportedTransportVersions();
160 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05161 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
162 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
163 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
164 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
165 params.push_back(PoolingTestParams{version, DIFFERENT, false});
166 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45167 }
168 return params;
169}
bncb07c05532015-05-14 19:07:20170
[email protected]61a527782013-02-21 03:58:00171} // namespace
172
ryansturm49a8cb12016-06-15 16:51:09173class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12174 public:
ryansturm49a8cb12016-06-15 16:51:09175 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12176
ryansturm49a8cb12016-06-15 16:51:09177 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12178
ryansturm49a8cb12016-06-15 16:51:09179 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
180 HttpRequestHeaders* request_headers) {
181 if (!proxy_info.is_http() && !proxy_info.is_https() &&
182 !proxy_info.is_quic()) {
183 return;
184 }
185 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12186 }
187
188 private:
ryansturm49a8cb12016-06-15 16:51:09189 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12190};
191
tbansal0f56a39a2016-04-07 22:03:38192class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40193 public:
tbansal180587c2017-02-16 15:13:23194 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
195 bool* rtt_notification_received)
196 : should_notify_updated_rtt_(should_notify_updated_rtt),
197 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38198 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40199
tbansal180587c2017-02-16 15:13:23200 bool ShouldNotifyUpdatedRTT() const override {
201 return *should_notify_updated_rtt_;
202 }
tbansalfdf5665b2015-09-21 22:46:40203
tbansal0f56a39a2016-04-07 22:03:38204 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
205 *rtt_notification_received_ = true;
206 }
207
208 void OnConnectionChanged() override {}
209
210 private:
tbansal180587c2017-02-16 15:13:23211 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38212 bool* rtt_notification_received_;
213
214 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
215};
216
217class TestSocketPerformanceWatcherFactory
218 : public SocketPerformanceWatcherFactory {
219 public:
220 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23221 : watcher_count_(0u),
222 should_notify_updated_rtt_(true),
223 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38224 ~TestSocketPerformanceWatcherFactory() override {}
225
226 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42227 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41228 const Protocol protocol,
229 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51230 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38231 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51232 }
233 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42234 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23235 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
236 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40237 }
238
tbansalc8a94ea2015-11-02 23:58:51239 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40240
tbansalc8a94ea2015-11-02 23:58:51241 bool rtt_notification_received() const { return rtt_notification_received_; }
242
tbansal180587c2017-02-16 15:13:23243 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
244 should_notify_updated_rtt_ = should_notify_updated_rtt;
245 }
246
tbansalc8a94ea2015-11-02 23:58:51247 private:
tbansal0f56a39a2016-04-07 22:03:38248 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23249 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51250 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38251
252 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51253};
254
Ryan Hamilton8d9ee76e2018-05-29 23:52:52255class QuicNetworkTransactionTest
256 : public PlatformTest,
257 public ::testing::WithParamInterface<
258 std::tuple<quic::QuicTransportVersion, bool>>,
259 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00260 protected:
[email protected]1c04f9522013-02-21 20:32:43261 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05262 : version_(std::get<0>(GetParam())),
263 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52264 supported_versions_(quic::test::SupportedTransportVersions(version_)),
David Schinazic8281052019-01-24 06:14:17265 random_generator_(0),
266 client_maker_(
267 version_,
268 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
269 &clock_,
270 kDefaultServerHostName,
271 quic::Perspective::IS_CLIENT,
272 client_headers_include_h2_stream_dependency_),
273 server_maker_(
274 version_,
275 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
276 &clock_,
277 kDefaultServerHostName,
278 quic::Perspective::IS_SERVER,
279 false),
rtenneti052774e2015-11-24 21:00:12280 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43281 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59282 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:11283 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
rchf114d982015-10-21 01:34:56284 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19285 request_.method = "GET";
rchf114d982015-10-21 01:34:56286 std::string url("https://");
bncb07c05532015-05-14 19:07:20287 url.append(kDefaultServerHostName);
288 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19289 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10290 request_.traffic_annotation =
291 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52292 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56293
294 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29295 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56296 verify_details_.cert_verify_result.verified_cert = cert;
297 verify_details_.cert_verify_result.is_issued_by_known_root = true;
298 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43299 }
[email protected]61a527782013-02-21 03:58:00300
dcheng67be2b1f2014-10-27 21:47:29301 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00302 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55303 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00304 }
305
dcheng67be2b1f2014-10-27 21:47:29306 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
308 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55309 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00310 PlatformTest::TearDown();
311 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55312 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40313 session_.reset();
[email protected]61a527782013-02-21 03:58:00314 }
315
Ryan Hamilton8d9ee76e2018-05-29 23:52:52316 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23317 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03318 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52319 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30320 }
321
Ryan Hamilton8d9ee76e2018-05-29 23:52:52322 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23323 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03324 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52325 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58326 }
327
Ryan Hamilton8d9ee76e2018-05-29 23:52:52328 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23329 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52330 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20331 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58332 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20333 }
334
Ryan Hamilton8d9ee76e2018-05-29 23:52:52335 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23336 uint64_t packet_number,
337 uint64_t largest_received,
338 uint64_t smallest_received,
339 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37340 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49341 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37342 }
343
Ryan Hamilton8d9ee76e2018-05-29 23:52:52344 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23345 uint64_t packet_number,
346 uint64_t largest_received,
347 uint64_t smallest_received,
348 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52349 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23350 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49351 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23352 ack_delay_time);
353 }
354
Ryan Hamilton8d9ee76e2018-05-29 23:52:52355 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23356 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 quic::QuicStreamId stream_id,
358 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23359 uint64_t largest_received,
360 uint64_t smallest_received,
361 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58362 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49363 num, false, stream_id, error_code, largest_received, smallest_received,
364 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20365 }
366
Ryan Hamilton8d9ee76e2018-05-29 23:52:52367 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23368 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 quic::QuicStreamId stream_id,
370 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56371 size_t bytes_written) {
372 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18373 bytes_written,
374 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56375 }
376
Ryan Hamilton8d9ee76e2018-05-29 23:52:52377 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23378 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
379 uint64_t largest_received,
380 uint64_t smallest_received,
381 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58382 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49383 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20384 }
[email protected]61a527782013-02-21 03:58:00385
Ryan Hamilton8d9ee76e2018-05-29 23:52:52386 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58387 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23388 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23390 uint64_t largest_received,
391 uint64_t smallest_received,
392 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50394 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58395 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12396 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49397 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12398 }
399
Ryan Hamilton8d9ee76e2018-05-29 23:52:52400 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23401 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12402 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52403 quic::QuicStreamId stream_id,
404 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58405 return server_maker_.MakeRstPacket(num, include_version, stream_id,
406 error_code);
zhongyica364fbb2015-12-12 03:39:12407 }
408
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23410 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36412 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37413 }
414
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23416 uint64_t packet_number,
417 uint64_t largest_received,
418 uint64_t smallest_received,
419 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37420 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49421 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37422 }
423
Ryan Hamilton8d9ee76e2018-05-29 23:52:52424 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23425 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57426 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 quic::QuicStreamId id,
428 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57429 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52430 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57431 return client_maker_.MakePriorityPacket(
432 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23433 ConvertRequestPriorityToQuicPriority(request_priority), offset);
434 }
435
Ryan Hamilton8d9ee76e2018-05-29 23:52:52436 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25437 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23438 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23439 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23440 uint64_t largest_received,
441 uint64_t smallest_received,
442 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25443 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
444 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52445 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25446 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23447 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25448 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57449 }
450
zhongyi32569c62016-01-08 02:54:30451 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13452 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
453 const std::string& scheme,
454 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58455 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30456 }
457
458 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13459 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
460 const std::string& scheme,
461 const std::string& path,
462 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50463 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00464 }
465
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56467 return client_maker_.ConnectRequestHeaders(host_port);
468 }
469
Ryan Hamilton0239aac2018-05-19 00:03:13470 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58471 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00472 }
473
zhongyi32569c62016-01-08 02:54:30474 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13475 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
476 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58477 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30478 }
479
Ryan Hamilton8d9ee76e2018-05-29 23:52:52480 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23481 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52482 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05483 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00484 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52485 quic::QuicStreamOffset offset,
486 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58487 return server_maker_.MakeDataPacket(
488 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00489 }
490
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23492 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52493 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36494 bool should_include_version,
495 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52496 quic::QuicStreamOffset offset,
497 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36498 return client_maker_.MakeDataPacket(
499 packet_number, stream_id, should_include_version, fin, offset, data);
500 }
501
Renjied172e812019-01-16 05:12:35502 std::unique_ptr<quic::QuicEncryptedPacket>
503 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23504 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35505 quic::QuicStreamId stream_id,
506 bool should_include_version,
507 bool fin,
508 quic::QuicStreamOffset offset,
509 const std::vector<std::string> data_writes) {
510 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
511 should_include_version,
512 fin, offset, data_writes);
513 }
514
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23516 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56517 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52518 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23519 uint64_t largest_received,
520 uint64_t smallest_received,
521 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56522 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 quic::QuicStreamOffset offset,
524 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56525 return client_maker_.MakeAckAndDataPacket(
526 packet_number, include_version, stream_id, largest_received,
527 smallest_received, least_unacked, fin, offset, data);
528 }
529
Renjied172e812019-01-16 05:12:35530 std::unique_ptr<quic::QuicEncryptedPacket>
531 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23532 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35533 bool include_version,
534 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23535 uint64_t largest_received,
536 uint64_t smallest_received,
537 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35538 bool fin,
539 quic::QuicStreamOffset offset,
540 const std::vector<std::string> data_writes) {
541 return client_maker_.MakeAckAndMultipleDataFramesPacket(
542 packet_number, include_version, stream_id, largest_received,
543 smallest_received, least_unacked, fin, offset, data_writes);
544 }
545
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23547 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52548 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36549 bool should_include_version,
550 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52551 quic::QuicStreamOffset* offset,
552 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36553 return client_maker_.MakeForceHolDataPacket(
554 packet_number, stream_id, should_include_version, fin, offset, data);
555 }
556
Ryan Hamilton8d9ee76e2018-05-29 23:52:52557 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23558 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 quic::QuicStreamId stream_id,
560 bool should_include_version,
561 bool fin,
562 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56563 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
564 should_include_version, fin,
565 std::move(headers), nullptr);
566 }
567
Ryan Hamilton8d9ee76e2018-05-29 23:52:52568 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23569 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 quic::QuicStreamId stream_id,
571 bool should_include_version,
572 bool fin,
573 spdy::SpdyHeaderBlock headers,
574 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48575 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
576 should_include_version, fin,
577 std::move(headers), 0, offset);
578 }
579
Ryan Hamilton8d9ee76e2018-05-29 23:52:52580 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23581 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52582 quic::QuicStreamId stream_id,
583 bool should_include_version,
584 bool fin,
585 spdy::SpdyHeaderBlock headers,
586 quic::QuicStreamId parent_stream_id,
587 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56588 return ConstructClientRequestHeadersPacket(
589 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48590 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30591 }
592
Ryan Hamilton8d9ee76e2018-05-29 23:52:52593 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23594 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52595 quic::QuicStreamId stream_id,
596 bool should_include_version,
597 bool fin,
598 RequestPriority request_priority,
599 spdy::SpdyHeaderBlock headers,
600 quic::QuicStreamId parent_stream_id,
601 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13602 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56603 ConvertRequestPriorityToQuicPriority(request_priority);
604 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
605 packet_number, stream_id, should_include_version, fin, priority,
606 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00607 }
608
Ryan Hamilton8d9ee76e2018-05-29 23:52:52609 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25610 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23611 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52612 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25613 bool should_include_version,
614 bool fin,
615 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13616 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52617 quic::QuicStreamId parent_stream_id,
618 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25619 size_t* spdy_headers_frame_length,
620 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13621 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25622 ConvertRequestPriorityToQuicPriority(request_priority);
623 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
624 packet_number, stream_id, should_include_version, fin, priority,
625 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
626 data_writes);
627 }
628
Ryan Hamilton8d9ee76e2018-05-29 23:52:52629 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23630 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52631 quic::QuicStreamId stream_id,
632 bool should_include_version,
633 bool fin,
634 const std::vector<std::string>& data,
635 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27636 return client_maker_.MakeMultipleDataFramesPacket(
637 packet_number, stream_id, should_include_version, fin, offset, data);
638 }
639
Ryan Hamilton8d9ee76e2018-05-29 23:52:52640 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23641 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 quic::QuicStreamId stream_id,
643 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13644 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13645 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52646 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13647 QuicTestPacketMaker* maker) {
648 return maker->MakePushPromisePacket(
649 packet_number, stream_id, promised_stream_id, should_include_version,
650 false, std::move(headers), nullptr, offset);
651 }
652
Ryan Hamilton8d9ee76e2018-05-29 23:52:52653 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23654 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52655 quic::QuicStreamId stream_id,
656 bool should_include_version,
657 bool fin,
658 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27659 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
660 should_include_version, fin,
661 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30662 }
663
Ryan Hamilton8d9ee76e2018-05-29 23:52:52664 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23665 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52666 quic::QuicStreamId stream_id,
667 bool should_include_version,
668 bool fin,
669 spdy::SpdyHeaderBlock headers,
670 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58671 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25672 packet_number, stream_id, should_include_version, fin,
673 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30674 }
675
Victor Vasiliev076657c2019-03-12 02:46:43676 std::string ConstructDataHeader(size_t body_len) {
Renjief49758b2019-01-11 23:32:41677 if (version_ != quic::QUIC_VERSION_99) {
678 return "";
679 }
680 quic::HttpEncoder encoder;
681 std::unique_ptr<char[]> buffer;
682 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:43683 return std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:41684 }
685
Ryan Hamilton8d9ee76e2018-05-29 23:52:52686 void CreateSession(
687 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41688 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21689 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05690 session_params_.quic_headers_include_h2_stream_dependency =
691 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00692
mmenke6ddfbea2017-05-31 21:48:41693 session_context_.quic_clock = &clock_;
694 session_context_.quic_random = &random_generator_;
695 session_context_.client_socket_factory = &socket_factory_;
696 session_context_.quic_crypto_client_stream_factory =
697 &crypto_client_stream_factory_;
698 session_context_.host_resolver = &host_resolver_;
699 session_context_.cert_verifier = &cert_verifier_;
700 session_context_.transport_security_state = &transport_security_state_;
701 session_context_.cert_transparency_verifier =
702 cert_transparency_verifier_.get();
703 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
704 session_context_.socket_performance_watcher_factory =
705 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59706 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41707 session_context_.ssl_config_service = ssl_config_service_.get();
708 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
709 session_context_.http_server_properties = &http_server_properties_;
710 session_context_.net_log = net_log_.bound().net_log();
711
712 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12713 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56714 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
715 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00716 }
717
zhongyi86838d52017-06-30 01:19:44718 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21719
bnc691fda62016-08-12 00:43:16720 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19721 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42722 ASSERT_TRUE(response != nullptr);
723 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19724 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
725 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52726 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44727 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19728 response->connection_info);
729 }
730
bnc691fda62016-08-12 00:43:16731 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41732 const HttpResponseInfo* response = trans->GetResponseInfo();
733 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37734 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41735 }
736
bnc691fda62016-08-12 00:43:16737 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19738 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42739 ASSERT_TRUE(response != nullptr);
740 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19741 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
742 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52743 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52744 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19745 response->connection_info);
746 }
747
Yixin Wang46a273ec302018-01-23 17:59:56748 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
749 const HttpResponseInfo* response = trans->GetResponseInfo();
750 ASSERT_TRUE(response != nullptr);
751 ASSERT_TRUE(response->headers.get() != nullptr);
752 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
753 EXPECT_TRUE(response->was_fetched_via_spdy);
754 EXPECT_TRUE(response->was_alpn_negotiated);
755 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
756 response->connection_info);
757 }
758
bnc691fda62016-08-12 00:43:16759 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19760 const std::string& expected) {
761 std::string response_data;
bnc691fda62016-08-12 00:43:16762 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19763 EXPECT_EQ(expected, response_data);
764 }
765
bnc691fda62016-08-12 00:43:16766 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19767 TestCompletionCallback callback;
768 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
770 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19771 }
772
773 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
775 RunTransaction(&trans);
776 CheckWasHttpResponse(&trans);
777 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19778 }
779
tbansalc3308d72016-08-27 10:25:04780 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
781 bool used_proxy,
782 uint16_t port) {
783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
784 HeadersHandler headers_handler;
785 trans.SetBeforeHeadersSentCallback(
786 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
787 base::Unretained(&headers_handler)));
788 RunTransaction(&trans);
789 CheckWasHttpResponse(&trans);
790 CheckResponsePort(&trans, port);
791 CheckResponseData(&trans, expected);
792 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47793 if (used_proxy) {
794 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
795 } else {
796 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
797 }
tbansalc3308d72016-08-27 10:25:04798 }
799
[email protected]aa9b14d2013-05-10 23:45:19800 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56801 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12802 }
803
bnc62a44f022015-04-02 15:59:41804 void SendRequestAndExpectQuicResponseFromProxyOnPort(
805 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46806 uint16_t port) {
bnc62a44f022015-04-02 15:59:41807 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19808 }
809
810 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27811 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19812 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46813 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21814 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12815 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21816 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44817 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19818 }
819
rchbe69cb902016-02-11 01:10:48820 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27821 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48822 const HostPortPair& alternative) {
823 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46824 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21825 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48826 alternative.port());
827 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21828 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44829 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48830 }
831
[email protected]aa9b14d2013-05-10 23:45:19832 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46833 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34834 const AlternativeServiceInfoVector alternative_service_info_vector =
835 http_server_properties_.GetAlternativeServiceInfos(server);
836 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07837 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54838 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19839 }
840
[email protected]4d590c9c2014-05-02 05:14:33841 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46842 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34843 const AlternativeServiceInfoVector alternative_service_info_vector =
844 http_server_properties_.GetAlternativeServiceInfos(server);
845 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54846 EXPECT_EQ(
847 kProtoQUIC,
848 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23849 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54850 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33851 }
852
[email protected]aa9b14d2013-05-10 23:45:19853 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42854 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30855 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30856 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30857 hanging_data->set_connect_data(hanging_connect);
858 hanging_data_.push_back(std::move(hanging_data));
859 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56860 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19861 }
862
Zhongyi Shia6b68d112018-09-24 07:49:03863 void SetUpTestForRetryConnectionOnAlternateNetwork() {
864 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
865 session_params_.quic_migrate_sessions_early_v2 = true;
866 session_params_.quic_retry_on_alternate_network_before_handshake = true;
867 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
868 MockNetworkChangeNotifier* mock_ncn =
869 scoped_mock_change_notifier_->mock_network_change_notifier();
870 mock_ncn->ForceNetworkHandlesSupported();
871 mock_ncn->SetConnectedNetworksList(
872 {kDefaultNetworkForTests, kNewNetworkForTests});
873 }
874
tbansalc3308d72016-08-27 10:25:04875 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
876 // alternative proxy. Verifies that if the alternative proxy job returns
877 // |error_code|, the request is fetched successfully by the main job.
878 void TestAlternativeProxy(int error_code) {
879 // Use a non-cryptographic scheme for the request URL since this request
880 // will be fetched via proxy with QUIC as the alternative service.
881 request_.url = GURL("http://example.org/");
882 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27883 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04884 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27885 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04886 };
887
Ryan Sleevib8d7ea02018-05-07 20:01:01888 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04889 socket_factory_.AddSocketDataProvider(&quic_data);
890
891 // Main job succeeds and the alternative job fails.
892 // Add data for two requests that will be read by the main job.
893 MockRead http_reads_1[] = {
894 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
895 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
896 MockRead(ASYNC, OK)};
897
898 MockRead http_reads_2[] = {
899 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
900 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
901 MockRead(ASYNC, OK)};
902
Ryan Sleevib8d7ea02018-05-07 20:01:01903 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
904 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04905 socket_factory_.AddSocketDataProvider(&http_data_1);
906 socket_factory_.AddSocketDataProvider(&http_data_2);
907 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
909
910 TestProxyDelegate test_proxy_delegate;
911 // Proxy URL is different from the request URL.
912 test_proxy_delegate.set_alternative_proxy_server(
913 ProxyServer::FromPacString("QUIC myproxy.org:443"));
914
Lily Houghton8c2f97d2018-01-22 05:06:59915 proxy_resolution_service_ =
916 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49917 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52918 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04919
920 CreateSession();
921 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
922
923 // The first request should be fetched via the HTTPS proxy.
924 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
925
Reilly Grant89a7e512018-01-20 01:57:16926 // Since the main job succeeded only the alternative proxy server should be
927 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59928 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16929 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04930
931 // Verify that the second request completes successfully, and the
932 // alternative proxy server job is not started.
933 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
934 }
935
Fan Yang32c5a112018-12-10 20:06:33936 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
937 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36938 }
939
Fan Yang32c5a112018-12-10 20:06:33940 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
941 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36942 }
943
Bence Béky230ac612017-08-30 19:17:08944 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49945 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08946 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49947 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08948 }
949
Ryan Hamilton8d9ee76e2018-05-29 23:52:52950 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05951 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52952 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01953 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52954 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17955 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58956 QuicTestPacketMaker client_maker_;
957 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42958 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00959 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56960 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05961 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43962 MockHostResolver host_resolver_;
963 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11964 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42965 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23966 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38967 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07968 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59969 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42970 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07971 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41972 HttpNetworkSession::Params session_params_;
973 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19974 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51975 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42976 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56977 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03978 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12979
980 private:
981 void SendRequestAndExpectQuicResponseMaybeFromProxy(
982 const std::string& expected,
bnc62a44f022015-04-02 15:59:41983 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46984 uint16_t port) {
bnc691fda62016-08-12 00:43:16985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09986 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16987 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09988 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
989 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16990 RunTransaction(&trans);
991 CheckWasQuicResponse(&trans);
992 CheckResponsePort(&trans, port);
993 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09994 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47995 if (used_proxy) {
996 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
997 } else {
998 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
999 }
tbansal7cec3812015-02-05 21:25:121000 }
[email protected]61a527782013-02-21 03:58:001001};
1002
Victor Costane635086f2019-01-27 05:20:301003INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231004 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051005 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521006 ::testing::Combine(
1007 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1008 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201009
Ryan Hamiltona64a5bcf2017-11-30 07:35:281010TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481011 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281012 base::HistogramTester histograms;
1013 session_params_.origins_to_force_quic_on.insert(
1014 HostPortPair::FromString("mail.example.org:443"));
1015 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271016 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281017
1018 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521019 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281020 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431021 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281022 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1023 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1024 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1025
1026 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1027
1028 CreateSession();
1029
1030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1031 TestCompletionCallback callback;
1032 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1034 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1035
1036 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1037 -ERR_INTERNET_DISCONNECTED, 1);
1038 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1039 -ERR_INTERNET_DISCONNECTED, 1);
1040}
1041
1042TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481043 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281044 base::HistogramTester histograms;
1045 session_params_.origins_to_force_quic_on.insert(
1046 HostPortPair::FromString("mail.example.org:443"));
1047 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271048 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281049
1050 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521051 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281052 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431053 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281054 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1055 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1056 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1057
1058 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1059
1060 CreateSession();
1061
1062 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1063 TestCompletionCallback callback;
1064 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1066 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1067
1068 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1069 -ERR_INTERNET_DISCONNECTED, 1);
1070 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1071 -ERR_INTERNET_DISCONNECTED, 1);
1072}
1073
tbansal180587c2017-02-16 15:13:231074TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411075 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231076 HostPortPair::FromString("mail.example.org:443"));
1077
1078 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521079 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361080 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431081 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1082 mock_quic_data.AddWrite(
1083 SYNCHRONOUS,
1084 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331085 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431086 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431087 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331088 ASYNC, ConstructServerResponseHeadersPacket(
1089 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1090 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431091 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331092 mock_quic_data.AddRead(
1093 ASYNC, ConstructServerDataPacket(
1094 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411095 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431096 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231097 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1098
1099 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1100
1101 CreateSession();
1102 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1103
1104 EXPECT_FALSE(
1105 test_socket_performance_watcher_factory_.rtt_notification_received());
1106 SendRequestAndExpectQuicResponse("hello!");
1107 EXPECT_TRUE(
1108 test_socket_performance_watcher_factory_.rtt_notification_received());
1109}
1110
1111TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411112 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231113 HostPortPair::FromString("mail.example.org:443"));
1114
1115 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521116 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361117 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431118 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1119 mock_quic_data.AddWrite(
1120 SYNCHRONOUS,
1121 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331122 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431123 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431124 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331125 ASYNC, ConstructServerResponseHeadersPacket(
1126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1127 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431128 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331129 mock_quic_data.AddRead(
1130 ASYNC, ConstructServerDataPacket(
1131 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411132 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431133 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231134 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1135
1136 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1137
1138 CreateSession();
1139 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1140
1141 EXPECT_FALSE(
1142 test_socket_performance_watcher_factory_.rtt_notification_received());
1143 SendRequestAndExpectQuicResponse("hello!");
1144 EXPECT_FALSE(
1145 test_socket_performance_watcher_factory_.rtt_notification_received());
1146}
1147
[email protected]1e960032013-12-20 19:00:201148TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411149 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571150 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471151
[email protected]1e960032013-12-20 19:00:201152 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521153 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361154 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431155 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1156 mock_quic_data.AddWrite(
1157 SYNCHRONOUS,
1158 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331159 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431160 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431161 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331162 ASYNC, ConstructServerResponseHeadersPacket(
1163 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1164 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431165 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331166 mock_quic_data.AddRead(
1167 ASYNC, ConstructServerDataPacket(
1168 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411169 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431170 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591171 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471172
rcha5399e02015-04-21 19:32:041173 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471174
[email protected]4dca587c2013-03-07 16:54:471175 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471176
[email protected]aa9b14d2013-05-10 23:45:191177 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471178
[email protected]98b20ce2013-05-10 05:55:261179 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461180 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191181 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261182 EXPECT_LT(0u, entries.size());
1183
1184 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291185 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001186 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1187 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261188 EXPECT_LT(0, pos);
1189
rchfd527212015-08-25 00:41:261190 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291191 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261192 entries, 0,
mikecirone8b85c432016-09-08 19:11:001193 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1194 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261195 EXPECT_LT(0, pos);
1196
Eric Romanaefc98c2018-12-18 21:38:011197 int packet_number;
1198 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1199 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261200
rchfd527212015-08-25 00:41:261201 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1202 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001203 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1204 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261205 EXPECT_LT(0, pos);
1206
[email protected]98b20ce2013-05-10 05:55:261207 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291208 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001209 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1210 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261211 EXPECT_LT(0, pos);
1212
1213 int log_stream_id;
1214 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381215 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1216 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471217}
1218
rchbd089ab2017-05-26 23:05:041219TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411220 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041221 HostPortPair::FromString("mail.example.org:443"));
1222
1223 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521224 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041225 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431226 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1227 mock_quic_data.AddWrite(
1228 SYNCHRONOUS,
1229 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331230 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431231 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131232 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041233 response_headers["key1"] = std::string(30000, 'A');
1234 response_headers["key2"] = std::string(30000, 'A');
1235 response_headers["key3"] = std::string(30000, 'A');
1236 response_headers["key4"] = std::string(30000, 'A');
1237 response_headers["key5"] = std::string(30000, 'A');
1238 response_headers["key6"] = std::string(30000, 'A');
1239 response_headers["key7"] = std::string(30000, 'A');
1240 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331241 spdy::SpdyHeadersIR headers_frame(
1242 GetNthClientInitiatedBidirectionalStreamId(0),
1243 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131244 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1245 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041246 response_framer.SerializeFrame(headers_frame);
1247
Fan Yangac867502019-01-28 21:10:231248 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041249 size_t chunk_size = 1200;
1250 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1251 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431252 mock_quic_data.AddRead(
1253 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091254 packet_number++,
1255 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521256 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041257 }
1258
Victor Vasiliev076657c2019-03-12 02:46:431259 std::string header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041260 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331261 ASYNC, ConstructServerDataPacket(
1262 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411263 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041264 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431265 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1266 mock_quic_data.AddWrite(ASYNC,
1267 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041268
1269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1270
1271 CreateSession();
1272
1273 SendRequestAndExpectQuicResponse("hello!");
1274}
1275
1276TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481277 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411278 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041279 HostPortPair::FromString("mail.example.org:443"));
1280
1281 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521282 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041283 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431284 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1285 mock_quic_data.AddWrite(
1286 SYNCHRONOUS,
1287 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331288 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431289 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131290 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041291 response_headers["key1"] = std::string(30000, 'A');
1292 response_headers["key2"] = std::string(30000, 'A');
1293 response_headers["key3"] = std::string(30000, 'A');
1294 response_headers["key4"] = std::string(30000, 'A');
1295 response_headers["key5"] = std::string(30000, 'A');
1296 response_headers["key6"] = std::string(30000, 'A');
1297 response_headers["key7"] = std::string(30000, 'A');
1298 response_headers["key8"] = std::string(30000, 'A');
1299 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331300 spdy::SpdyHeadersIR headers_frame(
1301 GetNthClientInitiatedBidirectionalStreamId(0),
1302 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131303 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1304 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041305 response_framer.SerializeFrame(headers_frame);
1306
Fan Yangac867502019-01-28 21:10:231307 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041308 size_t chunk_size = 1200;
1309 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1310 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431311 mock_quic_data.AddRead(
1312 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091313 packet_number++,
1314 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521315 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041316 }
1317
Victor Vasiliev076657c2019-03-12 02:46:431318 std::string header = ConstructDataHeader(6);
Renjief49758b2019-01-11 23:32:411319
rchbd089ab2017-05-26 23:05:041320 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331321 ASYNC, ConstructServerDataPacket(
1322 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411323 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041324 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431325 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1326 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331327 ASYNC, ConstructClientAckAndRstPacket(
1328 4, GetNthClientInitiatedBidirectionalStreamId(0),
1329 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041330
1331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1332
1333 CreateSession();
1334
1335 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1336 TestCompletionCallback callback;
1337 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1339 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1340}
1341
rcha2bd44b2016-07-02 00:42:551342TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411343 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551344
Ryan Hamilton9835e662018-08-02 05:36:271345 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551346
1347 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521348 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361349 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431350 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1351 mock_quic_data.AddWrite(
1352 SYNCHRONOUS,
1353 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331354 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431355 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431356 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331357 ASYNC, ConstructServerResponseHeadersPacket(
1358 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1359 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431360 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331361 mock_quic_data.AddRead(
1362 ASYNC, ConstructServerDataPacket(
1363 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411364 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431365 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551366 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1367
1368 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1369
1370 CreateSession();
1371
1372 SendRequestAndExpectQuicResponse("hello!");
1373 EXPECT_TRUE(
1374 test_socket_performance_watcher_factory_.rtt_notification_received());
1375}
1376
[email protected]cf3e3cd62014-02-05 16:16:161377TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411378 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591379 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491380 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161381
[email protected]cf3e3cd62014-02-05 16:16:161382 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521383 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361384 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431385 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1386 mock_quic_data.AddWrite(
1387 SYNCHRONOUS,
1388 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331389 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431390 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431391 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331392 ASYNC, ConstructServerResponseHeadersPacket(
1393 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1394 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431395 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331396 mock_quic_data.AddRead(
1397 ASYNC, ConstructServerDataPacket(
1398 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411399 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431400 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501401 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591402 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161403
rcha5399e02015-04-21 19:32:041404 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161405
tbansal0f56a39a2016-04-07 22:03:381406 EXPECT_FALSE(
1407 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161408 // There is no need to set up an alternate protocol job, because
1409 // no attempt will be made to speak to the proxy over TCP.
1410
rch9ae5b3b2016-02-11 00:36:291411 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161412 CreateSession();
1413
bnc62a44f022015-04-02 15:59:411414 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381415 EXPECT_TRUE(
1416 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161417}
1418
bnc313ba9c2015-06-11 15:42:311419// Regression test for https://crbug.com/492458. Test that for an HTTP
1420// connection through a QUIC proxy, the certificate exhibited by the proxy is
1421// checked against the proxy hostname, not the origin hostname.
1422TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291423 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311424 const std::string proxy_host = "www.example.org";
1425
mmenke6ddfbea2017-05-31 21:48:411426 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591427 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491428 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311429
alyssar2adf3ac2016-05-03 17:12:581430 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311431 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521432 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361433 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431434 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1435 mock_quic_data.AddWrite(
1436 SYNCHRONOUS,
1437 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331438 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431439 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431440 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331441 ASYNC, ConstructServerResponseHeadersPacket(
1442 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1443 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431444 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331445 mock_quic_data.AddRead(
1446 ASYNC, ConstructServerDataPacket(
1447 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411448 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431449 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501450 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591451 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311452 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1453
1454 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291455 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311456 ASSERT_TRUE(cert.get());
1457 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241458 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1459 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311460 ProofVerifyDetailsChromium verify_details;
1461 verify_details.cert_verify_result.verified_cert = cert;
1462 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561463 ProofVerifyDetailsChromium verify_details2;
1464 verify_details2.cert_verify_result.verified_cert = cert;
1465 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311466
1467 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091468 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321469 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271470 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311471 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1472}
1473
rchbe69cb902016-02-11 01:10:481474TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341475 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481476 HostPortPair origin("www.example.org", 443);
1477 HostPortPair alternative("mail.example.org", 443);
1478
1479 base::FilePath certs_dir = GetTestCertsDirectory();
1480 scoped_refptr<X509Certificate> cert(
1481 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1482 ASSERT_TRUE(cert.get());
1483 // TODO(rch): the connection should be "to" the origin, so if the cert is
1484 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241485 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1486 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481487 ProofVerifyDetailsChromium verify_details;
1488 verify_details.cert_verify_result.verified_cert = cert;
1489 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1490
alyssar2adf3ac2016-05-03 17:12:581491 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481492 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521493 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361494 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431495 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1496 mock_quic_data.AddWrite(
1497 SYNCHRONOUS,
1498 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331499 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431500 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431501 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331502 ASYNC, ConstructServerResponseHeadersPacket(
1503 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1504 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431505 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331506 mock_quic_data.AddRead(
1507 ASYNC, ConstructServerDataPacket(
1508 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411509 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431510 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481511 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1512 mock_quic_data.AddRead(ASYNC, 0);
1513 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1514
1515 request_.url = GURL("https://" + origin.host());
1516 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271517 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091518 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321519 CreateSession();
rchbe69cb902016-02-11 01:10:481520
1521 SendRequestAndExpectQuicResponse("hello!");
1522}
1523
zhongyief3f4ce52017-07-05 23:53:281524TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521525 quic::QuicTransportVersion unsupported_version =
1526 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281527 // Add support for another QUIC version besides |version_|. Also find a
1528 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521529 for (const quic::QuicTransportVersion& version :
1530 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281531 if (version == version_)
1532 continue;
1533 if (supported_versions_.size() != 2) {
1534 supported_versions_.push_back(version);
1535 continue;
1536 }
1537 unsupported_version = version;
1538 break;
1539 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521540 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281541
1542 // Set up alternative service to use QUIC with a version that is not
1543 // supported.
1544 url::SchemeHostPort server(request_.url);
1545 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1546 443);
1547 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1548 http_server_properties_.SetQuicAlternativeService(
1549 server, alternative_service, expiration, {unsupported_version});
1550
1551 AlternativeServiceInfoVector alt_svc_info_vector =
1552 http_server_properties_.GetAlternativeServiceInfos(server);
1553 EXPECT_EQ(1u, alt_svc_info_vector.size());
1554 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1555 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1556 EXPECT_EQ(unsupported_version,
1557 alt_svc_info_vector[0].advertised_versions()[0]);
1558
1559 // First request should still be sent via TCP as the QUIC version advertised
1560 // in the stored AlternativeService is not supported by the client. However,
1561 // the response from the server will advertise new Alt-Svc with supported
1562 // versions.
1563 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521564 GenerateQuicVersionsListForAltSvcHeader(
1565 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281566 std::string altsvc_header =
1567 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1568 advertised_versions_list_str.c_str());
1569 MockRead http_reads[] = {
1570 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1571 MockRead("hello world"),
1572 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1573 MockRead(ASYNC, OK)};
1574
Ryan Sleevib8d7ea02018-05-07 20:01:011575 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281576 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081577 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281578 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1579
1580 // Second request should be sent via QUIC as a new list of verions supported
1581 // by the client has been advertised by the server.
1582 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521583 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281584 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431585 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1586 mock_quic_data.AddWrite(
1587 SYNCHRONOUS,
1588 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331589 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431590 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431591 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331592 ASYNC, ConstructServerResponseHeadersPacket(
1593 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1594 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431595 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331596 mock_quic_data.AddRead(
1597 ASYNC, ConstructServerDataPacket(
1598 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411599 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431600 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281601 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1602 mock_quic_data.AddRead(ASYNC, 0); // EOF
1603
1604 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1605
1606 AddHangingNonAlternateProtocolSocketData();
1607
1608 CreateSession(supported_versions_);
1609
1610 SendRequestAndExpectHttpResponse("hello world");
1611 SendRequestAndExpectQuicResponse("hello!");
1612
1613 // Check alternative service list is updated with new versions.
1614 alt_svc_info_vector =
1615 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1616 EXPECT_EQ(1u, alt_svc_info_vector.size());
1617 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1618 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1619 // Advertised versions will be lised in a sorted order.
1620 std::sort(supported_versions_.begin(), supported_versions_.end());
1621 EXPECT_EQ(supported_versions_[0],
1622 alt_svc_info_vector[0].advertised_versions()[0]);
1623 EXPECT_EQ(supported_versions_[1],
1624 alt_svc_info_vector[0].advertised_versions()[1]);
1625}
1626
bncaccd4962017-04-06 21:00:261627// Regression test for https://crbug.com/546991.
1628// The server might not be able to serve a request on an alternative connection,
1629// and might send a 421 Misdirected Request response status to indicate this.
1630// HttpNetworkTransaction should reset the request and retry without using
1631// alternative services.
1632TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1633 // Set up alternative service to use QUIC.
1634 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1635 // that overrides |enable_alternative_services|.
1636 url::SchemeHostPort server(request_.url);
1637 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1638 443);
1639 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211640 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441641 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261642
davidbena4449722017-05-05 23:30:531643 // First try: The alternative job uses QUIC and reports an HTTP 421
1644 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1645 // paused at Connect(), so it will never exit the socket pool. This ensures
1646 // that the alternate job always wins the race and keeps whether the
1647 // |http_data| exits the socket pool before the main job is aborted
1648 // deterministic. The first main job gets aborted without the socket pool ever
1649 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261650 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521651 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361652 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431653 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1654 mock_quic_data.AddWrite(
1655 SYNCHRONOUS,
1656 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331657 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431658 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331659 mock_quic_data.AddRead(
1660 ASYNC, ConstructServerResponseHeadersPacket(
1661 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1662 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261663 mock_quic_data.AddRead(ASYNC, OK);
1664 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1665
davidbena4449722017-05-05 23:30:531666 // Second try: The main job uses TCP, and there is no alternate job. Once the
1667 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1668 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261669 // Note that if there was an alternative QUIC Job created for the second try,
1670 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1671 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531672 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1673 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1674 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1675 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1676 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1677 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011678 reads, writes);
bncaccd4962017-04-06 21:00:261679 socket_factory_.AddSocketDataProvider(&http_data);
1680 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1681
bncaccd4962017-04-06 21:00:261682 CreateSession();
1683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531684
1685 // Run until |mock_quic_data| has failed and |http_data| has paused.
1686 TestCompletionCallback callback;
1687 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1689 base::RunLoop().RunUntilIdle();
1690
1691 // |mock_quic_data| must have run to completion.
1692 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1693 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1694
1695 // Now that the QUIC data has been consumed, unblock |http_data|.
1696 http_data.socket()->OnConnectComplete(MockConnect());
1697
1698 // The retry logic must hide the 421 status. The transaction succeeds on
1699 // |http_data|.
1700 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261701 CheckWasHttpResponse(&trans);
1702 CheckResponsePort(&trans, 443);
1703 CheckResponseData(&trans, "hello!");
1704}
1705
[email protected]1e960032013-12-20 19:00:201706TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411707 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571708 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301709
tbansalfdf5665b2015-09-21 22:46:401710 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521711 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361712 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431713 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401714 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401715 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371716 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361717 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431718 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301719 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401720 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431721 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401722
1723 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1724 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301725
1726 CreateSession();
1727
tbansal0f56a39a2016-04-07 22:03:381728 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401729 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401731 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161732 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1734 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381735 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531736
1737 NetErrorDetails details;
1738 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521739 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401740 }
[email protected]cebe3282013-05-22 23:49:301741}
1742
tbansalc8a94ea2015-11-02 23:58:511743TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1744 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411745 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571746 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511747
1748 MockRead http_reads[] = {
1749 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1750 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1751 MockRead(ASYNC, OK)};
1752
Ryan Sleevib8d7ea02018-05-07 20:01:011753 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511754 socket_factory_.AddSocketDataProvider(&data);
1755 SSLSocketDataProvider ssl(ASYNC, OK);
1756 socket_factory_.AddSSLSocketDataProvider(&ssl);
1757
1758 CreateSession();
1759
1760 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381761 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511762}
1763
bncc958faa2015-07-31 18:14:521764TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521765 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561766 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1767 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521768 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1769 MockRead(ASYNC, OK)};
1770
Ryan Sleevib8d7ea02018-05-07 20:01:011771 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521772 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081773 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561774 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521775
1776 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521777 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361778 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431779 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1780 mock_quic_data.AddWrite(
1781 SYNCHRONOUS,
1782 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331783 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431784 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431785 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331786 ASYNC, ConstructServerResponseHeadersPacket(
1787 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1788 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431789 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331790 mock_quic_data.AddRead(
1791 ASYNC, ConstructServerDataPacket(
1792 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411793 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431794 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521795 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591796 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521797
1798 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1799
rtennetib8e80fb2016-05-16 00:12:091800 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321801 CreateSession();
bncc958faa2015-07-31 18:14:521802
1803 SendRequestAndExpectHttpResponse("hello world");
1804 SendRequestAndExpectQuicResponse("hello!");
1805}
1806
zhongyia00ca012017-07-06 23:36:391807TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1808 // Both server advertises and client supports two QUIC versions.
1809 // Only |version_| is advertised and supported.
1810 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1811 // PacketMakers are using |version_|.
1812
1813 // Add support for another QUIC version besides |version_| on the client side.
1814 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521815 quic::QuicTransportVersion advertised_version_2 =
1816 quic::QUIC_VERSION_UNSUPPORTED;
1817 for (const quic::QuicTransportVersion& version :
1818 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391819 if (version == version_)
1820 continue;
1821 if (supported_versions_.size() != 2) {
1822 supported_versions_.push_back(version);
1823 continue;
1824 }
1825 advertised_version_2 = version;
1826 break;
1827 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521828 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391829
1830 std::string QuicAltSvcWithVersionHeader =
1831 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1832 advertised_version_2, version_);
1833
1834 MockRead http_reads[] = {
1835 MockRead("HTTP/1.1 200 OK\r\n"),
1836 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1837 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1838 MockRead(ASYNC, OK)};
1839
Ryan Sleevib8d7ea02018-05-07 20:01:011840 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391841 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081842 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391843 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1844
1845 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521846 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391847 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431848 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1849 mock_quic_data.AddWrite(
1850 SYNCHRONOUS,
1851 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331852 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431853 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431854 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331855 ASYNC, ConstructServerResponseHeadersPacket(
1856 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1857 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431858 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331859 mock_quic_data.AddRead(
1860 ASYNC, ConstructServerDataPacket(
1861 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411862 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431863 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391864 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1865 mock_quic_data.AddRead(ASYNC, 0); // EOF
1866
1867 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1868
1869 AddHangingNonAlternateProtocolSocketData();
1870 CreateSession(supported_versions_);
1871
1872 SendRequestAndExpectHttpResponse("hello world");
1873 SendRequestAndExpectQuicResponse("hello!");
1874}
1875
1876TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1877 // Client and server mutually support more than one QUIC_VERSION.
1878 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1879 // which is verified as the PacketMakers are using |version_|.
1880
Ryan Hamilton8d9ee76e2018-05-29 23:52:521881 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1882 for (const quic::QuicTransportVersion& version :
1883 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391884 if (version == version_)
1885 continue;
1886 common_version_2 = version;
1887 break;
1888 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521889 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391890
1891 supported_versions_.push_back(
1892 common_version_2); // Supported but unpreferred.
1893
1894 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1895 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1896
1897 MockRead http_reads[] = {
1898 MockRead("HTTP/1.1 200 OK\r\n"),
1899 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1900 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1901 MockRead(ASYNC, OK)};
1902
Ryan Sleevib8d7ea02018-05-07 20:01:011903 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391904 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081905 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1907
1908 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521909 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391910 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431911 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1912 mock_quic_data.AddWrite(
1913 SYNCHRONOUS,
1914 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331915 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431916 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431917 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331918 ASYNC, ConstructServerResponseHeadersPacket(
1919 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1920 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431921 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331922 mock_quic_data.AddRead(
1923 ASYNC, ConstructServerDataPacket(
1924 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411925 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431926 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391927 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1928 mock_quic_data.AddRead(ASYNC, 0); // EOF
1929
1930 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1931
1932 AddHangingNonAlternateProtocolSocketData();
1933 CreateSession(supported_versions_);
1934
1935 SendRequestAndExpectHttpResponse("hello world");
1936 SendRequestAndExpectQuicResponse("hello!");
1937}
1938
rchf47265dc2016-03-21 21:33:121939TEST_P(QuicNetworkTransactionTest,
1940 UseAlternativeServiceWithProbabilityForQuic) {
1941 MockRead http_reads[] = {
1942 MockRead("HTTP/1.1 200 OK\r\n"),
1943 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1944 MockRead("hello world"),
1945 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1946 MockRead(ASYNC, OK)};
1947
Ryan Sleevib8d7ea02018-05-07 20:01:011948 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121949 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081950 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121951 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1952
1953 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521954 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361955 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431956 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1957 mock_quic_data.AddWrite(
1958 SYNCHRONOUS,
1959 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331960 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431961 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431962 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331963 ASYNC, ConstructServerResponseHeadersPacket(
1964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1965 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:431966 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331967 mock_quic_data.AddRead(
1968 ASYNC, ConstructServerDataPacket(
1969 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411970 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431971 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121972 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1973 mock_quic_data.AddRead(ASYNC, 0); // EOF
1974
1975 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1976
rtennetib8e80fb2016-05-16 00:12:091977 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121978 CreateSession();
1979
1980 SendRequestAndExpectHttpResponse("hello world");
1981 SendRequestAndExpectQuicResponse("hello!");
1982}
1983
zhongyi3d4a55e72016-04-22 20:36:461984TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1985 MockRead http_reads[] = {
1986 MockRead("HTTP/1.1 200 OK\r\n"),
1987 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1988 MockRead("hello world"),
1989 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1990 MockRead(ASYNC, OK)};
1991
Ryan Sleevib8d7ea02018-05-07 20:01:011992 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461993 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081994 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461995 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1996
1997 CreateSession();
bncb26024382016-06-29 02:39:451998 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461999 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452000 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462001 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402002 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462003 session_->http_server_properties();
2004 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2005 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2006 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462007 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342008 2u,
2009 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452010 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342011 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462012}
2013
2014TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2015 MockRead http_reads[] = {
2016 MockRead("HTTP/1.1 200 OK\r\n"),
2017 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2018 MockRead("hello world"),
2019 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2020 MockRead(ASYNC, OK)};
2021
Ryan Sleevib8d7ea02018-05-07 20:01:012022 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082023 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462024
2025 socket_factory_.AddSocketDataProvider(&http_data);
2026 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2027 socket_factory_.AddSocketDataProvider(&http_data);
2028 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2029
2030 CreateSession();
2031
2032 // Send https request and set alternative services if response header
2033 // advertises alternative service for mail.example.org.
2034 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402035 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462036 session_->http_server_properties();
2037
2038 const url::SchemeHostPort https_server(request_.url);
2039 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342040 EXPECT_EQ(
2041 2u,
2042 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462043
2044 // Send http request to the same origin but with diffrent scheme, should not
2045 // use QUIC.
2046 request_.url = GURL("http://mail.example.org:443");
2047 SendRequestAndExpectHttpResponse("hello world");
2048}
2049
zhongyie537a002017-06-27 16:48:212050TEST_P(QuicNetworkTransactionTest,
2051 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442052 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522053 for (const quic::QuicTransportVersion& version :
2054 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442055 if (version == version_)
2056 continue;
2057 supported_versions_.push_back(version);
2058 break;
2059 }
2060
zhongyie537a002017-06-27 16:48:212061 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522062 GenerateQuicVersionsListForAltSvcHeader(
2063 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212064 std::string altsvc_header =
2065 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2066 advertised_versions_list_str.c_str());
2067 MockRead http_reads[] = {
2068 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2069 MockRead("hello world"),
2070 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2071 MockRead(ASYNC, OK)};
2072
Ryan Sleevib8d7ea02018-05-07 20:01:012073 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212074 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082075 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212076 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2077
2078 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522079 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212080 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432081 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2082 mock_quic_data.AddWrite(
2083 SYNCHRONOUS,
2084 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332085 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432086 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432087 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332088 ASYNC, ConstructServerResponseHeadersPacket(
2089 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2090 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432091 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332092 mock_quic_data.AddRead(
2093 ASYNC, ConstructServerDataPacket(
2094 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412095 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432096 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212097 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2098 mock_quic_data.AddRead(ASYNC, 0); // EOF
2099
2100 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2101
2102 AddHangingNonAlternateProtocolSocketData();
2103
zhongyi86838d52017-06-30 01:19:442104 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212105
2106 SendRequestAndExpectHttpResponse("hello world");
2107 SendRequestAndExpectQuicResponse("hello!");
2108
2109 // Check alternative service is set with only mutually supported versions.
2110 const url::SchemeHostPort https_server(request_.url);
2111 const AlternativeServiceInfoVector alt_svc_info_vector =
2112 session_->http_server_properties()->GetAlternativeServiceInfos(
2113 https_server);
2114 EXPECT_EQ(1u, alt_svc_info_vector.size());
2115 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2116 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2117 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442118 std::sort(supported_versions_.begin(), supported_versions_.end());
2119 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212120 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442121 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212122 alt_svc_info_vector[0].advertised_versions()[1]);
2123}
2124
danzh3134c2562016-08-12 14:07:522125TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442126 std::string altsvc_header =
2127 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072128 MockRead http_reads[] = {
2129 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2130 MockRead("hello world"),
2131 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2132 MockRead(ASYNC, OK)};
2133
Ryan Sleevib8d7ea02018-05-07 20:01:012134 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072135 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082136 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072137 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2138
2139 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522140 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362141 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432142 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2143 mock_quic_data.AddWrite(
2144 SYNCHRONOUS,
2145 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332146 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432147 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432148 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332149 ASYNC, ConstructServerResponseHeadersPacket(
2150 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2151 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:432152 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332153 mock_quic_data.AddRead(
2154 ASYNC, ConstructServerDataPacket(
2155 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412156 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432157 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072158 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592159 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072160
2161 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2162
rtennetib8e80fb2016-05-16 00:12:092163 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322164 CreateSession();
bnc8be55ebb2015-10-30 14:12:072165
2166 SendRequestAndExpectHttpResponse("hello world");
2167 SendRequestAndExpectQuicResponse("hello!");
2168}
2169
zhongyi6b5a3892016-03-12 04:46:202170TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092171 if (version_ == quic::QUIC_VERSION_99) {
2172 // Not available under version 99
2173 return;
2174 }
zhongyi6b5a3892016-03-12 04:46:202175 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522176 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362177 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432178 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2179 mock_quic_data.AddWrite(
2180 SYNCHRONOUS,
2181 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332182 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432183 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332184 mock_quic_data.AddRead(
2185 ASYNC, ConstructServerResponseHeadersPacket(
2186 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2187 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202188 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522189 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432190 mock_quic_data.AddRead(SYNCHRONOUS,
2191 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522192 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432193 "connection migration with port change only"));
2194 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Victor Vasiliev076657c2019-03-12 02:46:432195 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332196 mock_quic_data.AddRead(
2197 SYNCHRONOUS, ConstructServerDataPacket(
2198 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412199 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332200 mock_quic_data.AddWrite(SYNCHRONOUS,
2201 ConstructClientAckAndRstPacket(
2202 4, GetNthClientInitiatedBidirectionalStreamId(0),
2203 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202204 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2205 mock_quic_data.AddRead(ASYNC, 0); // EOF
2206
2207 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2208
2209 // The non-alternate protocol job needs to hang in order to guarantee that
2210 // the alternate-protocol job will "win".
2211 AddHangingNonAlternateProtocolSocketData();
2212
2213 // In order for a new QUIC session to be established via alternate-protocol
2214 // without racing an HTTP connection, we need the host resolution to happen
2215 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2216 // connection to the the server, in this test we require confirmation
2217 // before encrypting so the HTTP job will still start.
2218 host_resolver_.set_synchronous_mode(true);
2219 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2220 "");
zhongyi6b5a3892016-03-12 04:46:202221
2222 CreateSession();
2223 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272224 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202225
bnc691fda62016-08-12 00:43:162226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202227 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362228 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202230
2231 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522232 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012233 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202234
2235 // Check whether this transaction is correctly marked as received a go-away
2236 // because of migrating port.
2237 NetErrorDetails details;
2238 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162239 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202240 EXPECT_TRUE(details.quic_port_migration_detected);
2241}
2242
Zhongyi Shia6b68d112018-09-24 07:49:032243// This test verifies that a new QUIC connection will be attempted on the
2244// alternate network if the original QUIC connection fails with idle timeout
2245// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2246// alternate network as well, QUIC is marked as broken and the brokenness will
2247// not expire when default network changes.
2248TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
Michael Warres167db3e2019-03-01 21:38:032249 if (version_ >= quic::QUIC_VERSION_47) {
2250 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2251 return;
2252 }
Zhongyi Shia6b68d112018-09-24 07:49:032253 SetUpTestForRetryConnectionOnAlternateNetwork();
2254
2255 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032256 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032257
2258 // The request will initially go out over QUIC.
2259 MockQuicData quic_data;
2260 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2261 int packet_num = 1;
2262 quic_data.AddWrite(SYNCHRONOUS,
2263 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2264 // Retranmit the handshake messages.
2265 quic_data.AddWrite(SYNCHRONOUS,
2266 client_maker_.MakeDummyCHLOPacket(packet_num++));
2267 quic_data.AddWrite(SYNCHRONOUS,
2268 client_maker_.MakeDummyCHLOPacket(packet_num++));
2269 quic_data.AddWrite(SYNCHRONOUS,
2270 client_maker_.MakeDummyCHLOPacket(packet_num++));
2271 quic_data.AddWrite(SYNCHRONOUS,
2272 client_maker_.MakeDummyCHLOPacket(packet_num++));
2273 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2274 if (version_ <= quic::QUIC_VERSION_39) {
2275 quic_data.AddWrite(SYNCHRONOUS,
2276 client_maker_.MakeDummyCHLOPacket(packet_num++));
2277 }
2278 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2279 quic_data.AddWrite(SYNCHRONOUS,
2280 client_maker_.MakeConnectionClosePacket(
2281 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2282 "No recent network activity."));
2283 quic_data.AddSocketDataToFactory(&socket_factory_);
2284
2285 // Add successful TCP data so that TCP job will succeed.
2286 MockWrite http_writes[] = {
2287 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2288 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2289 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2290
2291 MockRead http_reads[] = {
2292 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2293 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2294 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2295 SequencedSocketData http_data(http_reads, http_writes);
2296 socket_factory_.AddSocketDataProvider(&http_data);
2297 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2298
2299 // Add data for the second QUIC connection to fail.
2300 MockQuicData quic_data2;
2301 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2302 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2303 quic_data2.AddSocketDataToFactory(&socket_factory_);
2304
2305 // Resolve the host resolution synchronously.
2306 host_resolver_.set_synchronous_mode(true);
2307 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2308 "");
Zhongyi Shia6b68d112018-09-24 07:49:032309
2310 CreateSession();
2311 session_->quic_stream_factory()->set_require_confirmation(true);
2312 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2313 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2314 QuicStreamFactoryPeer::SetAlarmFactory(
2315 session_->quic_stream_factory(),
2316 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2317 &clock_));
2318 // Add alternate protocol mapping to race QUIC and TCP.
2319 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2320 // peer.
2321 AddQuicAlternateProtocolMapping(
2322 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2323
2324 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2325 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362326 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032327 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2328
2329 // Pump the message loop to get the request started.
2330 // Request will be served with TCP job.
2331 base::RunLoop().RunUntilIdle();
2332 EXPECT_THAT(callback.WaitForResult(), IsOk());
2333 CheckResponseData(&trans, "TCP succeeds");
2334
2335 // Fire the retransmission alarm, from this point, connection will idle
2336 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062337 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182338 quic_fix_time_of_first_packet_sent_after_receiving)) {
2339 quic_task_runner_->RunNextTask();
2340 }
Zhongyi Shia6b68d112018-09-24 07:49:032341 // Fast forward to idle timeout the original connection. A new connection will
2342 // be kicked off on the alternate network.
2343 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2344 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2345 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2346
2347 // Run the message loop to execute posted tasks, which will report job status.
2348 base::RunLoop().RunUntilIdle();
2349
2350 // Verify that QUIC is marked as broken.
2351 ExpectBrokenAlternateProtocolMapping();
2352
2353 // Deliver a message to notify the new network becomes default, the brokenness
2354 // will not expire as QUIC is broken on both networks.
2355 scoped_mock_change_notifier_->mock_network_change_notifier()
2356 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2357 ExpectBrokenAlternateProtocolMapping();
2358
2359 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2360 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2361}
2362
2363// This test verifies that a new QUIC connection will be attempted on the
2364// alternate network if the original QUIC connection fails with idle timeout
2365// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2366// alternate network, QUIC is marked as broken. The brokenness will expire when
2367// the default network changes.
2368TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Michael Warres167db3e2019-03-01 21:38:032369 if (version_ >= quic::QUIC_VERSION_47) {
2370 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2371 return;
2372 }
Zhongyi Shia6b68d112018-09-24 07:49:032373 SetUpTestForRetryConnectionOnAlternateNetwork();
2374
2375 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032376 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032377
2378 // The request will initially go out over QUIC.
2379 MockQuicData quic_data;
2380 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2381 int packet_num = 1;
2382 quic_data.AddWrite(SYNCHRONOUS,
2383 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2384 // Retranmit the handshake messages.
2385 quic_data.AddWrite(SYNCHRONOUS,
2386 client_maker_.MakeDummyCHLOPacket(packet_num++));
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 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2394 if (version_ <= quic::QUIC_VERSION_39) {
2395 quic_data.AddWrite(SYNCHRONOUS,
2396 client_maker_.MakeDummyCHLOPacket(packet_num++));
2397 }
2398 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2399 quic_data.AddWrite(SYNCHRONOUS,
2400 client_maker_.MakeConnectionClosePacket(
2401 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2402 "No recent network activity."));
2403 quic_data.AddSocketDataToFactory(&socket_factory_);
2404
2405 // Add successful TCP data so that TCP job will succeed.
2406 MockWrite http_writes[] = {
2407 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2408 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2409 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2410
2411 MockRead http_reads[] = {
2412 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2413 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2414 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2415 SequencedSocketData http_data(http_reads, http_writes);
2416 socket_factory_.AddSocketDataProvider(&http_data);
2417 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2418
2419 // Quic connection will be retried on the alternate network after the initial
2420 // one fails on the default network.
2421 MockQuicData quic_data2;
2422 quic::QuicStreamOffset header_stream_offset = 0;
2423 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2424 quic_data2.AddWrite(SYNCHRONOUS,
2425 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2426
2427 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2428 quic_data2.AddWrite(SYNCHRONOUS,
2429 ConstructInitialSettingsPacket(2, &header_stream_offset));
2430 quic_data2.AddSocketDataToFactory(&socket_factory_);
2431
2432 // Resolve the host resolution synchronously.
2433 host_resolver_.set_synchronous_mode(true);
2434 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2435 "");
Zhongyi Shia6b68d112018-09-24 07:49:032436
2437 CreateSession();
2438 session_->quic_stream_factory()->set_require_confirmation(true);
2439 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2440 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2441 QuicStreamFactoryPeer::SetAlarmFactory(
2442 session_->quic_stream_factory(),
2443 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2444 &clock_));
2445 // Add alternate protocol mapping to race QUIC and TCP.
2446 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2447 // peer.
2448 AddQuicAlternateProtocolMapping(
2449 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2450
2451 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2452 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362453 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2455
2456 // Pump the message loop to get the request started.
2457 // Request will be served with TCP job.
2458 base::RunLoop().RunUntilIdle();
2459 EXPECT_THAT(callback.WaitForResult(), IsOk());
2460 CheckResponseData(&trans, "TCP succeeds");
2461
2462 // Fire the retransmission alarm, after which connection will idle
2463 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062464 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182465 quic_fix_time_of_first_packet_sent_after_receiving)) {
2466 quic_task_runner_->RunNextTask();
2467 }
Zhongyi Shia6b68d112018-09-24 07:49:032468 // Fast forward to idle timeout the original connection. A new connection will
2469 // be kicked off on the alternate network.
2470 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2471 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2472 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2473
2474 // The second connection hasn't finish handshake, verify that QUIC is not
2475 // marked as broken.
2476 ExpectQuicAlternateProtocolMapping();
2477 // Explicitly confirm the handshake on the second connection.
2478 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2479 quic::QuicSession::HANDSHAKE_CONFIRMED);
2480 // Run message loop to execute posted tasks, which will notify JoController
2481 // about the orphaned job status.
2482 base::RunLoop().RunUntilIdle();
2483
2484 // Verify that QUIC is marked as broken.
2485 ExpectBrokenAlternateProtocolMapping();
2486
2487 // Deliver a message to notify the new network becomes default, the previous
2488 // brokenness will be clear as the brokenness is bond with old default
2489 // network.
2490 scoped_mock_change_notifier_->mock_network_change_notifier()
2491 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2492 ExpectQuicAlternateProtocolMapping();
2493
2494 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2495 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2496}
2497
2498// This test verifies that a new QUIC connection will be attempted on the
2499// alternate network if the original QUIC connection fails with idle timeout
2500// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2501// alternative network succeeds, QUIC is not marked as broken.
2502TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Michael Warres167db3e2019-03-01 21:38:032503 if (version_ >= quic::QUIC_VERSION_47) {
2504 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2505 return;
2506 }
Zhongyi Shia6b68d112018-09-24 07:49:032507 SetUpTestForRetryConnectionOnAlternateNetwork();
2508
2509 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032510 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032511
2512 // The request will initially go out over QUIC.
2513 MockQuicData quic_data;
2514 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2515 int packet_num = 1;
2516 quic_data.AddWrite(SYNCHRONOUS,
2517 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2518 // Retranmit the handshake messages.
2519 quic_data.AddWrite(SYNCHRONOUS,
2520 client_maker_.MakeDummyCHLOPacket(packet_num++));
2521 quic_data.AddWrite(SYNCHRONOUS,
2522 client_maker_.MakeDummyCHLOPacket(packet_num++));
2523 quic_data.AddWrite(SYNCHRONOUS,
2524 client_maker_.MakeDummyCHLOPacket(packet_num++));
2525 quic_data.AddWrite(SYNCHRONOUS,
2526 client_maker_.MakeDummyCHLOPacket(packet_num++));
2527 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2528 // quic_fix_has_pending_crypto_data is introduced and enabled.
2529 if (version_ <= quic::QUIC_VERSION_39) {
2530 quic_data.AddWrite(SYNCHRONOUS,
2531 client_maker_.MakeDummyCHLOPacket(packet_num++));
2532 }
2533 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2534 quic_data.AddWrite(SYNCHRONOUS,
2535 client_maker_.MakeConnectionClosePacket(
2536 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2537 "No recent network activity."));
2538 quic_data.AddSocketDataToFactory(&socket_factory_);
2539
2540 // Add hanging TCP data so that TCP job will never succeeded.
2541 AddHangingNonAlternateProtocolSocketData();
2542
2543 // Quic connection will then be retried on the alternate network.
2544 MockQuicData quic_data2;
2545 quic::QuicStreamOffset header_stream_offset = 0;
2546 quic_data2.AddWrite(SYNCHRONOUS,
2547 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2548
Victor Vasiliev076657c2019-03-12 02:46:432549 const std::string body = "hello!";
2550 std::string header = ConstructDataHeader(body.length());
Renjief49758b2019-01-11 23:32:412551
Zhongyi Shia6b68d112018-09-24 07:49:032552 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2553 quic_data2.AddWrite(SYNCHRONOUS,
2554 ConstructInitialSettingsPacket(2, &header_stream_offset));
2555 quic_data2.AddWrite(
2556 SYNCHRONOUS,
2557 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332558 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032559 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032560 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332561 ASYNC, ConstructServerResponseHeadersPacket(
2562 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2563 GetResponseHeaders("200 OK")));
2564 quic_data2.AddRead(
2565 ASYNC, ConstructServerDataPacket(
2566 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412567 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032568 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2569 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2570 quic_data2.AddSocketDataToFactory(&socket_factory_);
2571
2572 // Resolve the host resolution synchronously.
2573 host_resolver_.set_synchronous_mode(true);
2574 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2575 "");
Zhongyi Shia6b68d112018-09-24 07:49:032576
2577 CreateSession();
2578 session_->quic_stream_factory()->set_require_confirmation(true);
2579 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2580 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2581 QuicStreamFactoryPeer::SetAlarmFactory(
2582 session_->quic_stream_factory(),
2583 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2584 &clock_));
2585 // Add alternate protocol mapping to race QUIC and TCP.
2586 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2587 // peer.
2588 AddQuicAlternateProtocolMapping(
2589 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2590
2591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2592 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362593 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2595
2596 // Pump the message loop to get the request started.
2597 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062598 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182599 quic_fix_time_of_first_packet_sent_after_receiving)) {
2600 quic_task_runner_->RunNextTask();
2601 }
Zhongyi Shia6b68d112018-09-24 07:49:032602
2603 // Fast forward to idle timeout the original connection. A new connection will
2604 // be kicked off on the alternate network.
2605 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2606 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2607 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2608
2609 // Verify that QUIC is not marked as broken.
2610 ExpectQuicAlternateProtocolMapping();
2611 // Explicitly confirm the handshake on the second connection.
2612 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2613 quic::QuicSession::HANDSHAKE_CONFIRMED);
2614
2615 // Read the response.
2616 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412617 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032618 // Verify that QUIC is not marked as broken.
2619 ExpectQuicAlternateProtocolMapping();
2620
2621 // Deliver a message to notify the new network becomes default.
2622 scoped_mock_change_notifier_->mock_network_change_notifier()
2623 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2624 ExpectQuicAlternateProtocolMapping();
2625 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2626 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2627}
2628
rch9ecde09b2017-04-08 00:18:232629// Verify that if a QUIC connection times out, the QuicHttpStream will
2630// return QUIC_PROTOCOL_ERROR.
2631TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482632 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412633 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232634
2635 // The request will initially go out over QUIC.
2636 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522637 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132638 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232639 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2640
2641 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032642 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432643 quic_data.AddWrite(SYNCHRONOUS,
2644 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332645 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2646 true, priority, GetRequestHeaders("GET", "https", "/"),
2647 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232648
2649 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522650 quic::QuicStreamOffset settings_offset = header_stream_offset;
2651 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432652 quic_data.AddWrite(SYNCHRONOUS,
2653 client_maker_.MakeInitialSettingsPacketAndSaveData(
2654 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232655 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092656 quic_data.AddWrite(SYNCHRONOUS,
2657 client_maker_.MakeDataPacket(
2658 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2659 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232660 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092661 quic_data.AddWrite(SYNCHRONOUS,
2662 client_maker_.MakeDataPacket(
2663 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2664 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232665 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092666 quic_data.AddWrite(SYNCHRONOUS,
2667 client_maker_.MakeDataPacket(
2668 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2669 false, 0, request_data));
2670 quic_data.AddWrite(SYNCHRONOUS,
2671 client_maker_.MakeDataPacket(
2672 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2673 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232674 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092675 quic_data.AddWrite(SYNCHRONOUS,
2676 client_maker_.MakeDataPacket(
2677 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2678 false, 0, request_data));
2679 quic_data.AddWrite(SYNCHRONOUS,
2680 client_maker_.MakeDataPacket(
2681 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2682 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232683 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092684 quic_data.AddWrite(SYNCHRONOUS,
2685 client_maker_.MakeDataPacket(
2686 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2687 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522688 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092689 SYNCHRONOUS, client_maker_.MakeDataPacket(
2690 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2691 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232692
Zhongyi Shi32f2fd02018-04-16 18:23:432693 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522694 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432695 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222696
rch9ecde09b2017-04-08 00:18:232697 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2698 quic_data.AddRead(ASYNC, OK);
2699 quic_data.AddSocketDataToFactory(&socket_factory_);
2700
2701 // In order for a new QUIC session to be established via alternate-protocol
2702 // without racing an HTTP connection, we need the host resolution to happen
2703 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2704 // connection to the the server, in this test we require confirmation
2705 // before encrypting so the HTTP job will still start.
2706 host_resolver_.set_synchronous_mode(true);
2707 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2708 "");
rch9ecde09b2017-04-08 00:18:232709
2710 CreateSession();
2711 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552712 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232713 QuicStreamFactoryPeer::SetAlarmFactory(
2714 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192715 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552716 &clock_));
rch9ecde09b2017-04-08 00:18:232717
Ryan Hamilton9835e662018-08-02 05:36:272718 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232719
2720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2721 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362722 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232723 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2724
2725 // Pump the message loop to get the request started.
2726 base::RunLoop().RunUntilIdle();
2727 // Explicitly confirm the handshake.
2728 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522729 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232730
2731 // Run the QUIC session to completion.
2732 quic_task_runner_->RunUntilIdle();
2733
2734 ExpectQuicAlternateProtocolMapping();
2735 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2736 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2737}
2738
2739// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2740// return QUIC_PROTOCOL_ERROR.
2741TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482742 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522743 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232744
2745 // The request will initially go out over QUIC.
2746 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522747 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132748 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232749 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2750
2751 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032752 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432753 quic_data.AddWrite(SYNCHRONOUS,
2754 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332755 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2756 true, priority, GetRequestHeaders("GET", "https", "/"),
2757 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232758
2759 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522760 quic::QuicStreamOffset settings_offset = header_stream_offset;
2761 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432762 quic_data.AddWrite(SYNCHRONOUS,
2763 client_maker_.MakeInitialSettingsPacketAndSaveData(
2764 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232765 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092766 quic_data.AddWrite(SYNCHRONOUS,
2767 client_maker_.MakeDataPacket(
2768 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2769 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232770 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092771 quic_data.AddWrite(SYNCHRONOUS,
2772 client_maker_.MakeDataPacket(
2773 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2774 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232775 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092776 quic_data.AddWrite(SYNCHRONOUS,
2777 client_maker_.MakeDataPacket(
2778 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2779 false, 0, request_data));
2780 quic_data.AddWrite(SYNCHRONOUS,
2781 client_maker_.MakeDataPacket(
2782 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2783 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232784 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092785 quic_data.AddWrite(SYNCHRONOUS,
2786 client_maker_.MakeDataPacket(
2787 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2788 false, 0, request_data));
2789 quic_data.AddWrite(SYNCHRONOUS,
2790 client_maker_.MakeDataPacket(
2791 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2792 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232793 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092794 quic_data.AddWrite(SYNCHRONOUS,
2795 client_maker_.MakeDataPacket(
2796 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2797 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522798 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092799 SYNCHRONOUS, client_maker_.MakeDataPacket(
2800 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2801 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232802 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522803 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092804 SYNCHRONOUS, client_maker_.MakeDataPacket(
2805 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2806 false, 0, request_data));
2807 quic_data.AddWrite(
2808 SYNCHRONOUS, client_maker_.MakeDataPacket(
2809 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2810 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232811 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432812 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522813 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432814 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232815
2816 quic_data.AddRead(ASYNC, OK);
2817 quic_data.AddSocketDataToFactory(&socket_factory_);
2818
2819 // In order for a new QUIC session to be established via alternate-protocol
2820 // without racing an HTTP connection, we need the host resolution to happen
2821 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2822 // connection to the the server, in this test we require confirmation
2823 // before encrypting so the HTTP job will still start.
2824 host_resolver_.set_synchronous_mode(true);
2825 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2826 "");
rch9ecde09b2017-04-08 00:18:232827
2828 CreateSession();
2829 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552830 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232831 QuicStreamFactoryPeer::SetAlarmFactory(
2832 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192833 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552834 &clock_));
rch9ecde09b2017-04-08 00:18:232835
Ryan Hamilton9835e662018-08-02 05:36:272836 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232837
2838 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2839 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362840 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2842
2843 // Pump the message loop to get the request started.
2844 base::RunLoop().RunUntilIdle();
2845 // Explicitly confirm the handshake.
2846 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522847 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232848
2849 // Run the QUIC session to completion.
2850 quic_task_runner_->RunUntilIdle();
2851
2852 ExpectQuicAlternateProtocolMapping();
2853 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2854 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2855}
2856
2857// Verify that if a QUIC connection RTOs, while there are no active streams
2858// QUIC will not be marked as broken.
2859TEST_P(QuicNetworkTransactionTest,
2860 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522861 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232862
2863 // The request will initially go out over QUIC.
2864 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522865 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132866 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232867 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2868
2869 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032870 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432871 quic_data.AddWrite(SYNCHRONOUS,
2872 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332873 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2874 true, priority, GetRequestHeaders("GET", "https", "/"),
2875 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232876
2877 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522878 quic::QuicStreamOffset settings_offset = header_stream_offset;
2879 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432880 quic_data.AddWrite(SYNCHRONOUS,
2881 client_maker_.MakeInitialSettingsPacketAndSaveData(
2882 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232883
Fan Yang32c5a112018-12-10 20:06:332884 quic_data.AddWrite(SYNCHRONOUS,
2885 client_maker_.MakeRstPacket(
2886 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2887 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232888 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092889 quic_data.AddWrite(SYNCHRONOUS,
2890 client_maker_.MakeDataPacket(
2891 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2892 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232893 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092894 quic_data.AddWrite(SYNCHRONOUS,
2895 client_maker_.MakeDataPacket(
2896 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2897 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232898 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332899 quic_data.AddWrite(SYNCHRONOUS,
2900 client_maker_.MakeRstPacket(
2901 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2902 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092903 quic_data.AddWrite(SYNCHRONOUS,
2904 client_maker_.MakeDataPacket(
2905 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2906 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232907 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092908 quic_data.AddWrite(SYNCHRONOUS,
2909 client_maker_.MakeDataPacket(
2910 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2911 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332912 quic_data.AddWrite(SYNCHRONOUS,
2913 client_maker_.MakeRstPacket(
2914 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2915 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232916 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522917 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092918 SYNCHRONOUS, client_maker_.MakeDataPacket(
2919 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2920 false, 0, request_data));
2921 quic_data.AddWrite(
2922 SYNCHRONOUS, client_maker_.MakeDataPacket(
2923 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2924 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232925 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432926 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332927 SYNCHRONOUS, client_maker_.MakeRstPacket(
2928 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2929 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522930 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092931 SYNCHRONOUS, client_maker_.MakeDataPacket(
2932 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2933 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232934 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432935 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522936 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432937 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232938
2939 quic_data.AddRead(ASYNC, OK);
2940 quic_data.AddSocketDataToFactory(&socket_factory_);
2941
2942 // In order for a new QUIC session to be established via alternate-protocol
2943 // without racing an HTTP connection, we need the host resolution to happen
2944 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2945 // connection to the the server, in this test we require confirmation
2946 // before encrypting so the HTTP job will still start.
2947 host_resolver_.set_synchronous_mode(true);
2948 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2949 "");
rch9ecde09b2017-04-08 00:18:232950
2951 CreateSession();
2952 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552953 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232954 QuicStreamFactoryPeer::SetAlarmFactory(
2955 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192956 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552957 &clock_));
rch9ecde09b2017-04-08 00:18:232958
Ryan Hamilton9835e662018-08-02 05:36:272959 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232960
Jeremy Roman0579ed62017-08-29 15:56:192961 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232962 session_.get());
2963 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362964 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232965 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2966
2967 // Pump the message loop to get the request started.
2968 base::RunLoop().RunUntilIdle();
2969 // Explicitly confirm the handshake.
2970 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522971 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232972
2973 // Now cancel the request.
2974 trans.reset();
2975
2976 // Run the QUIC session to completion.
2977 quic_task_runner_->RunUntilIdle();
2978
2979 ExpectQuicAlternateProtocolMapping();
2980
2981 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2982}
2983
rch2f2991c2017-04-13 19:28:172984// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2985// the request fails with QUIC_PROTOCOL_ERROR.
2986TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482987 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172988 // The request will initially go out over QUIC.
2989 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522990 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:032991 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:432992 quic_data.AddWrite(
2993 SYNCHRONOUS,
2994 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332995 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432996 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522997 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432998 quic_data.AddWrite(SYNCHRONOUS,
2999 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173000 // Peer sending data from an non-existing stream causes this end to raise
3001 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333002 quic_data.AddRead(
3003 ASYNC, ConstructServerRstPacket(
3004 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3005 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173006 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433007 quic_data.AddWrite(SYNCHRONOUS,
3008 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523009 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3010 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173011 quic_data.AddSocketDataToFactory(&socket_factory_);
3012
3013 // In order for a new QUIC session to be established via alternate-protocol
3014 // without racing an HTTP connection, we need the host resolution to happen
3015 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3016 // connection to the the server, in this test we require confirmation
3017 // before encrypting so the HTTP job will still start.
3018 host_resolver_.set_synchronous_mode(true);
3019 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3020 "");
rch2f2991c2017-04-13 19:28:173021
3022 CreateSession();
3023
Ryan Hamilton9835e662018-08-02 05:36:273024 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173025
3026 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3027 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363028 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3030
3031 // Pump the message loop to get the request started.
3032 base::RunLoop().RunUntilIdle();
3033 // Explicitly confirm the handshake.
3034 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523035 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173036
3037 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3038
3039 // Run the QUIC session to completion.
3040 base::RunLoop().RunUntilIdle();
3041 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3042 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3043
3044 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3045 ExpectQuicAlternateProtocolMapping();
3046 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3047}
3048
rch9ecde09b2017-04-08 00:18:233049// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3050// connection times out, then QUIC will be marked as broken and the request
3051// retried over TCP.
3052TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413053 session_params_.mark_quic_broken_when_network_blackholes = true;
3054 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233055
3056 // The request will initially go out over QUIC.
3057 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523058 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133059 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233060 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3061
3062 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033063 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433064 quic_data.AddWrite(SYNCHRONOUS,
3065 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333066 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3067 true, priority, GetRequestHeaders("GET", "https", "/"),
3068 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233069
3070 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523071 quic::QuicStreamOffset settings_offset = header_stream_offset;
3072 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433073 quic_data.AddWrite(SYNCHRONOUS,
3074 client_maker_.MakeInitialSettingsPacketAndSaveData(
3075 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233076 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093077 quic_data.AddWrite(SYNCHRONOUS,
3078 client_maker_.MakeDataPacket(
3079 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3080 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233081 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093082 quic_data.AddWrite(SYNCHRONOUS,
3083 client_maker_.MakeDataPacket(
3084 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3085 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233086 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093087 quic_data.AddWrite(SYNCHRONOUS,
3088 client_maker_.MakeDataPacket(
3089 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3090 false, 0, request_data));
3091 quic_data.AddWrite(SYNCHRONOUS,
3092 client_maker_.MakeDataPacket(
3093 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3094 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233095 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093096 quic_data.AddWrite(SYNCHRONOUS,
3097 client_maker_.MakeDataPacket(
3098 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3099 false, 0, request_data));
3100 quic_data.AddWrite(SYNCHRONOUS,
3101 client_maker_.MakeDataPacket(
3102 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3103 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233104 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093105 quic_data.AddWrite(SYNCHRONOUS,
3106 client_maker_.MakeDataPacket(
3107 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3108 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523109 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093110 SYNCHRONOUS, client_maker_.MakeDataPacket(
3111 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3112 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233113
Zhongyi Shi32f2fd02018-04-16 18:23:433114 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523115 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433116 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223117
rch9ecde09b2017-04-08 00:18:233118 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3119 quic_data.AddRead(ASYNC, OK);
3120 quic_data.AddSocketDataToFactory(&socket_factory_);
3121
3122 // After that fails, it will be resent via TCP.
3123 MockWrite http_writes[] = {
3124 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3125 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3126 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3127
3128 MockRead http_reads[] = {
3129 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3130 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3131 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013132 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233133 socket_factory_.AddSocketDataProvider(&http_data);
3134 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3135
3136 // In order for a new QUIC session to be established via alternate-protocol
3137 // without racing an HTTP connection, we need the host resolution to happen
3138 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3139 // connection to the the server, in this test we require confirmation
3140 // before encrypting so the HTTP job will still start.
3141 host_resolver_.set_synchronous_mode(true);
3142 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3143 "");
rch9ecde09b2017-04-08 00:18:233144
3145 CreateSession();
3146 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553147 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233148 QuicStreamFactoryPeer::SetAlarmFactory(
3149 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193150 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553151 &clock_));
rch9ecde09b2017-04-08 00:18:233152
Ryan Hamilton9835e662018-08-02 05:36:273153 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233154
3155 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3156 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363157 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3159
3160 // Pump the message loop to get the request started.
3161 base::RunLoop().RunUntilIdle();
3162 // Explicitly confirm the handshake.
3163 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523164 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233165
3166 // Run the QUIC session to completion.
3167 quic_task_runner_->RunUntilIdle();
3168 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3169
3170 // Let the transaction proceed which will result in QUIC being marked
3171 // as broken and the request falling back to TCP.
3172 EXPECT_THAT(callback.WaitForResult(), IsOk());
3173
3174 ExpectBrokenAlternateProtocolMapping();
3175 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3176 ASSERT_FALSE(http_data.AllReadDataConsumed());
3177
3178 // Read the response body over TCP.
3179 CheckResponseData(&trans, "hello world");
3180 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3181 ASSERT_TRUE(http_data.AllReadDataConsumed());
3182}
3183
rch2f2991c2017-04-13 19:28:173184// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3185// connection times out, then QUIC will be marked as broken and the request
3186// retried over TCP.
3187TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413188 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173189
3190 // The request will initially go out over QUIC.
3191 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523192 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133193 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173194 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3195
3196 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033197 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433198 quic_data.AddWrite(SYNCHRONOUS,
3199 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333200 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3201 true, priority, GetRequestHeaders("GET", "https", "/"),
3202 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173203
3204 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523205 quic::QuicStreamOffset settings_offset = header_stream_offset;
3206 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433207 quic_data.AddWrite(SYNCHRONOUS,
3208 client_maker_.MakeInitialSettingsPacketAndSaveData(
3209 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173210 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093211 quic_data.AddWrite(SYNCHRONOUS,
3212 client_maker_.MakeDataPacket(
3213 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3214 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173215 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093216 quic_data.AddWrite(SYNCHRONOUS,
3217 client_maker_.MakeDataPacket(
3218 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3219 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173220 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093221 quic_data.AddWrite(SYNCHRONOUS,
3222 client_maker_.MakeDataPacket(
3223 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3224 false, 0, request_data));
3225 quic_data.AddWrite(SYNCHRONOUS,
3226 client_maker_.MakeDataPacket(
3227 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3228 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173229 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093230 quic_data.AddWrite(SYNCHRONOUS,
3231 client_maker_.MakeDataPacket(
3232 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3233 false, 0, request_data));
3234 quic_data.AddWrite(SYNCHRONOUS,
3235 client_maker_.MakeDataPacket(
3236 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3237 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173238 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093239 quic_data.AddWrite(SYNCHRONOUS,
3240 client_maker_.MakeDataPacket(
3241 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3242 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523243 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093244 SYNCHRONOUS, client_maker_.MakeDataPacket(
3245 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3246 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173247
Zhongyi Shi32f2fd02018-04-16 18:23:433248 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523249 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433250 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223251
rch2f2991c2017-04-13 19:28:173252 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3253 quic_data.AddRead(ASYNC, OK);
3254 quic_data.AddSocketDataToFactory(&socket_factory_);
3255
3256 // After that fails, it will be resent via TCP.
3257 MockWrite http_writes[] = {
3258 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3259 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3260 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3261
3262 MockRead http_reads[] = {
3263 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3264 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3265 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013266 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173267 socket_factory_.AddSocketDataProvider(&http_data);
3268 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3269
3270 // In order for a new QUIC session to be established via alternate-protocol
3271 // without racing an HTTP connection, we need the host resolution to happen
3272 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3273 // connection to the the server, in this test we require confirmation
3274 // before encrypting so the HTTP job will still start.
3275 host_resolver_.set_synchronous_mode(true);
3276 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3277 "");
rch2f2991c2017-04-13 19:28:173278
3279 CreateSession();
3280 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553281 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173282 QuicStreamFactoryPeer::SetAlarmFactory(
3283 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193284 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553285 &clock_));
rch2f2991c2017-04-13 19:28:173286
Ryan Hamilton9835e662018-08-02 05:36:273287 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173288
3289 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3290 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363291 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173292 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3293
3294 // Pump the message loop to get the request started.
3295 base::RunLoop().RunUntilIdle();
3296 // Explicitly confirm the handshake.
3297 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523298 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173299
3300 // Run the QUIC session to completion.
3301 quic_task_runner_->RunUntilIdle();
3302 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3303
3304 ExpectQuicAlternateProtocolMapping();
3305
3306 // Let the transaction proceed which will result in QUIC being marked
3307 // as broken and the request falling back to TCP.
3308 EXPECT_THAT(callback.WaitForResult(), IsOk());
3309
3310 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3311 ASSERT_FALSE(http_data.AllReadDataConsumed());
3312
3313 // Read the response body over TCP.
3314 CheckResponseData(&trans, "hello world");
3315 ExpectBrokenAlternateProtocolMapping();
3316 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3317 ASSERT_TRUE(http_data.AllReadDataConsumed());
3318}
3319
rch9ecde09b2017-04-08 00:18:233320// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3321// connection times out, then QUIC will be marked as broken but the request
3322// will not be retried over TCP.
3323TEST_P(QuicNetworkTransactionTest,
3324 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413325 session_params_.mark_quic_broken_when_network_blackholes = true;
3326 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233327
3328 // The request will initially go out over QUIC.
3329 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523330 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133331 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233332 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3333
3334 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033335 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433336 quic_data.AddWrite(SYNCHRONOUS,
3337 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333338 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3339 true, priority, GetRequestHeaders("GET", "https", "/"),
3340 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233341
3342 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523343 quic::QuicStreamOffset settings_offset = header_stream_offset;
3344 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433345 quic_data.AddWrite(SYNCHRONOUS,
3346 client_maker_.MakeInitialSettingsPacketAndSaveData(
3347 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233348
Zhongyi Shi32f2fd02018-04-16 18:23:433349 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333350 1, GetNthClientInitiatedBidirectionalStreamId(0),
3351 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433352 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523353 quic_data.AddWrite(
3354 SYNCHRONOUS,
3355 ConstructClientAckPacket(3, 1, 1, 1,
3356 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233357
3358 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523359 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093360 SYNCHRONOUS, client_maker_.MakeDataPacket(
3361 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3362 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233363 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093364 quic_data.AddWrite(
3365 SYNCHRONOUS, client_maker_.MakeDataPacket(
3366 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3367 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233368 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523369 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093370 SYNCHRONOUS, client_maker_.MakeDataPacket(
3371 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3372 false, 0, request_data));
3373 quic_data.AddWrite(
3374 SYNCHRONOUS, client_maker_.MakeDataPacket(
3375 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3376 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233377 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523378 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093379 SYNCHRONOUS, client_maker_.MakeDataPacket(
3380 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3381 false, 0, request_data));
3382 quic_data.AddWrite(
3383 SYNCHRONOUS, client_maker_.MakeDataPacket(
3384 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3385 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233386 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523387 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093388 SYNCHRONOUS, client_maker_.MakeDataPacket(
3389 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3390 false, 0, request_data));
3391 quic_data.AddWrite(
3392 SYNCHRONOUS, client_maker_.MakeDataPacket(
3393 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3394 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233395
Michael Warres112212822018-12-26 17:51:063396 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183397 quic_fix_time_of_first_packet_sent_after_receiving)) {
3398 quic_data.AddWrite(
3399 SYNCHRONOUS,
3400 client_maker_.MakeAckAndConnectionClosePacket(
3401 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3402 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3403
3404 } else {
3405 quic_data.AddWrite(
3406 SYNCHRONOUS,
3407 client_maker_.MakeAckAndConnectionClosePacket(
3408 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3409 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3410 }
Fan Yang928f1632017-12-14 18:55:223411
rch9ecde09b2017-04-08 00:18:233412 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3413 quic_data.AddRead(ASYNC, OK);
3414 quic_data.AddSocketDataToFactory(&socket_factory_);
3415
3416 // In order for a new QUIC session to be established via alternate-protocol
3417 // without racing an HTTP connection, we need the host resolution to happen
3418 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3419 // connection to the the server, in this test we require confirmation
3420 // before encrypting so the HTTP job will still start.
3421 host_resolver_.set_synchronous_mode(true);
3422 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3423 "");
rch9ecde09b2017-04-08 00:18:233424
3425 CreateSession();
3426 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553427 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233428 QuicStreamFactoryPeer::SetAlarmFactory(
3429 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193430 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553431 &clock_));
rch9ecde09b2017-04-08 00:18:233432
Ryan Hamilton9835e662018-08-02 05:36:273433 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233434
3435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3436 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363437 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3439
3440 // Pump the message loop to get the request started.
3441 base::RunLoop().RunUntilIdle();
3442 // Explicitly confirm the handshake.
3443 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523444 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233445
3446 // Pump the message loop to get the request started.
3447 base::RunLoop().RunUntilIdle();
3448
3449 // Run the QUIC session to completion.
3450 quic_task_runner_->RunUntilIdle();
3451 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3452
3453 // Let the transaction proceed which will result in QUIC being marked
3454 // as broken and the request falling back to TCP.
3455 EXPECT_THAT(callback.WaitForResult(), IsOk());
3456
3457 ExpectBrokenAlternateProtocolMapping();
3458 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3459
3460 std::string response_data;
3461 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3462 IsError(ERR_QUIC_PROTOCOL_ERROR));
3463}
3464
3465// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3466// connection RTOs, then QUIC will be marked as broken and the request retried
3467// over TCP.
3468TEST_P(QuicNetworkTransactionTest,
3469 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413470 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523471 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233472
3473 // The request will initially go out over QUIC.
3474 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523475 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133476 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233477 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3478
3479 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033480 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433481 quic_data.AddWrite(SYNCHRONOUS,
3482 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333483 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3484 true, priority, GetRequestHeaders("GET", "https", "/"),
3485 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233486
3487 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523488 quic::QuicStreamOffset settings_offset = header_stream_offset;
3489 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433490 quic_data.AddWrite(SYNCHRONOUS,
3491 client_maker_.MakeInitialSettingsPacketAndSaveData(
3492 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233493 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093494 quic_data.AddWrite(SYNCHRONOUS,
3495 client_maker_.MakeDataPacket(
3496 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3497 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233498 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093499 quic_data.AddWrite(SYNCHRONOUS,
3500 client_maker_.MakeDataPacket(
3501 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3502 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233503 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093504 quic_data.AddWrite(SYNCHRONOUS,
3505 client_maker_.MakeDataPacket(
3506 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3507 false, 0, request_data));
3508 quic_data.AddWrite(SYNCHRONOUS,
3509 client_maker_.MakeDataPacket(
3510 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3511 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233512 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093513 quic_data.AddWrite(SYNCHRONOUS,
3514 client_maker_.MakeDataPacket(
3515 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3516 false, 0, request_data));
3517 quic_data.AddWrite(SYNCHRONOUS,
3518 client_maker_.MakeDataPacket(
3519 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3520 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233521 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093522 quic_data.AddWrite(SYNCHRONOUS,
3523 client_maker_.MakeDataPacket(
3524 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3525 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523526 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093527 SYNCHRONOUS, client_maker_.MakeDataPacket(
3528 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3529 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233530 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523531 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093532 SYNCHRONOUS, client_maker_.MakeDataPacket(
3533 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3534 false, 0, request_data));
3535 quic_data.AddWrite(
3536 SYNCHRONOUS, client_maker_.MakeDataPacket(
3537 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3538 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233539
Zhongyi Shi32f2fd02018-04-16 18:23:433540 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523541 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433542 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233543
3544 quic_data.AddRead(ASYNC, OK);
3545 quic_data.AddSocketDataToFactory(&socket_factory_);
3546
3547 // After that fails, it will be resent via TCP.
3548 MockWrite http_writes[] = {
3549 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3550 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3551 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3552
3553 MockRead http_reads[] = {
3554 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3555 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3556 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013557 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233558 socket_factory_.AddSocketDataProvider(&http_data);
3559 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3560
3561 // In order for a new QUIC session to be established via alternate-protocol
3562 // without racing an HTTP connection, we need the host resolution to happen
3563 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3564 // connection to the the server, in this test we require confirmation
3565 // before encrypting so the HTTP job will still start.
3566 host_resolver_.set_synchronous_mode(true);
3567 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3568 "");
rch9ecde09b2017-04-08 00:18:233569
3570 CreateSession();
3571 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553572 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233573 QuicStreamFactoryPeer::SetAlarmFactory(
3574 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193575 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553576 &clock_));
rch9ecde09b2017-04-08 00:18:233577
Ryan Hamilton9835e662018-08-02 05:36:273578 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233579
3580 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3581 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363582 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3584
3585 // Pump the message loop to get the request started.
3586 base::RunLoop().RunUntilIdle();
3587 // Explicitly confirm the handshake.
3588 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523589 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233590
3591 // Run the QUIC session to completion.
3592 quic_task_runner_->RunUntilIdle();
3593 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3594
3595 // Let the transaction proceed which will result in QUIC being marked
3596 // as broken and the request falling back to TCP.
3597 EXPECT_THAT(callback.WaitForResult(), IsOk());
3598
3599 ExpectBrokenAlternateProtocolMapping();
3600 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3601 ASSERT_FALSE(http_data.AllReadDataConsumed());
3602
3603 // Read the response body over TCP.
3604 CheckResponseData(&trans, "hello world");
3605 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3606 ASSERT_TRUE(http_data.AllReadDataConsumed());
3607}
3608
3609// Verify that if a QUIC connection RTOs, while there are no active streams
3610// QUIC will be marked as broken.
3611TEST_P(QuicNetworkTransactionTest,
3612 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413613 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523614 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233615
3616 // The request will initially go out over QUIC.
3617 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523618 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133619 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233620 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3621
3622 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033623 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433624 quic_data.AddWrite(SYNCHRONOUS,
3625 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333626 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3627 true, priority, GetRequestHeaders("GET", "https", "/"),
3628 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233629
3630 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523631 quic::QuicStreamOffset settings_offset = header_stream_offset;
3632 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433633 quic_data.AddWrite(SYNCHRONOUS,
3634 client_maker_.MakeInitialSettingsPacketAndSaveData(
3635 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233636
Fan Yang32c5a112018-12-10 20:06:333637 quic_data.AddWrite(SYNCHRONOUS,
3638 client_maker_.MakeRstPacket(
3639 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3640 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233641 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093642 quic_data.AddWrite(SYNCHRONOUS,
3643 client_maker_.MakeDataPacket(
3644 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3645 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233646 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093647 quic_data.AddWrite(SYNCHRONOUS,
3648 client_maker_.MakeDataPacket(
3649 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3650 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233651 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333652 quic_data.AddWrite(SYNCHRONOUS,
3653 client_maker_.MakeRstPacket(
3654 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3655 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093656 quic_data.AddWrite(SYNCHRONOUS,
3657 client_maker_.MakeDataPacket(
3658 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3659 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233660 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093661 quic_data.AddWrite(SYNCHRONOUS,
3662 client_maker_.MakeDataPacket(
3663 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3664 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333665 quic_data.AddWrite(SYNCHRONOUS,
3666 client_maker_.MakeRstPacket(
3667 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3668 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233669 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523670 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093671 SYNCHRONOUS, client_maker_.MakeDataPacket(
3672 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3673 false, 0, request_data));
3674 quic_data.AddWrite(
3675 SYNCHRONOUS, client_maker_.MakeDataPacket(
3676 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3677 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233678 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433679 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333680 SYNCHRONOUS, client_maker_.MakeRstPacket(
3681 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3682 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523683 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093684 SYNCHRONOUS, client_maker_.MakeDataPacket(
3685 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3686 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233687 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433688 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523689 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433690 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233691
3692 quic_data.AddRead(ASYNC, OK);
3693 quic_data.AddSocketDataToFactory(&socket_factory_);
3694
3695 // In order for a new QUIC session to be established via alternate-protocol
3696 // without racing an HTTP connection, we need the host resolution to happen
3697 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3698 // connection to the the server, in this test we require confirmation
3699 // before encrypting so the HTTP job will still start.
3700 host_resolver_.set_synchronous_mode(true);
3701 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3702 "");
rch9ecde09b2017-04-08 00:18:233703
3704 CreateSession();
3705 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553706 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233707 QuicStreamFactoryPeer::SetAlarmFactory(
3708 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193709 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553710 &clock_));
rch9ecde09b2017-04-08 00:18:233711
Ryan Hamilton9835e662018-08-02 05:36:273712 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233713
Jeremy Roman0579ed62017-08-29 15:56:193714 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233715 session_.get());
3716 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363717 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3719
3720 // Pump the message loop to get the request started.
3721 base::RunLoop().RunUntilIdle();
3722 // Explicitly confirm the handshake.
3723 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523724 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233725
3726 // Now cancel the request.
3727 trans.reset();
3728
3729 // Run the QUIC session to completion.
3730 quic_task_runner_->RunUntilIdle();
3731
3732 ExpectBrokenAlternateProtocolMapping();
3733
3734 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3735}
3736
rch2f2991c2017-04-13 19:28:173737// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3738// protocol error occurs after the handshake is confirmed, the request
3739// retried over TCP and the QUIC will be marked as broken.
3740TEST_P(QuicNetworkTransactionTest,
3741 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413742 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173743
3744 // The request will initially go out over QUIC.
3745 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523746 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033747 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433748 quic_data.AddWrite(
3749 SYNCHRONOUS,
3750 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333751 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433752 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523753 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433754 quic_data.AddWrite(SYNCHRONOUS,
3755 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173756 // Peer sending data from an non-existing stream causes this end to raise
3757 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333758 quic_data.AddRead(
3759 ASYNC, ConstructServerRstPacket(
3760 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3761 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173762 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433763 quic_data.AddWrite(SYNCHRONOUS,
3764 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523765 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3766 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173767 quic_data.AddSocketDataToFactory(&socket_factory_);
3768
3769 // After that fails, it will be resent via TCP.
3770 MockWrite http_writes[] = {
3771 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3772 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3773 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3774
3775 MockRead http_reads[] = {
3776 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3777 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3778 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013779 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173780 socket_factory_.AddSocketDataProvider(&http_data);
3781 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3782
3783 // In order for a new QUIC session to be established via alternate-protocol
3784 // without racing an HTTP connection, we need the host resolution to happen
3785 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3786 // connection to the the server, in this test we require confirmation
3787 // before encrypting so the HTTP job will still start.
3788 host_resolver_.set_synchronous_mode(true);
3789 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3790 "");
rch2f2991c2017-04-13 19:28:173791
3792 CreateSession();
3793
Ryan Hamilton9835e662018-08-02 05:36:273794 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173795
3796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3797 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363798 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3800
3801 // Pump the message loop to get the request started.
3802 base::RunLoop().RunUntilIdle();
3803 // Explicitly confirm the handshake.
3804 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523805 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173806
3807 // Run the QUIC session to completion.
3808 base::RunLoop().RunUntilIdle();
3809 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3810
3811 ExpectQuicAlternateProtocolMapping();
3812
3813 // Let the transaction proceed which will result in QUIC being marked
3814 // as broken and the request falling back to TCP.
3815 EXPECT_THAT(callback.WaitForResult(), IsOk());
3816
3817 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3818 ASSERT_FALSE(http_data.AllReadDataConsumed());
3819
3820 // Read the response body over TCP.
3821 CheckResponseData(&trans, "hello world");
3822 ExpectBrokenAlternateProtocolMapping();
3823 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3824 ASSERT_TRUE(http_data.AllReadDataConsumed());
3825}
3826
rch30943ee2017-06-12 21:28:443827// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3828// request is reset from, then QUIC will be marked as broken and the request
3829// retried over TCP.
3830TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443831 // The request will initially go out over QUIC.
3832 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523833 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133834 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443835 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3836
3837 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033838 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:433839 quic_data.AddWrite(SYNCHRONOUS,
3840 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333841 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3842 true, priority, GetRequestHeaders("GET", "https", "/"),
3843 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443844
3845 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523846 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3847 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433848 quic_data.AddWrite(SYNCHRONOUS,
3849 client_maker_.MakeInitialSettingsPacketAndSaveData(
3850 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443851
Fan Yang32c5a112018-12-10 20:06:333852 quic_data.AddRead(ASYNC,
3853 ConstructServerRstPacket(
3854 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3855 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443856
3857 quic_data.AddRead(ASYNC, OK);
3858 quic_data.AddSocketDataToFactory(&socket_factory_);
3859
3860 // After that fails, it will be resent via TCP.
3861 MockWrite http_writes[] = {
3862 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3863 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3864 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3865
3866 MockRead http_reads[] = {
3867 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3868 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3869 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013870 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443871 socket_factory_.AddSocketDataProvider(&http_data);
3872 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3873
3874 // In order for a new QUIC session to be established via alternate-protocol
3875 // without racing an HTTP connection, we need the host resolution to happen
3876 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3877 // connection to the the server, in this test we require confirmation
3878 // before encrypting so the HTTP job will still start.
3879 host_resolver_.set_synchronous_mode(true);
3880 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3881 "");
rch30943ee2017-06-12 21:28:443882
3883 CreateSession();
3884
Ryan Hamilton9835e662018-08-02 05:36:273885 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443886
3887 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3888 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363889 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3891
3892 // Pump the message loop to get the request started.
3893 base::RunLoop().RunUntilIdle();
3894 // Explicitly confirm the handshake.
3895 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523896 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443897
3898 // Run the QUIC session to completion.
3899 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3900
3901 ExpectQuicAlternateProtocolMapping();
3902
3903 // Let the transaction proceed which will result in QUIC being marked
3904 // as broken and the request falling back to TCP.
3905 EXPECT_THAT(callback.WaitForResult(), IsOk());
3906
3907 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3908 ASSERT_FALSE(http_data.AllReadDataConsumed());
3909
3910 // Read the response body over TCP.
3911 CheckResponseData(&trans, "hello world");
3912 ExpectBrokenAlternateProtocolMapping();
3913 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3914 ASSERT_TRUE(http_data.AllReadDataConsumed());
3915}
3916
Ryan Hamilton6c2a2a82017-12-15 02:06:283917// Verify that when an origin has two alt-svc advertisements, one local and one
3918// remote, that when the local is broken the request will go over QUIC via
3919// the remote Alt-Svc.
3920// This is a regression test for crbug/825646.
3921TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3922 session_params_.quic_allow_remote_alt_svc = true;
3923
3924 GURL origin1 = request_.url; // mail.example.org
3925 GURL origin2("https://www.example.org/");
3926 ASSERT_NE(origin1.host(), origin2.host());
3927
3928 scoped_refptr<X509Certificate> cert(
3929 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243930 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3931 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283932
3933 ProofVerifyDetailsChromium verify_details;
3934 verify_details.cert_verify_result.verified_cert = cert;
3935 verify_details.cert_verify_result.is_issued_by_known_root = true;
3936 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3937
3938 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523939 quic::QuicStreamOffset request_header_offset(0);
3940 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283941 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433942 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3943 mock_quic_data.AddWrite(
3944 SYNCHRONOUS,
3945 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333946 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433947 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3948 mock_quic_data.AddRead(
3949 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333950 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433951 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:433952 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433953 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333954 ASYNC, ConstructServerDataPacket(
3955 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:413956 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433957 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283958 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3959 mock_quic_data.AddRead(ASYNC, 0); // EOF
3960
3961 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3962 MockQuicData mock_quic_data2;
3963 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3964 AddHangingNonAlternateProtocolSocketData();
3965
3966 CreateSession();
3967
3968 // Set up alternative service for |origin1|.
3969 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3970 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3971 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3972 AlternativeServiceInfoVector alternative_services;
3973 alternative_services.push_back(
3974 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3975 local_alternative, expiration,
3976 session_->params().quic_supported_versions));
3977 alternative_services.push_back(
3978 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3979 remote_alternative, expiration,
3980 session_->params().quic_supported_versions));
3981 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3982 alternative_services);
3983
3984 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3985
3986 SendRequestAndExpectQuicResponse("hello!");
3987}
3988
rch30943ee2017-06-12 21:28:443989// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3990// request is reset from, then QUIC will be marked as broken and the request
3991// retried over TCP. Then, subsequent requests will go over a new QUIC
3992// connection instead of going back to the broken QUIC connection.
3993// This is a regression tests for crbug/731303.
3994TEST_P(QuicNetworkTransactionTest,
3995 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:343996 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443997
3998 GURL origin1 = request_.url;
3999 GURL origin2("https://www.example.org/");
4000 ASSERT_NE(origin1.host(), origin2.host());
4001
4002 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524003 quic::QuicStreamOffset request_header_offset(0);
4004 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444005
4006 scoped_refptr<X509Certificate> cert(
4007 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244008 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4009 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444010
4011 ProofVerifyDetailsChromium verify_details;
4012 verify_details.cert_verify_result.verified_cert = cert;
4013 verify_details.cert_verify_result.is_issued_by_known_root = true;
4014 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4015
4016 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434017 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444018 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434019 mock_quic_data.AddWrite(
4020 SYNCHRONOUS,
4021 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334022 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434023 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4024 mock_quic_data.AddRead(
4025 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334026 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434027 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434028 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434029 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334030 ASYNC, ConstructServerDataPacket(
4031 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414032 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434033 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444034
4035 // Second request will go over the pooled QUIC connection, but will be
4036 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054037 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174038 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4039 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054040 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174041 QuicTestPacketMaker server_maker2(
4042 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4043 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434044 mock_quic_data.AddWrite(
4045 SYNCHRONOUS,
4046 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334047 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434048 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334049 GetNthClientInitiatedBidirectionalStreamId(0),
4050 &request_header_offset));
4051 mock_quic_data.AddRead(
4052 ASYNC, ConstructServerRstPacket(
4053 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4054 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444055 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4056 mock_quic_data.AddRead(ASYNC, 0); // EOF
4057
4058 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4059
4060 // After that fails, it will be resent via TCP.
4061 MockWrite http_writes[] = {
4062 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4063 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4064 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4065
4066 MockRead http_reads[] = {
4067 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4068 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4069 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014070 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444071 socket_factory_.AddSocketDataProvider(&http_data);
4072 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4073
Ryan Hamilton6c2a2a82017-12-15 02:06:284074 // Then the next request to the second origin will be sent over TCP.
4075 socket_factory_.AddSocketDataProvider(&http_data);
4076 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444077
4078 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564079 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4080 QuicStreamFactoryPeer::SetAlarmFactory(
4081 session_->quic_stream_factory(),
4082 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4083 &clock_));
rch30943ee2017-06-12 21:28:444084
4085 // Set up alternative service for |origin1|.
4086 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244087 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214088 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244089 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444090 supported_versions_);
rch30943ee2017-06-12 21:28:444091
4092 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244093 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214094 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244095 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444096 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344097
rch30943ee2017-06-12 21:28:444098 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524099 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444100 SendRequestAndExpectQuicResponse("hello!");
4101
4102 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524103 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444104 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4105 request_.url = origin2;
4106 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284107 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244108 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284109 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244110 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444111
4112 // The third request should use a new QUIC connection, not the broken
4113 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284114 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444115}
4116
bnc8be55ebb2015-10-30 14:12:074117TEST_P(QuicNetworkTransactionTest,
4118 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4119 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444120 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074121 MockRead http_reads[] = {
4122 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4123 MockRead("hello world"),
4124 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4125 MockRead(ASYNC, OK)};
4126
Ryan Sleevib8d7ea02018-05-07 20:01:014127 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074128 socket_factory_.AddSocketDataProvider(&http_data);
4129 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4130 socket_factory_.AddSocketDataProvider(&http_data);
4131 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4132
rch3f4b8452016-02-23 16:59:324133 CreateSession();
bnc8be55ebb2015-10-30 14:12:074134
4135 SendRequestAndExpectHttpResponse("hello world");
4136 SendRequestAndExpectHttpResponse("hello world");
4137}
4138
Xida Chen9bfe0b62018-04-24 19:52:214139// When multiple alternative services are advertised, HttpStreamFactory should
4140// select the alternative service which uses existing QUIC session if available.
4141// If no existing QUIC session can be used, use the first alternative service
4142// from the list.
zhongyi32569c62016-01-08 02:54:304143TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344144 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524145 MockRead http_reads[] = {
4146 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294147 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524148 MockRead("hello world"),
4149 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4150 MockRead(ASYNC, OK)};
4151
Ryan Sleevib8d7ea02018-05-07 20:01:014152 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524153 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084154 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564155 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524156
Ryan Hamilton8d9ee76e2018-05-29 23:52:524157 quic::QuicStreamOffset request_header_offset = 0;
4158 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304159 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294160 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304161 // alternative service list.
bncc958faa2015-07-31 18:14:524162 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364163 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434164 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4165 mock_quic_data.AddWrite(
4166 SYNCHRONOUS,
4167 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334168 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434169 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304170
4171 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294172 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4173 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434174 mock_quic_data.AddRead(
4175 ASYNC,
4176 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334177 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434178 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434179 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434180 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334181 ASYNC, ConstructServerDataPacket(
4182 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414183 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434184 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304185
4186 // Second QUIC request data.
4187 // Connection pooling, using existing session, no need to include version
4188 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584189 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334190 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4191 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4192 true, GetRequestHeaders("GET", "https", "/"),
4193 GetNthClientInitiatedBidirectionalStreamId(0),
4194 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434195 mock_quic_data.AddRead(
4196 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334197 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434198 GetResponseHeaders("200 OK"), &response_header_offset));
4199 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334200 ASYNC, ConstructServerDataPacket(
4201 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414202 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434203 mock_quic_data.AddWrite(
4204 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524205 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594206 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524207
4208 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4209
rtennetib8e80fb2016-05-16 00:12:094210 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324211 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564212 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4213 QuicStreamFactoryPeer::SetAlarmFactory(
4214 session_->quic_stream_factory(),
4215 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4216 &clock_));
bncc958faa2015-07-31 18:14:524217
4218 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304219
bnc359ed2a2016-04-29 20:43:454220 SendRequestAndExpectQuicResponse("hello!");
4221 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304222}
4223
tbansal6490783c2016-09-20 17:55:274224// Check that an existing QUIC connection to an alternative proxy server is
4225// used.
4226TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4227 base::HistogramTester histogram_tester;
4228
Ryan Hamilton8d9ee76e2018-05-29 23:52:524229 quic::QuicStreamOffset request_header_offset = 0;
4230 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274231 // First QUIC request data.
4232 // Open a session to foo.example.org:443 using the first entry of the
4233 // alternative service list.
4234 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364235 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434236 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4237 mock_quic_data.AddWrite(
4238 SYNCHRONOUS,
4239 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334240 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434241 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274242
4243 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434244 mock_quic_data.AddRead(
4245 ASYNC,
4246 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334247 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434248 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434249 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434250 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334251 ASYNC, ConstructServerDataPacket(
4252 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414253 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434254 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274255
4256 // Second QUIC request data.
4257 // Connection pooling, using existing session, no need to include version
4258 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274259 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334260 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4261 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4262 true, GetRequestHeaders("GET", "http", "/"),
4263 GetNthClientInitiatedBidirectionalStreamId(0),
4264 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434265 mock_quic_data.AddRead(
4266 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334267 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434268 GetResponseHeaders("200 OK"), &response_header_offset));
4269 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334270 ASYNC, ConstructServerDataPacket(
4271 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414272 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434273 mock_quic_data.AddWrite(
4274 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274275 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4276 mock_quic_data.AddRead(ASYNC, 0); // EOF
4277
4278 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4279
4280 AddHangingNonAlternateProtocolSocketData();
4281
4282 TestProxyDelegate test_proxy_delegate;
4283
Lily Houghton8c2f97d2018-01-22 05:06:594284 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494285 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274286
4287 test_proxy_delegate.set_alternative_proxy_server(
4288 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524289 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274290
4291 request_.url = GURL("http://mail.example.org/");
4292
4293 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564294 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4295 QuicStreamFactoryPeer::SetAlarmFactory(
4296 session_->quic_stream_factory(),
4297 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4298 &clock_));
tbansal6490783c2016-09-20 17:55:274299
4300 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4301 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4302 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4303 1);
4304
4305 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4306 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4307 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4308 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4309 1);
4310}
4311
Ryan Hamilton8d9ee76e2018-05-29 23:52:524312// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454313// even if alternative service destination is different.
4314TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344315 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304316 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524317 quic::QuicStreamOffset request_header_offset(0);
4318 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454319
rch5cb522462017-04-25 20:18:364320 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434321 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454322 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434323 mock_quic_data.AddWrite(
4324 SYNCHRONOUS,
4325 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334326 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434327 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4328 mock_quic_data.AddRead(
4329 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334330 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434331 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434332 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434333 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334334 ASYNC, ConstructServerDataPacket(
4335 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414336 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434337 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304338
bnc359ed2a2016-04-29 20:43:454339 // Second request.
alyssar2adf3ac2016-05-03 17:12:584340 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334341 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4342 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4343 true, GetRequestHeaders("GET", "https", "/"),
4344 GetNthClientInitiatedBidirectionalStreamId(0),
4345 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434346 mock_quic_data.AddRead(
4347 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334348 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434349 GetResponseHeaders("200 OK"), &response_header_offset));
4350 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334351 ASYNC, ConstructServerDataPacket(
4352 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414353 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434354 mock_quic_data.AddWrite(
4355 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304356 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4357 mock_quic_data.AddRead(ASYNC, 0); // EOF
4358
4359 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454360
4361 AddHangingNonAlternateProtocolSocketData();
4362 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304363
rch3f4b8452016-02-23 16:59:324364 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564365 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4366 QuicStreamFactoryPeer::SetAlarmFactory(
4367 session_->quic_stream_factory(),
4368 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4369 &clock_));
zhongyi32569c62016-01-08 02:54:304370
bnc359ed2a2016-04-29 20:43:454371 const char destination1[] = "first.example.com";
4372 const char destination2[] = "second.example.com";
4373
4374 // Set up alternative service entry to destination1.
4375 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214376 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454377 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214378 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444379 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454380 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524381 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454382 SendRequestAndExpectQuicResponse("hello!");
4383
4384 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214385 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214386 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444387 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524388 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454389 // even though alternative service destination is different.
4390 SendRequestAndExpectQuicResponse("hello!");
4391}
4392
4393// Pool to existing session with matching destination and matching certificate
4394// even if origin is different, and even if the alternative service with
4395// matching destination is not the first one on the list.
4396TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344397 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454398 GURL origin1 = request_.url;
4399 GURL origin2("https://www.example.org/");
4400 ASSERT_NE(origin1.host(), origin2.host());
4401
4402 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524403 quic::QuicStreamOffset request_header_offset(0);
4404 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454405
rch5cb522462017-04-25 20:18:364406 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434407 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454408 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434409 mock_quic_data.AddWrite(
4410 SYNCHRONOUS,
4411 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334412 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434413 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4414 mock_quic_data.AddRead(
4415 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334416 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434417 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434418 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434419 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334420 ASYNC, ConstructServerDataPacket(
4421 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414422 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434423 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454424
4425 // Second request.
Yixin Wang079ad542018-01-11 04:06:054426 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174427 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4428 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054429 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174430 QuicTestPacketMaker server_maker2(
4431 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4432 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584433 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434434 SYNCHRONOUS,
4435 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334436 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434437 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334438 GetNthClientInitiatedBidirectionalStreamId(0),
4439 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434440 mock_quic_data.AddRead(
4441 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334442 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434443 GetResponseHeaders("200 OK"), &response_header_offset));
4444 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334445 ASYNC, ConstructServerDataPacket(
4446 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414447 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434448 mock_quic_data.AddWrite(
4449 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454450 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4451 mock_quic_data.AddRead(ASYNC, 0); // EOF
4452
4453 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4454
4455 AddHangingNonAlternateProtocolSocketData();
4456 AddHangingNonAlternateProtocolSocketData();
4457
4458 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564459 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4460 QuicStreamFactoryPeer::SetAlarmFactory(
4461 session_->quic_stream_factory(),
4462 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4463 &clock_));
bnc359ed2a2016-04-29 20:43:454464
4465 const char destination1[] = "first.example.com";
4466 const char destination2[] = "second.example.com";
4467
4468 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214469 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454470 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214471 http_server_properties_.SetQuicAlternativeService(
4472 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444473 supported_versions_);
bnc359ed2a2016-04-29 20:43:454474
4475 // Set up multiple alternative service entries for |origin2|,
4476 // the first one with a different destination as for |origin1|,
4477 // the second one with the same. The second one should be used,
4478 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214479 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454480 AlternativeServiceInfoVector alternative_services;
4481 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214482 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4483 alternative_service2, expiration,
4484 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454485 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214486 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4487 alternative_service1, expiration,
4488 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454489 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4490 alternative_services);
bnc359ed2a2016-04-29 20:43:454491 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524492 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454493 SendRequestAndExpectQuicResponse("hello!");
4494
4495 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524496 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454497 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584498
bnc359ed2a2016-04-29 20:43:454499 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304500}
4501
4502// Multiple origins have listed the same alternative services. When there's a
4503// existing QUIC session opened by a request to other origin,
4504// if the cert is valid, should select this QUIC session to make the request
4505// if this is also the first existing QUIC session.
4506TEST_P(QuicNetworkTransactionTest,
4507 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344508 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294509 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304510
rch9ae5b3b2016-02-11 00:36:294511 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304512 MockRead http_reads[] = {
4513 MockRead("HTTP/1.1 200 OK\r\n"),
4514 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294515 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304516 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4517 MockRead(ASYNC, OK)};
4518
Ryan Sleevib8d7ea02018-05-07 20:01:014519 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304520 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084521 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304522 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4523
4524 // HTTP data for request to mail.example.org.
4525 MockRead http_reads2[] = {
4526 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294527 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304528 MockRead("hello world from mail.example.org"),
4529 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4530 MockRead(ASYNC, OK)};
4531
Ryan Sleevib8d7ea02018-05-07 20:01:014532 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304533 socket_factory_.AddSocketDataProvider(&http_data2);
4534 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4535
Ryan Hamilton8d9ee76e2018-05-29 23:52:524536 quic::QuicStreamOffset request_header_offset = 0;
4537 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304538
Yixin Wang079ad542018-01-11 04:06:054539 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174540 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4541 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054542 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584543 server_maker_.set_hostname("www.example.org");
4544 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304545 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364546 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434547 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304548 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584549 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434550 SYNCHRONOUS,
4551 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334552 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434553 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4554
4555 mock_quic_data.AddRead(
4556 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334557 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434558 GetResponseHeaders("200 OK"), &response_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:434559 std::string header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334560 mock_quic_data.AddRead(
4561 ASYNC, ConstructServerDataPacket(
4562 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414563 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434564 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4565 // Second QUIC request data.
4566 mock_quic_data.AddWrite(
4567 SYNCHRONOUS,
4568 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334569 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434570 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334571 GetNthClientInitiatedBidirectionalStreamId(0),
4572 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434573 mock_quic_data.AddRead(
4574 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334575 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434576 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334577 mock_quic_data.AddRead(
4578 ASYNC, ConstructServerDataPacket(
4579 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414580 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434581 mock_quic_data.AddWrite(
4582 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304583 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4584 mock_quic_data.AddRead(ASYNC, 0); // EOF
4585
4586 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304587
rtennetib8e80fb2016-05-16 00:12:094588 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324589 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564590 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4591 QuicStreamFactoryPeer::SetAlarmFactory(
4592 session_->quic_stream_factory(),
4593 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4594 &clock_));
zhongyi32569c62016-01-08 02:54:304595
4596 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294597 request_.url = GURL("https://www.example.org/");
4598 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304599 request_.url = GURL("https://mail.example.org/");
4600 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4601
rch9ae5b3b2016-02-11 00:36:294602 // Open a QUIC session to mail.example.org:443 when making request
4603 // to mail.example.org.
4604 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454605 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304606
rch9ae5b3b2016-02-11 00:36:294607 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304608 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454609 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524610}
4611
4612TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524613 MockRead http_reads[] = {
4614 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564615 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524616 MockRead("hello world"),
4617 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4618 MockRead(ASYNC, OK)};
4619
Ryan Sleevib8d7ea02018-05-07 20:01:014620 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524621 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084622 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564623 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524624
rtennetib8e80fb2016-05-16 00:12:094625 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324626 CreateSession();
bncc958faa2015-07-31 18:14:524627
4628 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454629
4630 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344631 AlternativeServiceInfoVector alternative_service_info_vector =
4632 http_server_properties_.GetAlternativeServiceInfos(http_server);
4633 ASSERT_EQ(1u, alternative_service_info_vector.size());
4634 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544635 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344636 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4637 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4638 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524639}
4640
4641TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524642 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564643 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4644 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524645 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4646 MockRead(ASYNC, OK)};
4647
Ryan Sleevib8d7ea02018-05-07 20:01:014648 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524649 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084650 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564651 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524652
4653 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524654 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364655 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434656 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4657 mock_quic_data.AddWrite(
4658 SYNCHRONOUS,
4659 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334660 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434661 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434662 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334663 ASYNC, ConstructServerResponseHeadersPacket(
4664 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4665 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434666 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334667 mock_quic_data.AddRead(
4668 ASYNC, ConstructServerDataPacket(
4669 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414670 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434671 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524672 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4673 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524674
4675 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4676
rtennetib8e80fb2016-05-16 00:12:094677 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324678 CreateSession();
bncc958faa2015-07-31 18:14:524679
bnc3472afd2016-11-17 15:27:214680 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524681 HostPortPair::FromURL(request_.url));
4682 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4683 alternative_service);
4684 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4685 alternative_service));
4686
4687 SendRequestAndExpectHttpResponse("hello world");
4688 SendRequestAndExpectQuicResponse("hello!");
4689
mmenkee24011922015-12-17 22:12:594690 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524691
4692 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4693 alternative_service));
rchac7f35e2017-03-15 20:42:304694 EXPECT_NE(nullptr,
4695 http_server_properties_.GetServerNetworkStats(
4696 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524697}
4698
bncc958faa2015-07-31 18:14:524699TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524700 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564701 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4702 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524703 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4704 MockRead(ASYNC, OK)};
4705
Ryan Sleevib8d7ea02018-05-07 20:01:014706 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524707 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564708 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524709
4710 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524711 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364712 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434713 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4714 mock_quic_data.AddWrite(
4715 SYNCHRONOUS,
4716 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334717 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434718 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434719 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334720 ASYNC, ConstructServerResponseHeadersPacket(
4721 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4722 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434723 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334724 mock_quic_data.AddRead(
4725 ASYNC, ConstructServerDataPacket(
4726 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414727 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434728 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524729 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4730
4731 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4732
4733 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324734 CreateSession();
bncc958faa2015-07-31 18:14:524735
4736 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4737 SendRequestAndExpectHttpResponse("hello world");
4738}
4739
tbansalc3308d72016-08-27 10:25:044740// Tests that the connection to an HTTPS proxy is raced with an available
4741// alternative proxy server.
4742TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274743 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594744 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494745 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044746
4747 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524748 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364749 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434750 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4751 mock_quic_data.AddWrite(
4752 SYNCHRONOUS,
4753 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334754 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434755 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434756 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334757 ASYNC, ConstructServerResponseHeadersPacket(
4758 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4759 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434760 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334761 mock_quic_data.AddRead(
4762 ASYNC, ConstructServerDataPacket(
4763 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414764 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434765 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044766 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4767 mock_quic_data.AddRead(ASYNC, 0); // EOF
4768
4769 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4770
4771 // There is no need to set up main job, because no attempt will be made to
4772 // speak to the proxy over TCP.
4773 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044774 TestProxyDelegate test_proxy_delegate;
4775 const HostPortPair host_port_pair("mail.example.org", 443);
4776
4777 test_proxy_delegate.set_alternative_proxy_server(
4778 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524779 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044780 CreateSession();
4781 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4782
4783 // The main job needs to hang in order to guarantee that the alternative
4784 // proxy server job will "win".
4785 AddHangingNonAlternateProtocolSocketData();
4786
4787 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4788
4789 // Verify that the alternative proxy server is not marked as broken.
4790 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4791
4792 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594793 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274794
4795 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4796 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4797 1);
tbansalc3308d72016-08-27 10:25:044798}
4799
bnc1c196c6e2016-05-28 13:51:484800TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304801 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274802 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304803
4804 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564805 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294806 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564807 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304808
4809 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564810 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484811 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564812 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304813
Ryan Sleevib8d7ea02018-05-07 20:01:014814 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504815 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084816 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504817 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304818
4819 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454820 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304821 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454822 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304823 };
Ryan Sleevib8d7ea02018-05-07 20:01:014824 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504825 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304826
4827 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014828 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504829 socket_factory_.AddSocketDataProvider(&http_data2);
4830 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304831
bnc912a04b2016-04-20 14:19:504832 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304833
4834 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304835 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174836 ASSERT_TRUE(http_data.AllReadDataConsumed());
4837 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304838
4839 // Now run the second request in which the QUIC socket hangs,
4840 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304841 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454842 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304843
rch37de576c2015-05-17 20:28:174844 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4845 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454846 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304847}
4848
[email protected]1e960032013-12-20 19:00:204849TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204850 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524851 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:034852 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:434853 mock_quic_data.AddWrite(
4854 SYNCHRONOUS,
4855 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334856 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434857 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434858 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334859 ASYNC, ConstructServerResponseHeadersPacket(
4860 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4861 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434862 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334863 mock_quic_data.AddRead(
4864 ASYNC, ConstructServerDataPacket(
4865 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414866 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434867 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504868 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594869 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484870
rcha5399e02015-04-21 19:32:044871 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484872
rtennetib8e80fb2016-05-16 00:12:094873 // The non-alternate protocol job needs to hang in order to guarantee that
4874 // the alternate-protocol job will "win".
4875 AddHangingNonAlternateProtocolSocketData();
4876
rch3f4b8452016-02-23 16:59:324877 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274878 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194879 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304880
4881 EXPECT_EQ(nullptr,
4882 http_server_properties_.GetServerNetworkStats(
4883 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484884}
4885
[email protected]1e960032013-12-20 19:00:204886TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204887 MockQuicData mock_quic_data;
Michael Warres167db3e2019-03-01 21:38:034888 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Fan Yang32c5a112018-12-10 20:06:334889 mock_quic_data.AddWrite(
4890 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4891 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4892 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434893 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334894 ASYNC, ConstructServerResponseHeadersPacket(
4895 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4896 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434897 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334898 mock_quic_data.AddRead(
4899 ASYNC, ConstructServerDataPacket(
4900 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414901 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434902 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504903 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594904 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044905 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274906
4907 // In order for a new QUIC session to be established via alternate-protocol
4908 // without racing an HTTP connection, we need the host resolution to happen
4909 // synchronously.
4910 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294911 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564912 "");
[email protected]3a120a6b2013-06-25 01:08:274913
rtennetib8e80fb2016-05-16 00:12:094914 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324915 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274916 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274917 SendRequestAndExpectQuicResponse("hello!");
4918}
4919
[email protected]0fc924b2014-03-31 04:34:154920TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494921 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4922 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154923
4924 // Since we are using a proxy, the QUIC job will not succeed.
4925 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294926 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4927 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564928 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154929
4930 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564931 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484932 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564933 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154934
Ryan Sleevib8d7ea02018-05-07 20:01:014935 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154936 socket_factory_.AddSocketDataProvider(&http_data);
4937
4938 // In order for a new QUIC session to be established via alternate-protocol
4939 // without racing an HTTP connection, we need the host resolution to happen
4940 // synchronously.
4941 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294942 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564943 "");
[email protected]0fc924b2014-03-31 04:34:154944
rch9ae5b3b2016-02-11 00:36:294945 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324946 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274947 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154948 SendRequestAndExpectHttpResponse("hello world");
4949}
4950
[email protected]1e960032013-12-20 19:00:204951TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204952 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524953 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364954 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434955 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4956 mock_quic_data.AddWrite(
4957 SYNCHRONOUS,
4958 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334959 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434960 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434961 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334962 ASYNC, ConstructServerResponseHeadersPacket(
4963 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4964 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:434965 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334966 mock_quic_data.AddRead(
4967 ASYNC, ConstructServerDataPacket(
4968 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414969 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434970 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594971 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044972 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124973
rtennetib8e80fb2016-05-16 00:12:094974 // The non-alternate protocol job needs to hang in order to guarantee that
4975 // the alternate-protocol job will "win".
4976 AddHangingNonAlternateProtocolSocketData();
4977
[email protected]11c05872013-08-20 02:04:124978 // In order for a new QUIC session to be established via alternate-protocol
4979 // without racing an HTTP connection, we need the host resolution to happen
4980 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4981 // connection to the the server, in this test we require confirmation
4982 // before encrypting so the HTTP job will still start.
4983 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294984 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564985 "");
[email protected]11c05872013-08-20 02:04:124986
rch3f4b8452016-02-23 16:59:324987 CreateSession();
[email protected]11c05872013-08-20 02:04:124988 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274989 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124990
bnc691fda62016-08-12 00:43:164991 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124992 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364993 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124995
4996 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524997 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014998 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504999
bnc691fda62016-08-12 00:43:165000 CheckWasQuicResponse(&trans);
5001 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125002}
5003
Steven Valdez58097ec32018-07-16 18:29:045004TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5005 MockQuicData mock_quic_data;
5006 quic::QuicStreamOffset client_header_stream_offset = 0;
5007 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035008 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045009 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335010 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5011 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5012 true, GetRequestHeaders("GET", "https", "/"),
5013 &client_header_stream_offset));
5014 mock_quic_data.AddRead(
5015 ASYNC,
5016 ConstructServerResponseHeadersPacket(
5017 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5018 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5019 mock_quic_data.AddWrite(SYNCHRONOUS,
5020 ConstructClientAckAndRstPacket(
5021 2, GetNthClientInitiatedBidirectionalStreamId(0),
5022 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045023
5024 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5025
5026 spdy::SpdySettingsIR settings_frame;
5027 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5028 quic::kDefaultMaxUncompressedHeaderSize);
5029 spdy::SpdySerializedFrame spdy_frame(
5030 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5031 mock_quic_data.AddWrite(
5032 SYNCHRONOUS,
5033 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385034 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5035 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045036 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5037 client_header_stream_offset += spdy_frame.size();
5038
5039 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335040 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5041 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5042 true, GetRequestHeaders("GET", "https", "/"),
5043 GetNthClientInitiatedBidirectionalStreamId(0),
5044 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045045 mock_quic_data.AddRead(
5046 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335047 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045048 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Victor Vasiliev076657c2019-03-12 02:46:435049 std::string header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045050 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335051 ASYNC, ConstructServerDataPacket(
5052 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415053 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045054 mock_quic_data.AddWrite(
5055 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5056 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5057 mock_quic_data.AddRead(ASYNC, 0); // EOF
5058
5059 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5060
5061 // In order for a new QUIC session to be established via alternate-protocol
5062 // without racing an HTTP connection, we need the host resolution to happen
5063 // synchronously.
5064 host_resolver_.set_synchronous_mode(true);
5065 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5066 "");
Steven Valdez58097ec32018-07-16 18:29:045067
5068 AddHangingNonAlternateProtocolSocketData();
5069 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275070 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565071 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5072 QuicStreamFactoryPeer::SetAlarmFactory(
5073 session_->quic_stream_factory(),
5074 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5075 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045076
5077 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5078 TestCompletionCallback callback;
5079 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5081
5082 // Confirm the handshake after the 425 Too Early.
5083 base::RunLoop().RunUntilIdle();
5084
5085 // The handshake hasn't been confirmed yet, so the retry should not have
5086 // succeeded.
5087 EXPECT_FALSE(callback.have_result());
5088
5089 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5090 quic::QuicSession::HANDSHAKE_CONFIRMED);
5091
5092 EXPECT_THAT(callback.WaitForResult(), IsOk());
5093 CheckWasQuicResponse(&trans);
5094 CheckResponseData(&trans, "hello!");
5095}
5096
5097TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5098 MockQuicData mock_quic_data;
5099 quic::QuicStreamOffset client_header_stream_offset = 0;
5100 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035101 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045102 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335103 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5104 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5105 true, GetRequestHeaders("GET", "https", "/"),
5106 &client_header_stream_offset));
5107 mock_quic_data.AddRead(
5108 ASYNC,
5109 ConstructServerResponseHeadersPacket(
5110 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5111 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5112 mock_quic_data.AddWrite(SYNCHRONOUS,
5113 ConstructClientAckAndRstPacket(
5114 2, GetNthClientInitiatedBidirectionalStreamId(0),
5115 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045116
5117 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5118
5119 spdy::SpdySettingsIR settings_frame;
5120 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5121 quic::kDefaultMaxUncompressedHeaderSize);
5122 spdy::SpdySerializedFrame spdy_frame(
5123 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5124 mock_quic_data.AddWrite(
5125 SYNCHRONOUS,
5126 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385127 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5128 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045129 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5130 client_header_stream_offset += spdy_frame.size();
5131
5132 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335133 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5134 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5135 true, GetRequestHeaders("GET", "https", "/"),
5136 GetNthClientInitiatedBidirectionalStreamId(0),
5137 &client_header_stream_offset));
5138 mock_quic_data.AddRead(
5139 ASYNC,
5140 ConstructServerResponseHeadersPacket(
5141 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5142 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5143 mock_quic_data.AddWrite(SYNCHRONOUS,
5144 ConstructClientAckAndRstPacket(
5145 5, GetNthClientInitiatedBidirectionalStreamId(1),
5146 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045147 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5148 mock_quic_data.AddRead(ASYNC, 0); // EOF
5149
5150 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5151
5152 // In order for a new QUIC session to be established via alternate-protocol
5153 // without racing an HTTP connection, we need the host resolution to happen
5154 // synchronously.
5155 host_resolver_.set_synchronous_mode(true);
5156 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5157 "");
Steven Valdez58097ec32018-07-16 18:29:045158
5159 AddHangingNonAlternateProtocolSocketData();
5160 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275161 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565162 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5163 QuicStreamFactoryPeer::SetAlarmFactory(
5164 session_->quic_stream_factory(),
5165 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5166 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045167
5168 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5169 TestCompletionCallback callback;
5170 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5171 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5172
5173 // Confirm the handshake after the 425 Too Early.
5174 base::RunLoop().RunUntilIdle();
5175
5176 // The handshake hasn't been confirmed yet, so the retry should not have
5177 // succeeded.
5178 EXPECT_FALSE(callback.have_result());
5179
5180 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5181 quic::QuicSession::HANDSHAKE_CONFIRMED);
5182
5183 EXPECT_THAT(callback.WaitForResult(), IsOk());
5184 const HttpResponseInfo* response = trans.GetResponseInfo();
5185 ASSERT_TRUE(response != nullptr);
5186 ASSERT_TRUE(response->headers.get() != nullptr);
5187 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5188 EXPECT_TRUE(response->was_fetched_via_spdy);
5189 EXPECT_TRUE(response->was_alpn_negotiated);
5190 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5191 response->connection_info);
5192}
5193
zhongyica364fbb2015-12-12 03:39:125194TEST_P(QuicNetworkTransactionTest,
5195 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485196 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125197 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525198 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365199 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435200 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5201 mock_quic_data.AddWrite(
5202 SYNCHRONOUS,
5203 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335204 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435205 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125206 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525207 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435208 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125209 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5210
5211 // The non-alternate protocol job needs to hang in order to guarantee that
5212 // the alternate-protocol job will "win".
5213 AddHangingNonAlternateProtocolSocketData();
5214
5215 // In order for a new QUIC session to be established via alternate-protocol
5216 // without racing an HTTP connection, we need the host resolution to happen
5217 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5218 // connection to the the server, in this test we require confirmation
5219 // before encrypting so the HTTP job will still start.
5220 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295221 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125222 "");
zhongyica364fbb2015-12-12 03:39:125223
rch3f4b8452016-02-23 16:59:325224 CreateSession();
zhongyica364fbb2015-12-12 03:39:125225 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275226 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125227
bnc691fda62016-08-12 00:43:165228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125229 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365230 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015231 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125232
5233 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525234 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015235 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125236
5237 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525238 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125239
bnc691fda62016-08-12 00:43:165240 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125241 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525242 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5243 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125244}
5245
5246TEST_P(QuicNetworkTransactionTest,
5247 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485248 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125249 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525250 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365251 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435252 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5253 mock_quic_data.AddWrite(
5254 SYNCHRONOUS,
5255 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335256 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435257 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215258 // Peer sending data from an non-existing stream causes this end to raise
5259 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335260 mock_quic_data.AddRead(
5261 ASYNC, ConstructServerRstPacket(
5262 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5263 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215264 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525265 mock_quic_data.AddWrite(
5266 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5267 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5268 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5270
5271 // The non-alternate protocol job needs to hang in order to guarantee that
5272 // the alternate-protocol job will "win".
5273 AddHangingNonAlternateProtocolSocketData();
5274
5275 // In order for a new QUIC session to be established via alternate-protocol
5276 // without racing an HTTP connection, we need the host resolution to happen
5277 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5278 // connection to the the server, in this test we require confirmation
5279 // before encrypting so the HTTP job will still start.
5280 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295281 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125282 "");
zhongyica364fbb2015-12-12 03:39:125283
rch3f4b8452016-02-23 16:59:325284 CreateSession();
zhongyica364fbb2015-12-12 03:39:125285 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275286 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125287
bnc691fda62016-08-12 00:43:165288 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125289 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365290 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015291 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125292
5293 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525294 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015295 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125296 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525297 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125298
bnc691fda62016-08-12 00:43:165299 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525300 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125301}
5302
rchcd5f1c62016-06-23 02:43:485303TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5304 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525305 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365306 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435307 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5308 mock_quic_data.AddWrite(
5309 SYNCHRONOUS,
5310 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335311 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435312 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485313 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335314 mock_quic_data.AddRead(
5315 ASYNC, ConstructServerResponseHeadersPacket(
5316 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5317 GetResponseHeaders("200 OK")));
5318 mock_quic_data.AddRead(
5319 ASYNC, ConstructServerRstPacket(
5320 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5321 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435322 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485323 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5324 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5325
5326 // The non-alternate protocol job needs to hang in order to guarantee that
5327 // the alternate-protocol job will "win".
5328 AddHangingNonAlternateProtocolSocketData();
5329
5330 // In order for a new QUIC session to be established via alternate-protocol
5331 // without racing an HTTP connection, we need the host resolution to happen
5332 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5333 // connection to the the server, in this test we require confirmation
5334 // before encrypting so the HTTP job will still start.
5335 host_resolver_.set_synchronous_mode(true);
5336 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5337 "");
rchcd5f1c62016-06-23 02:43:485338
5339 CreateSession();
5340 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275341 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485342
bnc691fda62016-08-12 00:43:165343 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485344 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365345 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015346 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485347
5348 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525349 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485350 // Read the headers.
robpercival214763f2016-07-01 23:27:015351 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485352
bnc691fda62016-08-12 00:43:165353 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485354 ASSERT_TRUE(response != nullptr);
5355 ASSERT_TRUE(response->headers.get() != nullptr);
5356 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5357 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525358 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445359 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5360 response->connection_info);
rchcd5f1c62016-06-23 02:43:485361
5362 std::string response_data;
bnc691fda62016-08-12 00:43:165363 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485364}
5365
5366TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485367 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485368 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525369 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365370 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435371 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5372 mock_quic_data.AddWrite(
5373 SYNCHRONOUS,
5374 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335375 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435376 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335377 mock_quic_data.AddRead(
5378 ASYNC, ConstructServerRstPacket(
5379 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5380 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485381 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5382 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5383
5384 // The non-alternate protocol job needs to hang in order to guarantee that
5385 // the alternate-protocol job will "win".
5386 AddHangingNonAlternateProtocolSocketData();
5387
5388 // In order for a new QUIC session to be established via alternate-protocol
5389 // without racing an HTTP connection, we need the host resolution to happen
5390 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5391 // connection to the the server, in this test we require confirmation
5392 // before encrypting so the HTTP job will still start.
5393 host_resolver_.set_synchronous_mode(true);
5394 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5395 "");
rchcd5f1c62016-06-23 02:43:485396
5397 CreateSession();
5398 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275399 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485400
bnc691fda62016-08-12 00:43:165401 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485402 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365403 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015404 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485405
5406 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525407 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485408 // Read the headers.
robpercival214763f2016-07-01 23:27:015409 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485410}
5411
[email protected]1e960032013-12-20 19:00:205412TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305413 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525414 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585415 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305416 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505417 MockRead(ASYNC, close->data(), close->length()),
5418 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5419 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305420 };
Ryan Sleevib8d7ea02018-05-07 20:01:015421 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305422 socket_factory_.AddSocketDataProvider(&quic_data);
5423
5424 // Main job which will succeed even though the alternate job fails.
5425 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025426 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5427 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5428 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305429
Ryan Sleevib8d7ea02018-05-07 20:01:015430 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305431 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565432 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305433
rch3f4b8452016-02-23 16:59:325434 CreateSession();
David Schinazic8281052019-01-24 06:14:175435 AddQuicAlternateProtocolMapping(
5436 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195437 SendRequestAndExpectHttpResponse("hello from http");
5438 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305439}
5440
[email protected]1e960032013-12-20 19:00:205441TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595442 // Alternate-protocol job
5443 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025444 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595445 };
Ryan Sleevib8d7ea02018-05-07 20:01:015446 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595447 socket_factory_.AddSocketDataProvider(&quic_data);
5448
5449 // Main job which will succeed even though the alternate job fails.
5450 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025451 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5452 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5453 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595454
Ryan Sleevib8d7ea02018-05-07 20:01:015455 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595456 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565457 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595458
rch3f4b8452016-02-23 16:59:325459 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595460
Ryan Hamilton9835e662018-08-02 05:36:275461 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195462 SendRequestAndExpectHttpResponse("hello from http");
5463 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595464}
5465
[email protected]00c159f2014-05-21 22:38:165466TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535467 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165468 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025469 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165470 };
Ryan Sleevib8d7ea02018-05-07 20:01:015471 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165472 socket_factory_.AddSocketDataProvider(&quic_data);
5473
[email protected]eb71ab62014-05-23 07:57:535474 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165475 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025476 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165477 };
5478
Ryan Sleevib8d7ea02018-05-07 20:01:015479 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165480 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5481 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565482 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165483
rtennetib8e80fb2016-05-16 00:12:095484 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325485 CreateSession();
[email protected]00c159f2014-05-21 22:38:165486
Ryan Hamilton9835e662018-08-02 05:36:275487 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165489 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165490 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5492 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165493 ExpectQuicAlternateProtocolMapping();
5494}
5495
Zhongyi Shia0cef1082017-08-25 01:49:505496TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5497 // Tests that TCP job is delayed and QUIC job does not require confirmation
5498 // if QUIC was recently supported on the same IP on start.
5499
5500 // Set QUIC support on the last IP address, which is same with the local IP
5501 // address. Require confirmation mode will be turned off immediately when
5502 // local IP address is sorted out after we configure the UDP socket.
5503 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5504
5505 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525506 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035507 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shi32f2fd02018-04-16 18:23:435508 mock_quic_data.AddWrite(
5509 SYNCHRONOUS,
5510 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335511 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435512 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435513 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335514 ASYNC, ConstructServerResponseHeadersPacket(
5515 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5516 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435517 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335518 mock_quic_data.AddRead(
5519 ASYNC, ConstructServerDataPacket(
5520 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415521 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435522 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505523 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5524 mock_quic_data.AddRead(ASYNC, 0); // EOF
5525
5526 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5527 // No HTTP data is mocked as TCP job never starts in this case.
5528
5529 CreateSession();
5530 // QuicStreamFactory by default requires confirmation on construction.
5531 session_->quic_stream_factory()->set_require_confirmation(true);
5532
Ryan Hamilton9835e662018-08-02 05:36:275533 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505534
5535 // Stall host resolution so that QUIC job will not succeed synchronously.
5536 // Socket will not be configured immediately and QUIC support is not sorted
5537 // out, TCP job will still be delayed as server properties indicates QUIC
5538 // support on last IP address.
5539 host_resolver_.set_synchronous_mode(false);
5540
5541 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5542 TestCompletionCallback callback;
5543 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5544 IsError(ERR_IO_PENDING));
5545 // Complete host resolution in next message loop so that QUIC job could
5546 // proceed.
5547 base::RunLoop().RunUntilIdle();
5548 EXPECT_THAT(callback.WaitForResult(), IsOk());
5549
5550 CheckWasQuicResponse(&trans);
5551 CheckResponseData(&trans, "hello!");
5552}
5553
5554TEST_P(QuicNetworkTransactionTest,
5555 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5556 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5557 // was recently supported on a different IP address on start.
5558
5559 // Set QUIC support on the last IP address, which is different with the local
5560 // IP address. Require confirmation mode will remain when local IP address is
5561 // sorted out after we configure the UDP socket.
5562 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5563
5564 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525565 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505566 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435567 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5568 mock_quic_data.AddWrite(
5569 SYNCHRONOUS,
5570 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335571 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435572 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435573 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335574 ASYNC, ConstructServerResponseHeadersPacket(
5575 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5576 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435577 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335578 mock_quic_data.AddRead(
5579 ASYNC, ConstructServerDataPacket(
5580 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415581 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435582 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505583 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5584 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5585 // No HTTP data is mocked as TCP job will be delayed and never starts.
5586
5587 CreateSession();
5588 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275589 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505590
5591 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5592 // Socket will not be configured immediately and QUIC support is not sorted
5593 // out, TCP job will still be delayed as server properties indicates QUIC
5594 // support on last IP address.
5595 host_resolver_.set_synchronous_mode(false);
5596
5597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5598 TestCompletionCallback callback;
5599 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5600 IsError(ERR_IO_PENDING));
5601
5602 // Complete host resolution in next message loop so that QUIC job could
5603 // proceed.
5604 base::RunLoop().RunUntilIdle();
5605 // Explicitly confirm the handshake so that QUIC job could succeed.
5606 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525607 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505608 EXPECT_THAT(callback.WaitForResult(), IsOk());
5609
5610 CheckWasQuicResponse(&trans);
5611 CheckResponseData(&trans, "hello!");
5612}
5613
Ryan Hamilton75f197262017-08-17 14:00:075614TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5615 // Test that NetErrorDetails is correctly populated, even if the
5616 // handshake has not yet been confirmed and no stream has been created.
5617
5618 // QUIC job will pause. When resumed, it will fail.
5619 MockQuicData mock_quic_data;
5620 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5621 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5622 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5623
5624 // Main job will also fail.
5625 MockRead http_reads[] = {
5626 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5627 };
5628
Ryan Sleevib8d7ea02018-05-07 20:01:015629 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075630 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5631 socket_factory_.AddSocketDataProvider(&http_data);
5632 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5633
5634 AddHangingNonAlternateProtocolSocketData();
5635 CreateSession();
5636 // Require handshake confirmation to ensure that no QUIC streams are
5637 // created, and to ensure that the TCP job does not wait for the QUIC
5638 // job to fail before it starts.
5639 session_->quic_stream_factory()->set_require_confirmation(true);
5640
Ryan Hamilton9835e662018-08-02 05:36:275641 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075642 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5643 TestCompletionCallback callback;
5644 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5646 // Allow the TCP job to fail.
5647 base::RunLoop().RunUntilIdle();
5648 // Now let the QUIC job fail.
5649 mock_quic_data.Resume();
5650 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5651 ExpectQuicAlternateProtocolMapping();
5652 NetErrorDetails details;
5653 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525654 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075655}
5656
[email protected]1e960032013-12-20 19:00:205657TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455658 // Alternate-protocol job
5659 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025660 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455661 };
Ryan Sleevib8d7ea02018-05-07 20:01:015662 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455663 socket_factory_.AddSocketDataProvider(&quic_data);
5664
[email protected]c92c1b52014-05-31 04:16:065665 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015666 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065667 socket_factory_.AddSocketDataProvider(&quic_data2);
5668
[email protected]4d283b32013-10-17 12:57:275669 // Final job that will proceed when the QUIC job fails.
5670 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025671 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5672 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5673 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275674
Ryan Sleevib8d7ea02018-05-07 20:01:015675 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275676 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565677 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275678
rtennetiafccbc062016-05-16 18:21:145679 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325680 CreateSession();
[email protected]77c6c162013-08-17 02:57:455681
Ryan Hamilton9835e662018-08-02 05:36:275682 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455683
[email protected]4d283b32013-10-17 12:57:275684 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455685
5686 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275687
rch37de576c2015-05-17 20:28:175688 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5689 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455690}
5691
[email protected]93b31772014-06-19 08:03:355692TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035693 // Alternate-protocol job
5694 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595695 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035696 };
Ryan Sleevib8d7ea02018-05-07 20:01:015697 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035698 socket_factory_.AddSocketDataProvider(&quic_data);
5699
5700 // Main job that will proceed when the QUIC job fails.
5701 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025702 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5703 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5704 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035705
Ryan Sleevib8d7ea02018-05-07 20:01:015706 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035707 socket_factory_.AddSocketDataProvider(&http_data);
5708
rtennetib8e80fb2016-05-16 00:12:095709 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325710 CreateSession();
[email protected]65768442014-06-06 23:37:035711
Ryan Hamilton9835e662018-08-02 05:36:275712 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035713
5714 SendRequestAndExpectHttpResponse("hello from http");
5715}
5716
[email protected]eb71ab62014-05-23 07:57:535717TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335718 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015719 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495720 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335721 socket_factory_.AddSocketDataProvider(&quic_data);
5722
5723 // Main job which will succeed even though the alternate job fails.
5724 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025725 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5726 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5727 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335728
Ryan Sleevib8d7ea02018-05-07 20:01:015729 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335730 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565731 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335732
rch3f4b8452016-02-23 16:59:325733 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275734 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335735 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535736
5737 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335738}
5739
[email protected]4fee9672014-01-08 14:47:155740TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Michael Warres167db3e2019-03-01 21:38:035741 if (version_ >= quic::QUIC_VERSION_47) {
5742 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
5743 return;
5744 }
[email protected]4fee9672014-01-08 14:47:155745 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175746 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5747 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045748 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155749
5750 // When the QUIC connection fails, we will try the request again over HTTP.
5751 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485752 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565753 MockRead("hello world"),
5754 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5755 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155756
Ryan Sleevib8d7ea02018-05-07 20:01:015757 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155758 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565759 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155760
5761 // In order for a new QUIC session to be established via alternate-protocol
5762 // without racing an HTTP connection, we need the host resolution to happen
5763 // synchronously.
5764 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295765 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565766 "");
[email protected]4fee9672014-01-08 14:47:155767
rch3f4b8452016-02-23 16:59:325768 CreateSession();
David Schinazic8281052019-01-24 06:14:175769 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5770 AddQuicAlternateProtocolMapping(
5771 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155772 SendRequestAndExpectHttpResponse("hello world");
5773}
5774
tbansalc3308d72016-08-27 10:25:045775// For an alternative proxy that supports QUIC, test that the request is
5776// successfully fetched by the main job when the alternate proxy job encounters
5777// an error.
5778TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5779 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5780}
5781TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5782 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5783}
5784TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5785 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5786}
5787TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5788 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5789}
5790TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5791 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5792}
5793TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5794 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5795}
5796TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5797 TestAlternativeProxy(ERR_IO_PENDING);
5798}
5799TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5800 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5801}
5802
5803TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5804 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175805 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5806 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335807 mock_quic_data.AddWrite(
5808 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5809 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5810 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435811 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045812 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5813
5814 // When the QUIC connection fails, we will try the request again over HTTP.
5815 MockRead http_reads[] = {
5816 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5817 MockRead("hello world"),
5818 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5819 MockRead(ASYNC, OK)};
5820
Ryan Sleevib8d7ea02018-05-07 20:01:015821 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045822 socket_factory_.AddSocketDataProvider(&http_data);
5823 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5824
5825 TestProxyDelegate test_proxy_delegate;
5826 const HostPortPair host_port_pair("myproxy.org", 443);
5827 test_proxy_delegate.set_alternative_proxy_server(
5828 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5829 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5830
Ramin Halavatica8d5252018-03-12 05:33:495831 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5832 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525833 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045834 request_.url = GURL("http://mail.example.org/");
5835
5836 // In order for a new QUIC session to be established via alternate-protocol
5837 // without racing an HTTP connection, we need the host resolution to happen
5838 // synchronously.
5839 host_resolver_.set_synchronous_mode(true);
5840 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045841
5842 CreateSession();
David Schinazic8281052019-01-24 06:14:175843 crypto_client_stream_factory_.set_handshake_mode(
5844 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045845 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595846 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165847 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045848}
5849
bnc508835902015-05-12 20:10:295850TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585851 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385852 EXPECT_FALSE(
5853 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295854 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525855 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365856 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435857 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5858 mock_quic_data.AddWrite(
5859 SYNCHRONOUS,
5860 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335861 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435862 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435863 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335864 ASYNC, ConstructServerResponseHeadersPacket(
5865 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5866 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:435867 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335868 mock_quic_data.AddRead(
5869 ASYNC, ConstructServerDataPacket(
5870 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415871 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435872 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505873 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295874 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5875
bncb07c05532015-05-14 19:07:205876 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095877 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325878 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275879 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295880 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385881 EXPECT_TRUE(
5882 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295883}
5884
zhongyi363c91c2017-03-23 23:16:085885// TODO(zhongyi): disabled this broken test as it was not testing the correct
5886// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5887TEST_P(QuicNetworkTransactionTest,
5888 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275889 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595890 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495891 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045892
5893 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045894
5895 test_proxy_delegate.set_alternative_proxy_server(
5896 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525897 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045898
5899 request_.url = GURL("http://mail.example.org/");
5900
5901 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5902 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015903 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045904 socket_factory_.AddSocketDataProvider(&socket_data);
5905
5906 // The non-alternate protocol job needs to hang in order to guarantee that
5907 // the alternate-protocol job will "win".
5908 AddHangingNonAlternateProtocolSocketData();
5909
5910 CreateSession();
5911 request_.method = "POST";
5912 ChunkedUploadDataStream upload_data(0);
5913 upload_data.AppendData("1", 1, true);
5914
5915 request_.upload_data_stream = &upload_data;
5916
5917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5918 TestCompletionCallback callback;
5919 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5920 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5921 EXPECT_NE(OK, callback.WaitForResult());
5922
5923 // Verify that the alternative proxy server is not marked as broken.
5924 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5925
5926 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595927 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275928
5929 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5930 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5931 1);
tbansalc3308d72016-08-27 10:25:045932}
5933
rtenneti56977812016-01-15 19:26:565934TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415935 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575936 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565937
5938 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5939 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015940 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565941 socket_factory_.AddSocketDataProvider(&socket_data);
5942
rtennetib8e80fb2016-05-16 00:12:095943 // The non-alternate protocol job needs to hang in order to guarantee that
5944 // the alternate-protocol job will "win".
5945 AddHangingNonAlternateProtocolSocketData();
5946
rtenneti56977812016-01-15 19:26:565947 CreateSession();
5948 request_.method = "POST";
5949 ChunkedUploadDataStream upload_data(0);
5950 upload_data.AppendData("1", 1, true);
5951
5952 request_.upload_data_stream = &upload_data;
5953
bnc691fda62016-08-12 00:43:165954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565955 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165956 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565958 EXPECT_NE(OK, callback.WaitForResult());
5959}
5960
rche11300ef2016-09-02 01:44:285961TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485962 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285963 ScopedMockNetworkChangeNotifier network_change_notifier;
5964 MockNetworkChangeNotifier* mock_ncn =
5965 network_change_notifier.mock_network_change_notifier();
5966 mock_ncn->ForceNetworkHandlesSupported();
5967 mock_ncn->SetConnectedNetworksList(
5968 {kDefaultNetworkForTests, kNewNetworkForTests});
5969
mmenke6ddfbea2017-05-31 21:48:415970 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285971 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315972 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285973
5974 MockQuicData socket_data;
5975 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525976 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435977 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:335978 socket_data.AddWrite(
5979 SYNCHRONOUS,
5980 ConstructClientRequestHeadersPacket(
5981 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
5982 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:285983 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5984 socket_data.AddSocketDataToFactory(&socket_factory_);
5985
5986 MockQuicData socket_data2;
5987 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5988 socket_data2.AddSocketDataToFactory(&socket_factory_);
5989
5990 // The non-alternate protocol job needs to hang in order to guarantee that
5991 // the alternate-protocol job will "win".
5992 AddHangingNonAlternateProtocolSocketData();
5993
5994 CreateSession();
5995 request_.method = "POST";
5996 ChunkedUploadDataStream upload_data(0);
5997
5998 request_.upload_data_stream = &upload_data;
5999
rdsmith1d343be52016-10-21 20:37:506000 std::unique_ptr<HttpNetworkTransaction> trans(
6001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286002 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506003 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6005
6006 base::RunLoop().RunUntilIdle();
6007 upload_data.AppendData("1", 1, true);
6008 base::RunLoop().RunUntilIdle();
6009
6010 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506011 trans.reset();
rche11300ef2016-09-02 01:44:286012 session_.reset();
6013}
6014
Ryan Hamilton4b3574532017-10-30 20:17:256015TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6016 session_params_.origins_to_force_quic_on.insert(
6017 HostPortPair::FromString("mail.example.org:443"));
6018
6019 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526020 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436021 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256022 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336023 socket_data.AddWrite(
6024 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6025 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6026 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436027 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336028 ASYNC, ConstructServerResponseHeadersPacket(
6029 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6030 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436031 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336032 socket_data.AddRead(
6033 ASYNC, ConstructServerDataPacket(
6034 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416035 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436036 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256037 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166038 socket_data.AddWrite(
6039 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6040 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6041 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256042
6043 socket_data.AddSocketDataToFactory(&socket_factory_);
6044
6045 CreateSession();
6046
6047 SendRequestAndExpectQuicResponse("hello!");
6048 session_.reset();
6049}
6050
6051TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6052 session_params_.origins_to_force_quic_on.insert(
6053 HostPortPair::FromString("mail.example.org:443"));
6054
6055 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526056 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436057 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256058 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336059 socket_data.AddWrite(
6060 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6061 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6062 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436063 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336064 ASYNC, ConstructServerResponseHeadersPacket(
6065 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6066 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436067 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336068 socket_data.AddRead(
6069 ASYNC, ConstructServerDataPacket(
6070 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416071 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436072 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256073 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166074 socket_data.AddWrite(
6075 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6076 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6077 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256078
6079 socket_data.AddSocketDataToFactory(&socket_factory_);
6080
6081 CreateSession();
6082
6083 SendRequestAndExpectQuicResponse("hello!");
6084 session_.reset();
6085}
6086
Ryan Hamilton9edcf1a2017-11-22 05:55:176087TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486088 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256089 session_params_.origins_to_force_quic_on.insert(
6090 HostPortPair::FromString("mail.example.org:443"));
6091
6092 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526093 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256094 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436095 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176096 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256097 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6098 }
6099 socket_data.AddSocketDataToFactory(&socket_factory_);
6100
6101 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176102 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6103 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6104 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6105 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256106
Ryan Hamilton8d9ee76e2018-05-29 23:52:526107 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256108 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6109 TestCompletionCallback callback;
6110 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176112 while (!callback.have_result()) {
6113 base::RunLoop().RunUntilIdle();
6114 quic_task_runner_->RunUntilIdle();
6115 }
6116 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256117 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176118 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6119 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6120 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526121 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6122 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256123}
6124
Ryan Hamilton9edcf1a2017-11-22 05:55:176125TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486126 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256127 session_params_.origins_to_force_quic_on.insert(
6128 HostPortPair::FromString("mail.example.org:443"));
6129
6130 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526131 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256132 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436133 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176134 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256135 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6136 }
6137 socket_data.AddSocketDataToFactory(&socket_factory_);
6138
6139 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176140 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6141 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6142 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6143 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256144
Ryan Hamilton8d9ee76e2018-05-29 23:52:526145 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256146 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6147 TestCompletionCallback callback;
6148 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6149 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176150 while (!callback.have_result()) {
6151 base::RunLoop().RunUntilIdle();
6152 quic_task_runner_->RunUntilIdle();
6153 }
6154 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256155 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176156 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6157 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6158 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526159 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6160 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256161}
6162
Cherie Shi7596de632018-02-22 07:28:186163TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486164 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186165 session_params_.origins_to_force_quic_on.insert(
6166 HostPortPair::FromString("mail.example.org:443"));
Victor Vasiliev076657c2019-03-12 02:46:436167 const std::string error_details =
Ryan Hamilton8d9ee76e2018-05-29 23:52:526168 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6169 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186170
6171 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526172 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186173 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436174 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186175 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6176 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526177 socket_data.AddWrite(
6178 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6179 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186180 socket_data.AddSocketDataToFactory(&socket_factory_);
6181
6182 CreateSession();
6183
6184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6185 TestCompletionCallback callback;
6186 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6188 base::RunLoop().RunUntilIdle();
6189 ASSERT_TRUE(callback.have_result());
6190 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6191 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6192 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6193}
6194
ckrasic769733c2016-06-30 00:42:136195// Adds coverage to catch regression such as https://crbug.com/622043
6196TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416197 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136198 HostPortPair::FromString("mail.example.org:443"));
6199
6200 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526201 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236202 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436203 mock_quic_data.AddWrite(
6204 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6205 &header_stream_offset));
6206 mock_quic_data.AddWrite(
6207 SYNCHRONOUS,
6208 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336209 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6210 true, true, GetRequestHeaders("GET", "https", "/"),
6211 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526212 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436213 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336214 ASYNC, ConstructServerPushPromisePacket(
6215 1, GetNthClientInitiatedBidirectionalStreamId(0),
6216 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6217 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6218 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576219 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266220 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336221 mock_quic_data.AddWrite(SYNCHRONOUS,
6222 ConstructClientPriorityPacket(
6223 client_packet_number++, false,
6224 GetNthServerInitiatedUnidirectionalStreamId(0),
6225 GetNthClientInitiatedBidirectionalStreamId(0),
6226 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576227 }
Zhongyi Shi32f2fd02018-04-16 18:23:436228 mock_quic_data.AddRead(
6229 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336230 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436231 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576232 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436233 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6234 mock_quic_data.AddRead(
6235 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336236 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6237 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436238 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436239 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336240 ASYNC, ConstructServerDataPacket(
6241 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416242 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576243 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436244 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436245 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436246 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336247 ASYNC, ConstructServerDataPacket(
6248 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416249 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336250 mock_quic_data.AddWrite(SYNCHRONOUS,
6251 ConstructClientAckAndRstPacket(
6252 client_packet_number++,
6253 GetNthServerInitiatedUnidirectionalStreamId(0),
6254 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136255 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6256 mock_quic_data.AddRead(ASYNC, 0); // EOF
6257 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6258
6259 // The non-alternate protocol job needs to hang in order to guarantee that
6260 // the alternate-protocol job will "win".
6261 AddHangingNonAlternateProtocolSocketData();
6262
6263 CreateSession();
6264
6265 // PUSH_PROMISE handling in the http layer gets exercised here.
6266 SendRequestAndExpectQuicResponse("hello!");
6267
6268 request_.url = GURL("https://mail.example.org/pushed.jpg");
6269 SendRequestAndExpectQuicResponse("and hello!");
6270
6271 // Check that the NetLog was filled reasonably.
6272 TestNetLogEntry::List entries;
6273 net_log_.GetEntries(&entries);
6274 EXPECT_LT(0u, entries.size());
6275
6276 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6277 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006278 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6279 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136280 EXPECT_LT(0, pos);
6281}
6282
rch56ec40a2017-06-23 14:48:446283// Regression test for http://crbug.com/719461 in which a promised stream
6284// is closed before the pushed headers arrive, but after the connection
6285// is closed and before the callbacks are executed.
6286TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486287 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446288 session_params_.origins_to_force_quic_on.insert(
6289 HostPortPair::FromString("mail.example.org:443"));
6290
6291 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526292 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236293 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446294 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436295 mock_quic_data.AddWrite(
6296 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6297 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446298 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436299 mock_quic_data.AddWrite(
6300 SYNCHRONOUS,
6301 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336302 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6303 true, true, GetRequestHeaders("GET", "https", "/"),
6304 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526305 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446306 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436307 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336308 ASYNC, ConstructServerPushPromisePacket(
6309 1, GetNthClientInitiatedBidirectionalStreamId(0),
6310 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6311 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6312 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576313 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266314 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336315 mock_quic_data.AddWrite(SYNCHRONOUS,
6316 ConstructClientPriorityPacket(
6317 client_packet_number++, false,
6318 GetNthServerInitiatedUnidirectionalStreamId(0),
6319 GetNthClientInitiatedBidirectionalStreamId(0),
6320 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576321 }
rch56ec40a2017-06-23 14:48:446322 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436323 mock_quic_data.AddRead(
6324 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336325 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436326 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446327 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576328 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436329 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446330 // Response body for first request.
Victor Vasiliev076657c2019-03-12 02:46:436331 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436332 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336333 ASYNC, ConstructServerDataPacket(
6334 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416335 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446336 // Write error for the third request.
6337 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6338 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6339 mock_quic_data.AddRead(ASYNC, 0); // EOF
6340 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6341
6342 CreateSession();
6343
6344 // Send a request which triggers a push promise from the server.
6345 SendRequestAndExpectQuicResponse("hello!");
6346
6347 // Start a push transaction that will be cancelled after the connection
6348 // is closed, but before the callback is executed.
6349 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196350 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446351 session_.get());
6352 TestCompletionCallback callback2;
6353 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6354 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6355 base::RunLoop().RunUntilIdle();
6356
6357 // Cause the connection to close on a write error.
6358 HttpRequestInfo request3;
6359 request3.method = "GET";
6360 request3.url = GURL("https://mail.example.org/");
6361 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106362 request3.traffic_annotation =
6363 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446364 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6365 TestCompletionCallback callback3;
6366 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6367 IsError(ERR_IO_PENDING));
6368
6369 base::RunLoop().RunUntilIdle();
6370
6371 // When |trans2| is destroyed, the underlying stream will be closed.
6372 EXPECT_FALSE(callback2.have_result());
6373 trans2 = nullptr;
6374
6375 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6376}
6377
ckrasicda193a82016-07-09 00:39:366378TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416379 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366380 HostPortPair::FromString("mail.example.org:443"));
6381
6382 MockQuicData mock_quic_data;
6383
Ryan Hamilton8d9ee76e2018-05-29 23:52:526384 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416385 int write_packet_index = 1;
6386 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6387 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366388
Victor Vasiliev076657c2019-03-12 02:46:436389 std::string header = ConstructDataHeader(1);
Renjief49758b2019-01-11 23:32:416390 if (version_ != quic::QUIC_VERSION_99) {
6391 mock_quic_data.AddWrite(
6392 SYNCHRONOUS,
6393 ConstructClientRequestHeadersAndDataFramesPacket(
6394 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6395 true, true, DEFAULT_PRIORITY,
6396 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6397 {"1"}));
6398 } else {
6399 mock_quic_data.AddWrite(
6400 SYNCHRONOUS,
6401 ConstructClientRequestHeadersAndDataFramesPacket(
6402 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6403 true, true, DEFAULT_PRIORITY,
6404 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6405 {header, "1"}));
6406 }
ckrasicda193a82016-07-09 00:39:366407
Zhongyi Shi32f2fd02018-04-16 18:23:436408 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336409 ASYNC, ConstructServerResponseHeadersPacket(
6410 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6411 GetResponseHeaders("200 OK")));
6412
Victor Vasiliev076657c2019-03-12 02:46:436413 std::string header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336414 mock_quic_data.AddRead(
6415 ASYNC, ConstructServerDataPacket(
6416 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416417 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366418
Renjief49758b2019-01-11 23:32:416419 mock_quic_data.AddWrite(
6420 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366421
6422 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6423 mock_quic_data.AddRead(ASYNC, 0); // EOF
6424 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6425
6426 // The non-alternate protocol job needs to hang in order to guarantee that
6427 // the alternate-protocol job will "win".
6428 AddHangingNonAlternateProtocolSocketData();
6429
6430 CreateSession();
6431 request_.method = "POST";
6432 ChunkedUploadDataStream upload_data(0);
6433 upload_data.AppendData("1", 1, true);
6434
6435 request_.upload_data_stream = &upload_data;
6436
6437 SendRequestAndExpectQuicResponse("hello!");
6438}
6439
allada71b2efb2016-09-09 04:57:486440class QuicURLRequestContext : public URLRequestContext {
6441 public:
6442 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6443 MockClientSocketFactory* socket_factory)
6444 : storage_(this) {
6445 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076446 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046447 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486448 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046449 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596450 storage_.set_proxy_resolution_service(
6451 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076452 storage_.set_ssl_config_service(
6453 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486454 storage_.set_http_auth_handler_factory(
Eric Orthbe2efac2019-03-06 01:11:116455 HttpAuthHandlerFactory::CreateDefault());
allada71b2efb2016-09-09 04:57:486456 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076457 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046458 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486459 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046460 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6461 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6462 false));
allada71b2efb2016-09-09 04:57:486463 }
6464
6465 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6466
6467 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6468
6469 private:
6470 MockClientSocketFactory* socket_factory_;
6471 URLRequestContextStorage storage_;
6472};
6473
6474TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416475 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486476 HostPortPair::FromString("mail.example.org:443"));
6477
6478 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526479 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366480 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436481 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136482 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486483 headers["user-agent"] = "";
6484 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336485 mock_quic_data.AddWrite(
6486 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6487 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6488 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486489
Ryan Hamilton8d9ee76e2018-05-29 23:52:526490 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336491 mock_quic_data.AddRead(
6492 ASYNC,
6493 ConstructServerResponseHeadersPacket(
6494 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6495 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486496
Victor Vasiliev076657c2019-03-12 02:46:436497 std::string header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366498 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336499 ASYNC, ConstructServerDataPacket(
6500 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6501 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436502 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486503
6504 mock_quic_data.AddRead(ASYNC, 0); // EOF
6505
6506 CreateSession();
6507
6508 TestDelegate delegate;
6509 QuicURLRequestContext quic_url_request_context(std::move(session_),
6510 &socket_factory_);
6511
6512 mock_quic_data.AddSocketDataToFactory(
6513 &quic_url_request_context.socket_factory());
6514 TestNetworkDelegate network_delegate;
6515 quic_url_request_context.set_network_delegate(&network_delegate);
6516
6517 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296518 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6519 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486520 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6521 &ssl_data_);
6522
6523 request->Start();
Wez2a31b222018-06-07 22:07:156524 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486525
6526 EXPECT_LT(0, request->GetTotalSentBytes());
6527 EXPECT_LT(0, request->GetTotalReceivedBytes());
6528 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6529 request->GetTotalSentBytes());
6530 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6531 request->GetTotalReceivedBytes());
6532 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6533 request->raw_header_size());
Wez0e717112018-06-18 23:09:226534
6535 // Pump the message loop to allow all data to be consumed.
6536 base::RunLoop().RunUntilIdle();
6537
allada71b2efb2016-09-09 04:57:486538 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6539 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6540}
6541
6542TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416543 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486544 HostPortPair::FromString("mail.example.org:443"));
6545
6546 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526547 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236548 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436549 mock_quic_data.AddWrite(
6550 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6551 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136552 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486553 headers["user-agent"] = "";
6554 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436555 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336556 SYNCHRONOUS,
6557 ConstructClientRequestHeadersPacket(
6558 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6559 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486560
Ryan Hamilton8d9ee76e2018-05-29 23:52:526561 quic::QuicStreamOffset server_header_offset = 0;
6562 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486563
Zhongyi Shi32f2fd02018-04-16 18:23:436564 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336565 ASYNC, ConstructServerPushPromisePacket(
6566 1, GetNthClientInitiatedBidirectionalStreamId(0),
6567 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6568 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6569 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486570
Yixin Wangb470bc882018-02-15 18:43:576571 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266572 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336573 mock_quic_data.AddWrite(SYNCHRONOUS,
6574 ConstructClientPriorityPacket(
6575 client_packet_number++, false,
6576 GetNthServerInitiatedUnidirectionalStreamId(0),
6577 GetNthClientInitiatedBidirectionalStreamId(0),
6578 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576579 }
6580
allada71b2efb2016-09-09 04:57:486581 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436582 mock_quic_data.AddRead(
6583 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336584 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436585 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486586 expected_raw_header_response_size =
6587 server_header_offset - expected_raw_header_response_size;
6588
Yixin Wangb470bc882018-02-15 18:43:576589 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436590 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486591
ckrasicbf2f59c2017-05-04 23:54:366592 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436593 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336594 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6595 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:436596 std::string header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436597 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336598 ASYNC, ConstructServerDataPacket(
6599 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416600 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486601
Yixin Wangb470bc882018-02-15 18:43:576602 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436603 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Victor Vasiliev076657c2019-03-12 02:46:436604 std::string header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366605 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336606 ASYNC, ConstructServerDataPacket(
6607 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416608 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486609
Zhongyi Shi32f2fd02018-04-16 18:23:436610 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486611
6612 CreateSession();
6613
6614 TestDelegate delegate;
6615 QuicURLRequestContext quic_url_request_context(std::move(session_),
6616 &socket_factory_);
6617
6618 mock_quic_data.AddSocketDataToFactory(
6619 &quic_url_request_context.socket_factory());
6620 TestNetworkDelegate network_delegate;
6621 quic_url_request_context.set_network_delegate(&network_delegate);
6622
6623 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296624 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6625 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486626 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6627 &ssl_data_);
6628
6629 request->Start();
Wez2a31b222018-06-07 22:07:156630 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486631
6632 EXPECT_LT(0, request->GetTotalSentBytes());
6633 EXPECT_LT(0, request->GetTotalReceivedBytes());
6634 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6635 request->GetTotalSentBytes());
6636 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6637 request->GetTotalReceivedBytes());
6638 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6639 request->raw_header_size());
Wez0e717112018-06-18 23:09:226640
6641 // Pump the message loop to allow all data to be consumed.
6642 base::RunLoop().RunUntilIdle();
6643
allada71b2efb2016-09-09 04:57:486644 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6645 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6646}
6647
Yixin Wang10f477ed2017-11-21 04:20:206648TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6649 session_params_.quic_host_whitelist.insert("mail.example.org");
6650
6651 MockRead http_reads[] = {
6652 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6653 MockRead("hello world"),
6654 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6655 MockRead(ASYNC, OK)};
6656
Ryan Sleevib8d7ea02018-05-07 20:01:016657 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206658 socket_factory_.AddSocketDataProvider(&http_data);
6659 AddCertificate(&ssl_data_);
6660 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6661
6662 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526663 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206664 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436665 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6666 mock_quic_data.AddWrite(
6667 SYNCHRONOUS,
6668 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336669 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436670 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436671 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336672 ASYNC, ConstructServerResponseHeadersPacket(
6673 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6674 GetResponseHeaders("200 OK")));
Victor Vasiliev076657c2019-03-12 02:46:436675 std::string header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336676 mock_quic_data.AddRead(
6677 ASYNC, ConstructServerDataPacket(
6678 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416679 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436680 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206681 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6682 mock_quic_data.AddRead(ASYNC, 0); // EOF
6683
6684 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6685
6686 AddHangingNonAlternateProtocolSocketData();
6687 CreateSession();
6688
6689 SendRequestAndExpectHttpResponse("hello world");
6690 SendRequestAndExpectQuicResponse("hello!");
6691}
6692
6693TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6694 session_params_.quic_host_whitelist.insert("mail.example.com");
6695
6696 MockRead http_reads[] = {
6697 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6698 MockRead("hello world"),
6699 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6700 MockRead(ASYNC, OK)};
6701
Ryan Sleevib8d7ea02018-05-07 20:01:016702 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206703 socket_factory_.AddSocketDataProvider(&http_data);
6704 AddCertificate(&ssl_data_);
6705 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6706 socket_factory_.AddSocketDataProvider(&http_data);
6707 AddCertificate(&ssl_data_);
6708 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6709
6710 AddHangingNonAlternateProtocolSocketData();
6711 CreateSession();
6712
6713 SendRequestAndExpectHttpResponse("hello world");
6714 SendRequestAndExpectHttpResponse("hello world");
6715}
6716
bnc359ed2a2016-04-29 20:43:456717class QuicNetworkTransactionWithDestinationTest
6718 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016719 public ::testing::WithParamInterface<PoolingTestParams>,
6720 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456721 protected:
6722 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556723 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056724 client_headers_include_h2_stream_dependency_(
6725 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526726 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456727 destination_type_(GetParam().destination_type),
6728 cert_transparency_verifier_(new MultiLogCTVerifier()),
6729 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596730 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
Eric Orthbe2efac2019-03-06 01:11:116731 auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
bnc359ed2a2016-04-29 20:43:456732 random_generator_(0),
6733 ssl_data_(ASYNC, OK) {}
6734
6735 void SetUp() override {
6736 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556737 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456738
mmenke6ddfbea2017-05-31 21:48:416739 HttpNetworkSession::Params session_params;
6740 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346741 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446742 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056743 session_params.quic_headers_include_h2_stream_dependency =
6744 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416745
6746 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456747
Ryan Hamilton8d9ee76e2018-05-29 23:52:526748 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416749 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456750
6751 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276752 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416753 session_context.quic_crypto_client_stream_factory =
6754 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456755
mmenke6ddfbea2017-05-31 21:48:416756 session_context.quic_random = &random_generator_;
6757 session_context.client_socket_factory = &socket_factory_;
6758 session_context.host_resolver = &host_resolver_;
6759 session_context.cert_verifier = &cert_verifier_;
6760 session_context.transport_security_state = &transport_security_state_;
6761 session_context.cert_transparency_verifier =
6762 cert_transparency_verifier_.get();
6763 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6764 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456765 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416766 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596767 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416768 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6769 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456770
mmenke6ddfbea2017-05-31 21:48:416771 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456772 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456773 }
6774
6775 void TearDown() override {
6776 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6777 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556778 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456779 PlatformTest::TearDown();
6780 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556781 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406782 session_.reset();
bnc359ed2a2016-04-29 20:43:456783 }
6784
zhongyie537a002017-06-27 16:48:216785 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456786 HostPortPair destination;
6787 switch (destination_type_) {
6788 case SAME_AS_FIRST:
6789 destination = HostPortPair(origin1_, 443);
6790 break;
6791 case SAME_AS_SECOND:
6792 destination = HostPortPair(origin2_, 443);
6793 break;
6794 case DIFFERENT:
6795 destination = HostPortPair(kDifferentHostname, 443);
6796 break;
6797 }
bnc3472afd2016-11-17 15:27:216798 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456799 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216800 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456801 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446802 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456803 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526804 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236805 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526806 quic::QuicStreamId stream_id,
6807 bool should_include_version,
6808 quic::QuicStreamOffset* offset,
6809 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486810 return ConstructClientRequestHeadersPacket(
6811 packet_number, stream_id, should_include_version, 0, offset, maker);
6812 }
bnc359ed2a2016-04-29 20:43:456813
Ryan Hamilton8d9ee76e2018-05-29 23:52:526814 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236815 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526816 quic::QuicStreamId stream_id,
6817 bool should_include_version,
6818 quic::QuicStreamId parent_stream_id,
6819 quic::QuicStreamOffset* offset,
6820 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136821 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456822 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136823 spdy::SpdyHeaderBlock headers(
6824 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456825 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6826 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486827 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456828 }
6829
Ryan Hamilton8d9ee76e2018-05-29 23:52:526830 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236831 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526832 quic::QuicStreamId stream_id,
6833 bool should_include_version,
6834 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586835 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456836 packet_number, stream_id, should_include_version, nullptr, maker);
6837 }
6838
Ryan Hamilton8d9ee76e2018-05-29 23:52:526839 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236840 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526841 quic::QuicStreamId stream_id,
6842 quic::QuicStreamOffset* offset,
6843 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136844 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456845 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266846 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456847 }
6848
Ryan Hamilton8d9ee76e2018-05-29 23:52:526849 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236850 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526851 quic::QuicStreamId stream_id,
6852 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586853 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6854 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456855 }
6856
Ryan Hamilton8d9ee76e2018-05-29 23:52:526857 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236858 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526859 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456860 QuicTestPacketMaker* maker) {
Victor Vasiliev076657c2019-03-12 02:46:436861 std::string header = "";
Renjief49758b2019-01-11 23:32:416862 if (version_ == quic::QUIC_VERSION_99) {
6863 quic::HttpEncoder encoder;
6864 std::unique_ptr<char[]> buffer;
6865 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
Victor Vasiliev076657c2019-03-12 02:46:436866 header = std::string(buffer.get(), header_length);
Renjief49758b2019-01-11 23:32:416867 }
bnc359ed2a2016-04-29 20:43:456868 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416869 header + "hello");
bnc359ed2a2016-04-29 20:43:456870 }
6871
Ryan Hamilton8d9ee76e2018-05-29 23:52:526872 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236873 uint64_t packet_number,
6874 uint64_t largest_received,
6875 uint64_t smallest_received,
6876 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456877 QuicTestPacketMaker* maker) {
6878 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496879 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456880 }
6881
Ryan Hamilton8d9ee76e2018-05-29 23:52:526882 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236883 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526884 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376885 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366886 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376887 }
6888
bnc359ed2a2016-04-29 20:43:456889 void AddRefusedSocketData() {
6890 std::unique_ptr<StaticSocketDataProvider> refused_data(
6891 new StaticSocketDataProvider());
6892 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6893 refused_data->set_connect_data(refused_connect);
6894 socket_factory_.AddSocketDataProvider(refused_data.get());
6895 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6896 }
6897
6898 void AddHangingSocketData() {
6899 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6900 new StaticSocketDataProvider());
6901 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6902 hanging_data->set_connect_data(hanging_connect);
6903 socket_factory_.AddSocketDataProvider(hanging_data.get());
6904 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6905 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6906 }
6907
6908 bool AllDataConsumed() {
6909 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6910 if (!socket_data_ptr->AllReadDataConsumed() ||
6911 !socket_data_ptr->AllWriteDataConsumed()) {
6912 return false;
6913 }
6914 }
6915 return true;
6916 }
6917
6918 void SendRequestAndExpectQuicResponse(const std::string& host) {
6919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6920 HttpRequestInfo request;
6921 std::string url("https://");
6922 url.append(host);
6923 request.url = GURL(url);
6924 request.load_flags = 0;
6925 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106926 request.traffic_annotation =
6927 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456928 TestCompletionCallback callback;
6929 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016930 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456931
6932 std::string response_data;
robpercival214763f2016-07-01 23:27:016933 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456934 EXPECT_EQ("hello", response_data);
6935
6936 const HttpResponseInfo* response = trans.GetResponseInfo();
6937 ASSERT_TRUE(response != nullptr);
6938 ASSERT_TRUE(response->headers.get() != nullptr);
6939 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6940 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526941 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446942 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456943 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376944 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456945 }
6946
Fan Yang32c5a112018-12-10 20:06:336947 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
6948 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366949 }
6950
Ryan Hamilton8d9ee76e2018-05-29 23:52:526951 quic::MockClock clock_;
6952 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056953 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526954 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456955 DestinationType destination_type_;
6956 std::string origin1_;
6957 std::string origin2_;
6958 std::unique_ptr<HttpNetworkSession> session_;
6959 MockClientSocketFactory socket_factory_;
6960 MockHostResolver host_resolver_;
6961 MockCertVerifier cert_verifier_;
6962 TransportSecurityState transport_security_state_;
6963 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236964 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456965 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076966 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596967 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456968 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526969 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456970 HttpServerPropertiesImpl http_server_properties_;
6971 BoundTestNetLog net_log_;
6972 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6973 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6974 static_socket_data_provider_vector_;
6975 SSLSocketDataProvider ssl_data_;
6976};
6977
Victor Costane635086f2019-01-27 05:20:306978INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6979 QuicNetworkTransactionWithDestinationTest,
6980 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:456981
6982// A single QUIC request fails because the certificate does not match the origin
6983// hostname, regardless of whether it matches the alternative service hostname.
6984TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6985 if (destination_type_ == DIFFERENT)
6986 return;
6987
6988 GURL url("https://mail.example.com/");
6989 origin1_ = url.host();
6990
6991 // Not used for requests, but this provides a test case where the certificate
6992 // is valid for the hostname of the alternative service.
6993 origin2_ = "mail.example.org";
6994
zhongyie537a002017-06-27 16:48:216995 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456996
6997 scoped_refptr<X509Certificate> cert(
6998 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246999 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7000 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457001
7002 ProofVerifyDetailsChromium verify_details;
7003 verify_details.cert_verify_result.verified_cert = cert;
7004 verify_details.cert_verify_result.is_issued_by_known_root = true;
7005 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7006
7007 MockQuicData mock_quic_data;
7008 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7009 mock_quic_data.AddRead(ASYNC, 0);
7010
7011 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7012
7013 AddRefusedSocketData();
7014
7015 HttpRequestInfo request;
7016 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107017 request.traffic_annotation =
7018 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457019
7020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7021 TestCompletionCallback callback;
7022 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017023 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457024
7025 EXPECT_TRUE(AllDataConsumed());
7026}
7027
7028// First request opens QUIC session to alternative service. Second request
7029// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527030// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457031TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7032 origin1_ = "mail.example.org";
7033 origin2_ = "news.example.org";
7034
zhongyie537a002017-06-27 16:48:217035 SetQuicAlternativeService(origin1_);
7036 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457037
7038 scoped_refptr<X509Certificate> cert(
7039 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247040 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7041 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7042 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457043
7044 ProofVerifyDetailsChromium verify_details;
7045 verify_details.cert_verify_result.verified_cert = cert;
7046 verify_details.cert_verify_result.is_issued_by_known_root = true;
7047 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7048
Yixin Wang079ad542018-01-11 04:06:057049 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177050 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7051 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057052 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177053 QuicTestPacketMaker server_maker(
7054 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7055 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457056
Ryan Hamilton8d9ee76e2018-05-29 23:52:527057 quic::QuicStreamOffset request_header_offset(0);
7058 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457059
7060 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057061 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437062 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057063 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337064 mock_quic_data.AddWrite(
7065 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7066 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7067 &request_header_offset, &client_maker));
7068 mock_quic_data.AddRead(ASYNC,
7069 ConstructServerResponseHeadersPacket(
7070 1, GetNthClientInitiatedBidirectionalStreamId(0),
7071 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437072 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337073 ASYNC,
7074 ConstructServerDataPacket(
7075 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437076 mock_quic_data.AddWrite(SYNCHRONOUS,
7077 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457078
Yixin Wang079ad542018-01-11 04:06:057079 client_maker.set_hostname(origin2_);
7080 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457081
Zhongyi Shi32f2fd02018-04-16 18:23:437082 mock_quic_data.AddWrite(
7083 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337084 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7085 GetNthClientInitiatedBidirectionalStreamId(0),
7086 &request_header_offset, &client_maker));
7087 mock_quic_data.AddRead(ASYNC,
7088 ConstructServerResponseHeadersPacket(
7089 3, GetNthClientInitiatedBidirectionalStreamId(1),
7090 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437091 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337092 ASYNC,
7093 ConstructServerDataPacket(
7094 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437095 mock_quic_data.AddWrite(SYNCHRONOUS,
7096 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457097 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7098 mock_quic_data.AddRead(ASYNC, 0); // EOF
7099
7100 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7101
7102 AddHangingSocketData();
7103 AddHangingSocketData();
7104
Fan Yangc9e00dc2018-10-09 14:17:567105 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7106 QuicStreamFactoryPeer::SetAlarmFactory(
7107 session_->quic_stream_factory(),
7108 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7109 &clock_));
7110
bnc359ed2a2016-04-29 20:43:457111 SendRequestAndExpectQuicResponse(origin1_);
7112 SendRequestAndExpectQuicResponse(origin2_);
7113
7114 EXPECT_TRUE(AllDataConsumed());
7115}
7116
7117// First request opens QUIC session to alternative service. Second request does
7118// not pool to it, even though destination matches, because certificate is not
7119// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527120// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457121TEST_P(QuicNetworkTransactionWithDestinationTest,
7122 DoNotPoolIfCertificateInvalid) {
7123 origin1_ = "news.example.org";
7124 origin2_ = "mail.example.com";
7125
zhongyie537a002017-06-27 16:48:217126 SetQuicAlternativeService(origin1_);
7127 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457128
7129 scoped_refptr<X509Certificate> cert1(
7130 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247131 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7132 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7133 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457134
7135 scoped_refptr<X509Certificate> cert2(
7136 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247137 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7138 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457139
7140 ProofVerifyDetailsChromium verify_details1;
7141 verify_details1.cert_verify_result.verified_cert = cert1;
7142 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7143 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7144
7145 ProofVerifyDetailsChromium verify_details2;
7146 verify_details2.cert_verify_result.verified_cert = cert2;
7147 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7148 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7149
Yixin Wang079ad542018-01-11 04:06:057150 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177151 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7152 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057153 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177154 QuicTestPacketMaker server_maker1(
7155 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7156 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457157
7158 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527159 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457160 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437161 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7162 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337163 mock_quic_data1.AddWrite(
7164 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7165 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7166 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437167 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337168 ASYNC,
7169 ConstructServerResponseHeadersPacket(
7170 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437171 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337172 ASYNC,
7173 ConstructServerDataPacket(
7174 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437175 mock_quic_data1.AddWrite(
7176 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457177 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7178 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7179
7180 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7181
Yixin Wang079ad542018-01-11 04:06:057182 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177183 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7184 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057185 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177186 QuicTestPacketMaker server_maker2(
7187 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7188 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457189
7190 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527191 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457192 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437193 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7194 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337195 mock_quic_data2.AddWrite(
7196 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7197 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7198 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437199 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337200 ASYNC,
7201 ConstructServerResponseHeadersPacket(
7202 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437203 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337204 ASYNC,
7205 ConstructServerDataPacket(
7206 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437207 mock_quic_data2.AddWrite(
7208 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457209 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7210 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7211
7212 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7213
bnc359ed2a2016-04-29 20:43:457214 SendRequestAndExpectQuicResponse(origin1_);
7215 SendRequestAndExpectQuicResponse(origin2_);
7216
7217 EXPECT_TRUE(AllDataConsumed());
7218}
7219
ckrasicdee37572017-04-06 22:42:277220// crbug.com/705109 - this confirms that matching request with a body
7221// triggers a crash (pre-fix).
7222TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417223 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277224 HostPortPair::FromString("mail.example.org:443"));
7225
7226 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527227 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237228 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437229 mock_quic_data.AddWrite(
7230 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7231 &header_stream_offset));
7232 mock_quic_data.AddWrite(
7233 SYNCHRONOUS,
7234 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337235 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7236 true, true, GetRequestHeaders("GET", "https", "/"),
7237 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527238 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437239 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337240 ASYNC, ConstructServerPushPromisePacket(
7241 1, GetNthClientInitiatedBidirectionalStreamId(0),
7242 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7243 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7244 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577245 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267246 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337247 mock_quic_data.AddWrite(SYNCHRONOUS,
7248 ConstructClientPriorityPacket(
7249 client_packet_number++, false,
7250 GetNthServerInitiatedUnidirectionalStreamId(0),
7251 GetNthClientInitiatedBidirectionalStreamId(0),
7252 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577253 }
Zhongyi Shi32f2fd02018-04-16 18:23:437254 mock_quic_data.AddRead(
7255 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337256 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437257 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577258 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437259 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7260 mock_quic_data.AddRead(
7261 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337262 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7263 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437264 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437265 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337266 ASYNC, ConstructServerDataPacket(
7267 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417268 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577269 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437270 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417271
Victor Vasiliev076657c2019-03-12 02:46:437272 std::string header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437273 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337274 ASYNC, ConstructServerDataPacket(
7275 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417276 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277277
7278 // Because the matching request has a body, we will see the push
7279 // stream get cancelled, and the matching request go out on the
7280 // wire.
Fan Yang32c5a112018-12-10 20:06:337281 mock_quic_data.AddWrite(SYNCHRONOUS,
7282 ConstructClientAckAndRstPacket(
7283 client_packet_number++,
7284 GetNthServerInitiatedUnidirectionalStreamId(0),
7285 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277286 const char kBody[] = "1";
Victor Vasiliev076657c2019-03-12 02:46:437287 std::string header3 = ConstructDataHeader(1);
Renjief49758b2019-01-11 23:32:417288 if (version_ != quic::QUIC_VERSION_99) {
7289 mock_quic_data.AddWrite(
7290 SYNCHRONOUS,
7291 ConstructClientRequestHeadersAndDataFramesPacket(
7292 client_packet_number++,
7293 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7294 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7295 GetNthServerInitiatedUnidirectionalStreamId(0),
7296 &header_stream_offset, nullptr, {kBody}));
7297 } else {
7298 mock_quic_data.AddWrite(
7299 SYNCHRONOUS,
7300 ConstructClientRequestHeadersAndDataFramesPacket(
7301 client_packet_number++,
7302 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7303 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7304 GetNthServerInitiatedUnidirectionalStreamId(0),
7305 &header_stream_offset, nullptr, {header3, kBody}));
7306 }
ckrasicdee37572017-04-06 22:42:277307
7308 // We see the same response as for the earlier pushed and cancelled
7309 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437310 mock_quic_data.AddRead(
7311 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337312 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437313 GetResponseHeaders("200 OK"), &server_header_offset));
7314 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337315 ASYNC, ConstructServerDataPacket(
7316 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417317 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277318
Yixin Wangb470bc882018-02-15 18:43:577319 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437320 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277321 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7322 mock_quic_data.AddRead(ASYNC, 0); // EOF
7323 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7324
7325 // The non-alternate protocol job needs to hang in order to guarantee that
7326 // the alternate-protocol job will "win".
7327 AddHangingNonAlternateProtocolSocketData();
7328
7329 CreateSession();
7330
7331 // PUSH_PROMISE handling in the http layer gets exercised here.
7332 SendRequestAndExpectQuicResponse("hello!");
7333
7334 request_.url = GURL("https://mail.example.org/pushed.jpg");
7335 ChunkedUploadDataStream upload_data(0);
7336 upload_data.AppendData("1", 1, true);
7337 request_.upload_data_stream = &upload_data;
7338 SendRequestAndExpectQuicResponse("and hello!");
7339}
7340
Bence Béky7538a952018-02-01 16:59:527341// Regression test for https://crbug.com/797825: If pushed headers describe a
7342// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7343// not be called (otherwise a DCHECK fails).
7344TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137345 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527346 pushed_request_headers[":authority"] = "";
7347 pushed_request_headers[":method"] = "GET";
7348 pushed_request_headers[":path"] = "/";
7349 pushed_request_headers[":scheme"] = "nosuchscheme";
7350
7351 session_params_.origins_to_force_quic_on.insert(
7352 HostPortPair::FromString("mail.example.org:443"));
7353
7354 MockQuicData mock_quic_data;
7355
Ryan Hamilton8d9ee76e2018-05-29 23:52:527356 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527357 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437358 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7359 mock_quic_data.AddWrite(
7360 SYNCHRONOUS,
7361 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337362 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437363 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527364
Ryan Hamilton8d9ee76e2018-05-29 23:52:527365 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337366 mock_quic_data.AddRead(
7367 ASYNC, ConstructServerPushPromisePacket(
7368 1, GetNthClientInitiatedBidirectionalStreamId(0),
7369 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7370 std::move(pushed_request_headers), &server_header_offset,
7371 &server_maker_));
7372 mock_quic_data.AddWrite(SYNCHRONOUS,
7373 ConstructClientRstPacket(
7374 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7375 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527376
Zhongyi Shi32f2fd02018-04-16 18:23:437377 mock_quic_data.AddRead(
7378 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337379 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437380 GetResponseHeaders("200 OK"), &server_header_offset));
7381 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527382
Zhongyi Shi32f2fd02018-04-16 18:23:437383 mock_quic_data.AddRead(
7384 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337385 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7386 false, GetResponseHeaders("200 OK"), &server_header_offset));
Victor Vasiliev076657c2019-03-12 02:46:437387 std::string header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437388 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337389 ASYNC, ConstructServerDataPacket(
7390 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417391 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437392 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527393
7394 mock_quic_data.AddRead(ASYNC, 0);
7395 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7396
7397 // The non-alternate protocol job needs to hang in order to guarantee that
7398 // the alternate-protocol job will "win".
7399 AddHangingNonAlternateProtocolSocketData();
7400
7401 CreateSession();
7402
7403 // PUSH_PROMISE handling in the http layer gets exercised here.
7404 SendRequestAndExpectQuicResponse("hello!");
7405
7406 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7407 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7408}
7409
Yixin Wang46a273ec302018-01-23 17:59:567410// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147411TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567412 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147413 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567414 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497415 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567416
7417 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527418 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567419 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357420 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337421 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357422 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7423 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7424 false, ConnectRequestHeaders("mail.example.org:443"),
7425 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337426 mock_quic_data.AddRead(
7427 ASYNC, ConstructServerResponseHeadersPacket(
7428 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7429 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567430
7431 const char get_request[] =
7432 "GET / HTTP/1.1\r\n"
7433 "Host: mail.example.org\r\n"
7434 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437435 std::string header = ConstructDataHeader(strlen(get_request));
Renjief49758b2019-01-11 23:32:417436 if (version_ != quic::QUIC_VERSION_99) {
7437 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357438 SYNCHRONOUS,
7439 ConstructClientAckAndDataPacket(
7440 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7441 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417442 } else {
7443 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417444 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357445 ConstructClientAckAndMultipleDataFramesPacket(
7446 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437447 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417448 }
7449
Yixin Wang46a273ec302018-01-23 17:59:567450 const char get_response[] =
7451 "HTTP/1.1 200 OK\r\n"
7452 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437453 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437454 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337455 ASYNC, ConstructServerDataPacket(
7456 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437457 0, header2 + std::string(get_response)));
7458 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337459 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417460 SYNCHRONOUS, ConstructServerDataPacket(
7461 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7462 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437463 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357464 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567465 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7466
7467 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417468 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357469 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7470 quic::QUIC_STREAM_CANCELLED,
7471 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567472
7473 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7474
7475 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7476
7477 CreateSession();
7478
7479 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097480 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567481 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7482 HeadersHandler headers_handler;
7483 trans.SetBeforeHeadersSentCallback(
7484 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7485 base::Unretained(&headers_handler)));
7486 RunTransaction(&trans);
7487 CheckWasHttpResponse(&trans);
7488 CheckResponsePort(&trans, 70);
7489 CheckResponseData(&trans, "0123456789");
7490 EXPECT_TRUE(headers_handler.was_proxied());
7491 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7492
7493 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7494 // proxy socket to disconnect.
7495 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7496
7497 base::RunLoop().RunUntilIdle();
7498 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7499 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7500}
7501
7502// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147503TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567504 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147505 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567506 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497507 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567508
7509 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527510 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567511 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357512 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337513 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357514 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7515 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7516 false, ConnectRequestHeaders("mail.example.org:443"),
7517 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337518 mock_quic_data.AddRead(
7519 ASYNC, ConstructServerResponseHeadersPacket(
7520 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7521 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567522
7523 SpdyTestUtil spdy_util;
7524
Ryan Hamilton0239aac2018-05-19 00:03:137525 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567526 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437527 std::string header = ConstructDataHeader(get_frame.size());
Renjief49758b2019-01-11 23:32:417528 if (version_ != quic::QUIC_VERSION_99) {
7529 mock_quic_data.AddWrite(
7530 SYNCHRONOUS,
7531 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357532 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7533 false, 0,
Renjief49758b2019-01-11 23:32:417534 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7535 } else {
7536 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417537 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357538 ConstructClientAckAndMultipleDataFramesPacket(
7539 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7540 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437541 {header, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417542 }
Ryan Hamilton0239aac2018-05-19 00:03:137543 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567544 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437545 std::string header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437546 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337547 ASYNC,
7548 ConstructServerDataPacket(
7549 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437550 header2 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567551
Ryan Hamilton0239aac2018-05-19 00:03:137552 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197553 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Victor Vasiliev076657c2019-03-12 02:46:437554 std::string header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437555 mock_quic_data.AddRead(
7556 SYNCHRONOUS,
7557 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337558 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417559 resp_frame.size() + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437560 header3 + std::string(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357561 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567562 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7563
7564 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437565 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357566 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7567 quic::QUIC_STREAM_CANCELLED,
7568 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567569
7570 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7571
7572 SSLSocketDataProvider ssl_data(ASYNC, OK);
7573 ssl_data.next_proto = kProtoHTTP2;
7574 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7575
7576 CreateSession();
7577
7578 request_.url = GURL("https://mail.example.org/");
7579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7580 HeadersHandler headers_handler;
7581 trans.SetBeforeHeadersSentCallback(
7582 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7583 base::Unretained(&headers_handler)));
7584 RunTransaction(&trans);
7585 CheckWasSpdyResponse(&trans);
7586 CheckResponsePort(&trans, 70);
7587 CheckResponseData(&trans, "0123456789");
7588 EXPECT_TRUE(headers_handler.was_proxied());
7589 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7590
Wez0e717112018-06-18 23:09:227591 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7592 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567593 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7594
7595 base::RunLoop().RunUntilIdle();
7596 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7597 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7598}
7599
7600// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7601// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147602TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567603 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147604 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567605 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497606 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567607
7608 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527609 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417610 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567611 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417612 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7613 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337614 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417615 SYNCHRONOUS,
7616 ConstructClientRequestHeadersPacket(
7617 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7618 true, false, ConnectRequestHeaders("mail.example.org:443"),
7619 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337620 mock_quic_data.AddRead(
7621 ASYNC, ConstructServerResponseHeadersPacket(
7622 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7623 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567624
Ryan Hamilton8d9ee76e2018-05-29 23:52:527625 quic::QuicStreamOffset client_data_offset = 0;
7626 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567627 const char get_request_1[] =
7628 "GET / HTTP/1.1\r\n"
7629 "Host: mail.example.org\r\n"
7630 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437631 std::string header = ConstructDataHeader(strlen(get_request_1));
Renjief49758b2019-01-11 23:32:417632 if (version_ != quic::QUIC_VERSION_99) {
7633 mock_quic_data.AddWrite(
7634 SYNCHRONOUS,
7635 ConstructClientAckAndDataPacket(
7636 write_packet_index++, false,
7637 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7638 client_data_offset, quic::QuicStringPiece(get_request_1)));
7639 } else {
7640 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417641 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357642 ConstructClientAckAndMultipleDataFramesPacket(
7643 write_packet_index++, false,
7644 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
Victor Vasiliev076657c2019-03-12 02:46:437645 client_data_offset, {header, std::string(get_request_1)}));
Renjief49758b2019-01-11 23:32:417646 }
7647
7648 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567649
7650 const char get_response_1[] =
7651 "HTTP/1.1 200 OK\r\n"
7652 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437653 std::string header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437654 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437655 ASYNC, ConstructServerDataPacket(
7656 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7657 server_data_offset, header2 + std::string(get_response_1)));
Renjief49758b2019-01-11 23:32:417658 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567659
Victor Vasiliev076657c2019-03-12 02:46:437660 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337661 mock_quic_data.AddRead(
7662 SYNCHRONOUS,
7663 ConstructServerDataPacket(
7664 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437665 server_data_offset, header3 + std::string("0123456789")));
Renjief49758b2019-01-11 23:32:417666 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567667
Renjief49758b2019-01-11 23:32:417668 mock_quic_data.AddWrite(
7669 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567670
7671 const char get_request_2[] =
7672 "GET /2 HTTP/1.1\r\n"
7673 "Host: mail.example.org\r\n"
7674 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437675 std::string header4 = ConstructDataHeader(strlen(get_request_2));
Renjief49758b2019-01-11 23:32:417676 if (version_ == quic::QUIC_VERSION_99) {
7677 mock_quic_data.AddWrite(
7678 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357679 ConstructClientMultipleDataFramesPacket(
7680 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7681 false, false, client_data_offset,
Victor Vasiliev076657c2019-03-12 02:46:437682 {header4, std::string(get_request_2)}));
Renjied172e812019-01-16 05:12:357683 client_data_offset += header4.length() + strlen(get_request_2);
7684 } else {
7685 mock_quic_data.AddWrite(
7686 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417687 ConstructClientDataPacket(write_packet_index++,
7688 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357689 false, false, client_data_offset,
7690 quic::QuicStringPiece(get_request_2)));
7691 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417692 }
Yixin Wang46a273ec302018-01-23 17:59:567693
7694 const char get_response_2[] =
7695 "HTTP/1.1 200 OK\r\n"
7696 "Content-Length: 7\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437697 std::string header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437698 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437699 ASYNC, ConstructServerDataPacket(
7700 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7701 server_data_offset, header5 + std::string(get_response_2)));
Renjief49758b2019-01-11 23:32:417702 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567703
Victor Vasiliev076657c2019-03-12 02:46:437704 std::string header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527705 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337706 SYNCHRONOUS,
7707 ConstructServerDataPacket(
7708 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437709 server_data_offset, header6 + std::string("0123456")));
Renjief49758b2019-01-11 23:32:417710 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567711
Renjief49758b2019-01-11 23:32:417712 mock_quic_data.AddWrite(
7713 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567714 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7715
Renjief49758b2019-01-11 23:32:417716 mock_quic_data.AddWrite(
7717 SYNCHRONOUS,
7718 ConstructClientRstPacket(
7719 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7720 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567721
7722 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7723
7724 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7725
7726 CreateSession();
7727
7728 request_.url = GURL("https://mail.example.org/");
7729 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7730 HeadersHandler headers_handler_1;
7731 trans_1.SetBeforeHeadersSentCallback(
7732 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7733 base::Unretained(&headers_handler_1)));
7734 RunTransaction(&trans_1);
7735 CheckWasHttpResponse(&trans_1);
7736 CheckResponsePort(&trans_1, 70);
7737 CheckResponseData(&trans_1, "0123456789");
7738 EXPECT_TRUE(headers_handler_1.was_proxied());
7739 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7740
7741 request_.url = GURL("https://mail.example.org/2");
7742 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7743 HeadersHandler headers_handler_2;
7744 trans_2.SetBeforeHeadersSentCallback(
7745 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7746 base::Unretained(&headers_handler_2)));
7747 RunTransaction(&trans_2);
7748 CheckWasHttpResponse(&trans_2);
7749 CheckResponsePort(&trans_2, 70);
7750 CheckResponseData(&trans_2, "0123456");
7751 EXPECT_TRUE(headers_handler_2.was_proxied());
7752 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7753
7754 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7755 // proxy socket to disconnect.
7756 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7757
7758 base::RunLoop().RunUntilIdle();
7759 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7760 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7761}
7762
7763// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7764// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7765// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147766TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567767 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147768 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567769 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497770 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567771
7772 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527773 quic::QuicStreamOffset client_header_stream_offset = 0;
7774 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357775 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7776 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567777
7778 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337779 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357780 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7781 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7782 false, ConnectRequestHeaders("mail.example.org:443"),
7783 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437784 mock_quic_data.AddRead(
7785 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337786 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437787 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567788
7789 // GET request, response, and data over QUIC tunnel for first request
7790 const char get_request[] =
7791 "GET / HTTP/1.1\r\n"
7792 "Host: mail.example.org\r\n"
7793 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437794 std::string header = ConstructDataHeader(strlen(get_request));
Renjief49758b2019-01-11 23:32:417795 if (version_ != quic::QUIC_VERSION_99) {
7796 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357797 SYNCHRONOUS,
7798 ConstructClientAckAndDataPacket(
7799 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7800 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417801 } else {
7802 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417803 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357804 ConstructClientAckAndMultipleDataFramesPacket(
7805 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
Victor Vasiliev076657c2019-03-12 02:46:437806 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:417807 }
7808
Yixin Wang46a273ec302018-01-23 17:59:567809 const char get_response[] =
7810 "HTTP/1.1 200 OK\r\n"
7811 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:437812 std::string header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567813 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337814 ASYNC, ConstructServerDataPacket(
7815 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Victor Vasiliev076657c2019-03-12 02:46:437816 0, header2 + std::string(get_response)));
7817 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337818 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417819 SYNCHRONOUS, ConstructServerDataPacket(
7820 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7821 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:437822 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:357823 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567824
7825 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437826 mock_quic_data.AddWrite(
7827 SYNCHRONOUS,
7828 ConstructClientRequestHeadersPacket(
Renjied172e812019-01-16 05:12:357829 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7830 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:337831 GetNthClientInitiatedBidirectionalStreamId(0),
7832 &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 4, GetNthClientInitiatedBidirectionalStreamId(1), 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 second request
7839 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137840 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567841 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Victor Vasiliev076657c2019-03-12 02:46:437842 std::string header4 = ConstructDataHeader(get_frame.size());
Renjief49758b2019-01-11 23:32:417843 if (version_ != quic::QUIC_VERSION_99) {
7844 mock_quic_data.AddWrite(
7845 SYNCHRONOUS,
7846 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357847 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7848 false, 0,
Renjief49758b2019-01-11 23:32:417849 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7850 } else {
7851 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417852 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357853 ConstructClientAckAndMultipleDataFramesPacket(
7854 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7855 false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437856 {header4, std::string(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417857 }
Yixin Wang46a273ec302018-01-23 17:59:567858
Ryan Hamilton0239aac2018-05-19 00:03:137859 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567860 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Victor Vasiliev076657c2019-03-12 02:46:437861 std::string header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437862 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337863 ASYNC,
7864 ConstructServerDataPacket(
7865 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Victor Vasiliev076657c2019-03-12 02:46:437866 header5 + std::string(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567867
Ryan Hamilton0239aac2018-05-19 00:03:137868 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197869 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Victor Vasiliev076657c2019-03-12 02:46:437870 std::string header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437871 mock_quic_data.AddRead(
Victor Vasiliev076657c2019-03-12 02:46:437872 ASYNC, ConstructServerDataPacket(
7873 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7874 resp_frame.size() + header5.length(),
7875 header6 + std::string(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567876
Renjied172e812019-01-16 05:12:357877 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567878 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7879
7880 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417881 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357882 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7883 quic::QUIC_STREAM_CANCELLED,
7884 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567885 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437886 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357887 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7888 quic::QUIC_STREAM_CANCELLED,
7889 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567890
7891 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7892
7893 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7894
7895 SSLSocketDataProvider ssl_data(ASYNC, OK);
7896 ssl_data.next_proto = kProtoHTTP2;
7897 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7898
7899 CreateSession();
7900
7901 request_.url = GURL("https://mail.example.org/");
7902 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7903 HeadersHandler headers_handler_1;
7904 trans_1.SetBeforeHeadersSentCallback(
7905 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7906 base::Unretained(&headers_handler_1)));
7907 RunTransaction(&trans_1);
7908 CheckWasHttpResponse(&trans_1);
7909 CheckResponsePort(&trans_1, 70);
7910 CheckResponseData(&trans_1, "0123456789");
7911 EXPECT_TRUE(headers_handler_1.was_proxied());
7912 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7913
7914 request_.url = GURL("https://different.example.org/");
7915 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7916 HeadersHandler headers_handler_2;
7917 trans_2.SetBeforeHeadersSentCallback(
7918 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7919 base::Unretained(&headers_handler_2)));
7920 RunTransaction(&trans_2);
7921 CheckWasSpdyResponse(&trans_2);
7922 CheckResponsePort(&trans_2, 70);
7923 CheckResponseData(&trans_2, "0123456");
7924 EXPECT_TRUE(headers_handler_2.was_proxied());
7925 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7926
7927 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7928 // proxy socket to disconnect.
7929 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7930
7931 base::RunLoop().RunUntilIdle();
7932 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7933 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7934}
7935
7936// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147937TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567938 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147939 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567940 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497941 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567942
7943 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527944 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567945 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437946 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527947 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337948 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7949 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7950 false, ConnectRequestHeaders("mail.example.org:443"),
7951 &header_stream_offset));
7952 mock_quic_data.AddRead(
7953 ASYNC, ConstructServerResponseHeadersPacket(
7954 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7955 GetResponseHeaders("500")));
7956 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7957 mock_quic_data.AddWrite(SYNCHRONOUS,
7958 ConstructClientAckAndRstPacket(
7959 3, GetNthClientInitiatedBidirectionalStreamId(0),
7960 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567961
7962 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7963
7964 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7965
7966 CreateSession();
7967
7968 request_.url = GURL("https://mail.example.org/");
7969 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7970 HeadersHandler headers_handler;
7971 trans.SetBeforeHeadersSentCallback(
7972 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7973 base::Unretained(&headers_handler)));
7974 TestCompletionCallback callback;
7975 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7976 EXPECT_EQ(ERR_IO_PENDING, rv);
7977 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7978 EXPECT_EQ(false, headers_handler.was_proxied());
7979
7980 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7981 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7982}
7983
7984// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:147985TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:567986 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147987 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567988 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497989 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567990
7991 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527992 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567993 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437994 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337995 mock_quic_data.AddWrite(
7996 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7997 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7998 false, ConnectRequestHeaders("mail.example.org:443"),
7999 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568000 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8001
8002 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8003
8004 CreateSession();
8005
8006 request_.url = GURL("https://mail.example.org/");
8007 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8008 HeadersHandler headers_handler;
8009 trans.SetBeforeHeadersSentCallback(
8010 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8011 base::Unretained(&headers_handler)));
8012 TestCompletionCallback callback;
8013 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8014 EXPECT_EQ(ERR_IO_PENDING, rv);
8015 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8016
8017 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8018 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8019}
8020
8021// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8022// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148023TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568024 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148025 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568026 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498027 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568028
8029 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528030 quic::QuicStreamOffset client_header_stream_offset = 0;
8031 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358032 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8033 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338034 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358035 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8036 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8037 false, ConnectRequestHeaders("mail.example.org:443"),
8038 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438039 mock_quic_data.AddRead(
8040 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338041 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438042 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358043 mock_quic_data.AddWrite(SYNCHRONOUS,
8044 ConstructClientAckAndRstPacket(
8045 3, GetNthClientInitiatedBidirectionalStreamId(0),
8046 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568047
Zhongyi Shi32f2fd02018-04-16 18:23:438048 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358049 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8050 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8051 false, ConnectRequestHeaders("mail.example.org:443"),
8052 GetNthClientInitiatedBidirectionalStreamId(0),
8053 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438054 mock_quic_data.AddRead(
8055 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338056 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438057 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568058
8059 const char get_request[] =
8060 "GET / HTTP/1.1\r\n"
8061 "Host: mail.example.org\r\n"
8062 "Connection: keep-alive\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438063 std::string header = ConstructDataHeader(strlen(get_request));
Renjief49758b2019-01-11 23:32:418064 if (version_ != quic::QUIC_VERSION_99) {
8065 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358066 SYNCHRONOUS,
8067 ConstructClientAckAndDataPacket(
8068 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8069 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418070 } else {
8071 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418072 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358073 ConstructClientAckAndMultipleDataFramesPacket(
8074 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
Victor Vasiliev076657c2019-03-12 02:46:438075 false, 0, {header, std::string(get_request)}));
Renjief49758b2019-01-11 23:32:418076 }
Yixin Wang46a273ec302018-01-23 17:59:568077 const char get_response[] =
8078 "HTTP/1.1 200 OK\r\n"
8079 "Content-Length: 10\r\n\r\n";
Victor Vasiliev076657c2019-03-12 02:46:438080 std::string header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438081 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338082 ASYNC, ConstructServerDataPacket(
8083 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Victor Vasiliev076657c2019-03-12 02:46:438084 0, header2 + std::string(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528085
Victor Vasiliev076657c2019-03-12 02:46:438086 std::string header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338087 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418088 SYNCHRONOUS, ConstructServerDataPacket(
8089 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8090 false, strlen(get_response) + header2.length(),
Victor Vasiliev076657c2019-03-12 02:46:438091 header3 + std::string("0123456789")));
Renjied172e812019-01-16 05:12:358092 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568093 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8094
8095 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418096 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358097 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8098 quic::QUIC_STREAM_CANCELLED,
8099 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568100
8101 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8102
8103 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8104 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8105
8106 SSLSocketDataProvider ssl_data(ASYNC, OK);
8107 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8108
8109 CreateSession();
8110
8111 request_.url = GURL("https://mail.example.org/");
8112 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8113 HeadersHandler headers_handler;
8114 trans.SetBeforeHeadersSentCallback(
8115 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8116 base::Unretained(&headers_handler)));
8117 TestCompletionCallback callback;
8118 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8119 EXPECT_EQ(ERR_IO_PENDING, rv);
8120 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8121
8122 rv = trans.RestartIgnoringLastError(callback.callback());
8123 EXPECT_EQ(ERR_IO_PENDING, rv);
8124 EXPECT_EQ(OK, callback.WaitForResult());
8125
8126 CheckWasHttpResponse(&trans);
8127 CheckResponsePort(&trans, 70);
8128 CheckResponseData(&trans, "0123456789");
8129 EXPECT_EQ(true, headers_handler.was_proxied());
8130 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8131
8132 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8133 // proxy socket to disconnect.
8134 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8135
8136 base::RunLoop().RunUntilIdle();
8137 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8138 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8139}
8140
8141// Checks if a request's specified "user-agent" header shows up correctly in the
8142// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148143TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Matt Menked732ea42019-03-08 12:05:008144 const char kConfiguredUserAgent[] = "Configured User-Agent";
8145 const char kRequestUserAgent[] = "Request User-Agent";
Yixin Wang46a273ec302018-01-23 17:59:568146 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148147 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568148 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498149 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568150
8151 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528152 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568153 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438154 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568155
Ryan Hamilton0239aac2018-05-19 00:03:138156 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Matt Menked732ea42019-03-08 12:05:008157 headers["user-agent"] = kConfiguredUserAgent;
Fan Yang32c5a112018-12-10 20:06:338158 mock_quic_data.AddWrite(
8159 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8160 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8161 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568162 // Return an error, so the transaction stops here (this test isn't interested
8163 // in the rest).
8164 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8165
8166 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8167
Matt Menked732ea42019-03-08 12:05:008168 StaticHttpUserAgentSettings http_user_agent_settings(
8169 std::string() /* accept_language */, kConfiguredUserAgent);
8170 session_context_.http_user_agent_settings = &http_user_agent_settings;
Yixin Wang46a273ec302018-01-23 17:59:568171 CreateSession();
8172
8173 request_.url = GURL("https://mail.example.org/");
8174 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
Matt Menked732ea42019-03-08 12:05:008175 kRequestUserAgent);
Yixin Wang46a273ec302018-01-23 17:59:568176 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8177 HeadersHandler headers_handler;
8178 trans.SetBeforeHeadersSentCallback(
8179 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8180 base::Unretained(&headers_handler)));
8181 TestCompletionCallback callback;
8182 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8183 EXPECT_EQ(ERR_IO_PENDING, rv);
8184 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8185
8186 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8187 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8188}
8189
Yixin Wang00fc44c2018-01-23 21:12:208190// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8191// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148192TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208193 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148194 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208195 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498196 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208197
8198 const RequestPriority request_priority = MEDIUM;
8199
8200 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528201 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208202 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438203 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8204 mock_quic_data.AddWrite(
8205 SYNCHRONOUS,
8206 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338207 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8208 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438209 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208210 // Return an error, so the transaction stops here (this test isn't interested
8211 // in the rest).
8212 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8213
8214 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8215
8216 CreateSession();
8217
8218 request_.url = GURL("https://mail.example.org/");
8219 HttpNetworkTransaction trans(request_priority, session_.get());
8220 TestCompletionCallback callback;
8221 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8222 EXPECT_EQ(ERR_IO_PENDING, rv);
8223 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8224
8225 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8226 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8227}
8228
Matt Menkeedaf3b82019-03-14 21:39:448229// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8230// HTTP/2 stream dependency and weights given the request priority.
8231TEST_P(QuicNetworkTransactionTest, QuicProxyMultipleRequestsError) {
8232 session_params_.enable_quic = true;
8233 session_params_.enable_quic_proxies_for_https_urls = true;
8234 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
8235 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
8236
8237 const RequestPriority kRequestPriority = MEDIUM;
8238 const RequestPriority kRequestPriority2 = LOWEST;
8239
8240 MockQuicData mock_quic_data;
8241 quic::QuicStreamOffset header_stream_offset = 0;
8242 mock_quic_data.AddWrite(
8243 ASYNC, ConstructInitialSettingsPacket(1, &header_stream_offset));
8244 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
8245 // This should never be reached.
8246 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8247 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8248
8249 // Second connection attempt just fails - result doesn't really matter.
8250 MockQuicData mock_quic_data2;
8251 mock_quic_data2.AddConnect(SYNCHRONOUS, ERR_FAILED);
8252 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
8253
8254 int original_max_sockets_per_group =
8255 ClientSocketPoolManager::max_sockets_per_group(
8256 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8257 ClientSocketPoolManager::set_max_sockets_per_group(
8258 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8259 int original_max_sockets_per_pool =
8260 ClientSocketPoolManager::max_sockets_per_pool(
8261 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL);
8262 ClientSocketPoolManager::set_max_sockets_per_pool(
8263 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL, 1);
8264 CreateSession();
8265
8266 request_.url = GURL("https://mail.example.org/");
8267 HttpNetworkTransaction trans(kRequestPriority, session_.get());
8268 TestCompletionCallback callback;
8269 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8270 EXPECT_EQ(ERR_IO_PENDING, rv);
8271
8272 HttpRequestInfo request2;
8273 request2.url = GURL("https://mail.example.org/some/other/path/");
8274 request2.traffic_annotation =
8275 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8276
8277 HttpNetworkTransaction trans2(kRequestPriority2, session_.get());
8278 TestCompletionCallback callback2;
8279 int rv2 = trans2.Start(&request2, callback2.callback(), net_log_.bound());
8280 EXPECT_EQ(ERR_IO_PENDING, rv2);
8281
8282 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8283 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8284
8285 EXPECT_EQ(ERR_FAILED, callback2.WaitForResult());
8286
8287 ClientSocketPoolManager::set_max_sockets_per_pool(
8288 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8289 original_max_sockets_per_pool);
8290 ClientSocketPoolManager::set_max_sockets_per_group(
8291 HttpNetworkSession::SocketPoolType::NORMAL_SOCKET_POOL,
8292 original_max_sockets_per_group);
8293}
8294
Yixin Wang46a273ec302018-01-23 17:59:568295// Test the request-challenge-retry sequence for basic auth, over a QUIC
8296// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148297TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568298 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8299 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138300 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568301 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8302
8303 std::unique_ptr<QuicTestPacketMaker> client_maker;
8304 std::unique_ptr<QuicTestPacketMaker> server_maker;
8305
8306 // On the second pass, the body read of the auth challenge is synchronous, so
8307 // IsConnectedAndIdle returns false. The socket should still be drained and
8308 // reused. See http://crbug.com/544255.
8309 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338310 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178311 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8312 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338313 client_headers_include_h2_stream_dependency_));
8314 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178315 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8316 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568317
8318 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148319 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568320 proxy_resolution_service_ =
8321 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498322 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568323
8324 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528325 quic::QuicStreamOffset client_header_stream_offset = 0;
8326 quic::QuicStreamOffset server_header_stream_offset = 0;
8327 quic::QuicStreamOffset client_data_offset = 0;
8328 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568329
Zhongyi Shi32f2fd02018-04-16 18:23:438330 mock_quic_data.AddWrite(SYNCHRONOUS,
8331 client_maker->MakeInitialSettingsPacket(
8332 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568333
8334 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438335 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568336 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338337 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8338 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568339 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8340 &client_header_stream_offset));
8341
Ryan Hamilton0239aac2018-05-19 00:03:138342 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568343 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8344 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8345 headers["content-length"] = "10";
8346 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438347 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338348 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8349 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568350
8351 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438352 mock_quic_data.AddRead(
8353 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338354 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8355 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568356 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438357 mock_quic_data.AddRead(
8358 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338359 2, GetNthClientInitiatedBidirectionalStreamId(0),
8360 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568361 }
8362 server_data_offset += 10;
8363
Zhongyi Shi32f2fd02018-04-16 18:23:438364 mock_quic_data.AddWrite(SYNCHRONOUS,
8365 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568366
8367 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338368 SYNCHRONOUS,
8369 client_maker->MakeRstPacket(
8370 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188371 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8372 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568373
8374 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8375 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8376 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338377 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8378 5, GetNthClientInitiatedBidirectionalStreamId(1),
8379 false, false, default_priority, std::move(headers),
8380 GetNthClientInitiatedBidirectionalStreamId(0),
8381 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568382
8383 // Response to wrong password
8384 headers =
8385 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8386 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8387 headers["content-length"] = "10";
8388 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438389 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338390 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8391 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568392 mock_quic_data.AddRead(SYNCHRONOUS,
8393 ERR_IO_PENDING); // No more data to read
8394
Fan Yang32c5a112018-12-10 20:06:338395 mock_quic_data.AddWrite(
8396 SYNCHRONOUS,
8397 client_maker->MakeAckAndRstPacket(
8398 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8399 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568400
8401 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8402 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8403
8404 CreateSession();
8405
8406 request_.url = GURL("https://mail.example.org/");
8407 // Ensure that proxy authentication is attempted even
8408 // when the no authentication data flag is set.
8409 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8410 {
8411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8412 HeadersHandler headers_handler;
8413 trans.SetBeforeHeadersSentCallback(
8414 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8415 base::Unretained(&headers_handler)));
8416 RunTransaction(&trans);
8417
8418 const HttpResponseInfo* response = trans.GetResponseInfo();
8419 ASSERT_TRUE(response != nullptr);
8420 ASSERT_TRUE(response->headers.get() != nullptr);
8421 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8422 response->headers->GetStatusLine());
8423 EXPECT_TRUE(response->headers->IsKeepAlive());
8424 EXPECT_EQ(407, response->headers->response_code());
8425 EXPECT_EQ(10, response->headers->GetContentLength());
8426 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8427 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8428 ASSERT_TRUE(auth_challenge != nullptr);
8429 EXPECT_TRUE(auth_challenge->is_proxy);
8430 EXPECT_EQ("https://proxy.example.org:70",
8431 auth_challenge->challenger.Serialize());
8432 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8433 EXPECT_EQ("basic", auth_challenge->scheme);
8434
8435 TestCompletionCallback callback;
8436 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8437 callback.callback());
8438 EXPECT_EQ(ERR_IO_PENDING, rv);
8439 EXPECT_EQ(OK, callback.WaitForResult());
8440
8441 response = trans.GetResponseInfo();
8442 ASSERT_TRUE(response != nullptr);
8443 ASSERT_TRUE(response->headers.get() != nullptr);
8444 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8445 response->headers->GetStatusLine());
8446 EXPECT_TRUE(response->headers->IsKeepAlive());
8447 EXPECT_EQ(407, response->headers->response_code());
8448 EXPECT_EQ(10, response->headers->GetContentLength());
8449 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8450 auth_challenge = response->auth_challenge.get();
8451 ASSERT_TRUE(auth_challenge != nullptr);
8452 EXPECT_TRUE(auth_challenge->is_proxy);
8453 EXPECT_EQ("https://proxy.example.org:70",
8454 auth_challenge->challenger.Serialize());
8455 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8456 EXPECT_EQ("basic", auth_challenge->scheme);
8457 }
8458 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8459 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8460 // reused because it's not connected).
8461 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8462 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8463 }
8464}
8465
Yixin Wang385652a2018-02-16 02:37:238466TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8467 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8468 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268469 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238470 !client_headers_include_h2_stream_dependency_) {
8471 return;
8472 }
8473
8474 session_params_.origins_to_force_quic_on.insert(
8475 HostPortPair::FromString("mail.example.org:443"));
8476
Fan Yang32c5a112018-12-10 20:06:338477 const quic::QuicStreamId client_stream_0 =
8478 GetNthClientInitiatedBidirectionalStreamId(0);
8479 const quic::QuicStreamId client_stream_1 =
8480 GetNthClientInitiatedBidirectionalStreamId(1);
8481 const quic::QuicStreamId client_stream_2 =
8482 GetNthClientInitiatedBidirectionalStreamId(2);
8483 const quic::QuicStreamId push_stream_0 =
8484 GetNthServerInitiatedUnidirectionalStreamId(0);
8485 const quic::QuicStreamId push_stream_1 =
8486 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238487
8488 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528489 quic::QuicStreamOffset header_stream_offset = 0;
8490 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238491 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438492 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238493
8494 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438495 mock_quic_data.AddWrite(SYNCHRONOUS,
8496 ConstructClientRequestHeadersPacket(
8497 2, client_stream_0, true, true, HIGHEST,
8498 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8499 &header_stream_offset));
8500 mock_quic_data.AddWrite(SYNCHRONOUS,
8501 ConstructClientRequestHeadersPacket(
8502 3, client_stream_1, true, true, MEDIUM,
8503 GetRequestHeaders("GET", "https", "/1.jpg"),
8504 client_stream_0, &header_stream_offset));
8505 mock_quic_data.AddWrite(SYNCHRONOUS,
8506 ConstructClientRequestHeadersPacket(
8507 4, client_stream_2, true, true, MEDIUM,
8508 GetRequestHeaders("GET", "https", "/2.jpg"),
8509 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238510
8511 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438512 mock_quic_data.AddRead(
8513 ASYNC, ConstructServerResponseHeadersPacket(
8514 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8515 &server_header_offset));
8516 mock_quic_data.AddRead(
8517 ASYNC, ConstructServerResponseHeadersPacket(
8518 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8519 &server_header_offset));
8520 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8521 mock_quic_data.AddRead(
8522 ASYNC, ConstructServerResponseHeadersPacket(
8523 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8524 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238525
8526 // Server sends two push promises associated with |client_stream_0|; client
8527 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8528 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438529 mock_quic_data.AddRead(ASYNC,
8530 ConstructServerPushPromisePacket(
8531 4, client_stream_0, push_stream_0, false,
8532 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8533 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238534 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438535 SYNCHRONOUS,
8536 ConstructClientAckAndPriorityFramesPacket(
8537 6, false, 4, 3, 1,
8538 {{push_stream_0, client_stream_2,
8539 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8540 &header_stream_offset));
8541 mock_quic_data.AddRead(ASYNC,
8542 ConstructServerPushPromisePacket(
8543 5, client_stream_0, push_stream_1, false,
8544 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8545 &server_header_offset, &server_maker_));
8546 mock_quic_data.AddWrite(
8547 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238548 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8549 DEFAULT_PRIORITY, &header_stream_offset));
8550
8551 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438552 mock_quic_data.AddRead(
8553 ASYNC, ConstructServerResponseHeadersPacket(
8554 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8555 &server_header_offset));
8556 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8557 mock_quic_data.AddRead(
8558 ASYNC, ConstructServerResponseHeadersPacket(
8559 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8560 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238561
8562 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8563 // priority updates to match the request's priority. Client sends PRIORITY
8564 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438565 mock_quic_data.AddWrite(
8566 SYNCHRONOUS,
8567 ConstructClientAckAndPriorityFramesPacket(
8568 9, false, 7, 7, 1,
8569 {{push_stream_1, client_stream_2,
8570 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8571 {push_stream_0, client_stream_0,
8572 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8573 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238574
8575 // Server sends data for the three requests and the two push promises.
Victor Vasiliev076657c2019-03-12 02:46:438576 std::string header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438577 mock_quic_data.AddRead(
8578 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418579 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438580 mock_quic_data.AddRead(
8581 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418582 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438583 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8584 mock_quic_data.AddRead(
8585 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418586 header + "hello 2!"));
Victor Vasiliev076657c2019-03-12 02:46:438587 std::string header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438588 mock_quic_data.AddRead(
8589 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418590 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438591 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8592 mock_quic_data.AddRead(
8593 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418594 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238595
Yixin Wang385652a2018-02-16 02:37:238596 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8597 mock_quic_data.AddRead(ASYNC, 0); // EOF
8598 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8599
8600 // The non-alternate protocol job needs to hang in order to guarantee that
8601 // the alternate-protocol job will "win".
8602 AddHangingNonAlternateProtocolSocketData();
8603
8604 CreateSession();
8605
8606 request_.url = GURL("https://mail.example.org/0.jpg");
8607 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8608 TestCompletionCallback callback_0;
8609 EXPECT_EQ(ERR_IO_PENDING,
8610 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8611 base::RunLoop().RunUntilIdle();
8612
8613 request_.url = GURL("https://mail.example.org/1.jpg");
8614 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8615 TestCompletionCallback callback_1;
8616 EXPECT_EQ(ERR_IO_PENDING,
8617 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8618 base::RunLoop().RunUntilIdle();
8619
8620 request_.url = GURL("https://mail.example.org/2.jpg");
8621 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8622 TestCompletionCallback callback_2;
8623 EXPECT_EQ(ERR_IO_PENDING,
8624 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8625 base::RunLoop().RunUntilIdle();
8626
8627 // Client makes request that matches resource pushed in |pushed_stream_0|.
8628 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8629 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8630 TestCompletionCallback callback_3;
8631 EXPECT_EQ(ERR_IO_PENDING,
8632 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8633 base::RunLoop().RunUntilIdle();
8634
8635 EXPECT_TRUE(callback_0.have_result());
8636 EXPECT_EQ(OK, callback_0.WaitForResult());
8637 EXPECT_TRUE(callback_1.have_result());
8638 EXPECT_EQ(OK, callback_1.WaitForResult());
8639 EXPECT_TRUE(callback_2.have_result());
8640 EXPECT_EQ(OK, callback_2.WaitForResult());
8641
8642 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8643 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8644 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8645 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8646
8647 mock_quic_data.Resume();
8648 base::RunLoop().RunUntilIdle();
8649 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8650 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8651}
8652
[email protected]61a527782013-02-21 03:58:008653} // namespace test
8654} // namespace net