blob: 7ce82f6904632f95bb1f5fb60b8e970fc13b81bf [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"
Ryan Hamilton56b10c5d2018-05-11 13:40:1666#include "net/third_party/quic/core/crypto/quic_decrypter.h"
67#include "net/third_party/quic/core/crypto/quic_encrypter.h"
68#include "net/third_party/quic/core/quic_framer.h"
Ryan Hamilton47cf9d12018-10-17 04:33:0969#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1670#include "net/third_party/quic/platform/api/quic_str_cat.h"
71#include "net/third_party/quic/platform/api/quic_string_piece.h"
72#include "net/third_party/quic/platform/api/quic_test.h"
73#include "net/third_party/quic/test_tools/crypto_test_utils.h"
74#include "net/third_party/quic/test_tools/mock_clock.h"
75#include "net/third_party/quic/test_tools/mock_random.h"
76#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
77#include "net/third_party/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"
allada71b2efb2016-09-09 04:57:4881#include "net/url_request/url_request.h"
82#include "net/url_request/url_request_job_factory_impl.h"
83#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0184#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0085#include "testing/gtest/include/gtest/gtest.h"
86#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4687#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0088
Reilly Grant89a7e512018-01-20 01:57:1689using ::testing::ElementsAre;
90using ::testing::Key;
91
bnc508835902015-05-12 20:10:2992namespace net {
93namespace test {
[email protected]61a527782013-02-21 03:58:0094
95namespace {
96
bnc359ed2a2016-04-29 20:43:4597enum DestinationType {
98 // In pooling tests with two requests for different origins to the same
99 // destination, the destination should be
100 SAME_AS_FIRST, // the same as the first origin,
101 SAME_AS_SECOND, // the same as the second origin, or
102 DIFFERENT, // different from both.
103};
104
rchf114d982015-10-21 01:34:56105static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52106 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12107static const char kQuicAlternativeServiceWithProbabilityHeader[] =
108 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56109static const char kQuicAlternativeServiceDifferentPortHeader[] =
110 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20111
rch9ae5b3b2016-02-11 00:36:29112const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45113const char kDifferentHostname[] = "different.example.com";
114
115// Run QuicNetworkTransactionWithDestinationTest instances with all value
116// combinations of version and destination_type.
117struct PoolingTestParams {
118 friend std::ostream& operator<<(std::ostream& os,
119 const PoolingTestParams& p) {
120 os << "{ version: " << QuicVersionToString(p.version)
121 << ", destination_type: ";
122 switch (p.destination_type) {
123 case SAME_AS_FIRST:
124 os << "SAME_AS_FIRST";
125 break;
126 case SAME_AS_SECOND:
127 os << "SAME_AS_SECOND";
128 break;
129 case DIFFERENT:
130 os << "DIFFERENT";
131 break;
132 }
Yixin Wang079ad542018-01-11 04:06:05133 os << ", client_headers_include_h2_stream_dependency: "
134 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45135 os << " }";
136 return os;
137 }
138
Ryan Hamilton8d9ee76e2018-05-29 23:52:52139 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45140 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05141 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45142};
143
zhongyie537a002017-06-27 16:48:21144std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52145 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21146 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52147 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21148 if (!result.empty())
149 result.append(",");
Raul Tambre8c1981dd2019-02-08 02:22:26150 result.append(base::NumberToString(version));
zhongyie537a002017-06-27 16:48:21151 }
152 return result;
153}
154
bnc359ed2a2016-04-29 20:43:45155std::vector<PoolingTestParams> GetPoolingTestParams() {
156 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52157 quic::QuicTransportVersionVector all_supported_versions =
158 quic::AllSupportedTransportVersions();
159 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05160 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
161 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
162 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
163 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
164 params.push_back(PoolingTestParams{version, DIFFERENT, false});
165 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45166 }
167 return params;
168}
bncb07c05532015-05-14 19:07:20169
[email protected]61a527782013-02-21 03:58:00170} // namespace
171
ryansturm49a8cb12016-06-15 16:51:09172class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12173 public:
ryansturm49a8cb12016-06-15 16:51:09174 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12175
ryansturm49a8cb12016-06-15 16:51:09176 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12177
ryansturm49a8cb12016-06-15 16:51:09178 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
179 HttpRequestHeaders* request_headers) {
180 if (!proxy_info.is_http() && !proxy_info.is_https() &&
181 !proxy_info.is_quic()) {
182 return;
183 }
184 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12185 }
186
187 private:
ryansturm49a8cb12016-06-15 16:51:09188 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12189};
190
tbansal0f56a39a2016-04-07 22:03:38191class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40192 public:
tbansal180587c2017-02-16 15:13:23193 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
194 bool* rtt_notification_received)
195 : should_notify_updated_rtt_(should_notify_updated_rtt),
196 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38197 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40198
tbansal180587c2017-02-16 15:13:23199 bool ShouldNotifyUpdatedRTT() const override {
200 return *should_notify_updated_rtt_;
201 }
tbansalfdf5665b2015-09-21 22:46:40202
tbansal0f56a39a2016-04-07 22:03:38203 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
204 *rtt_notification_received_ = true;
205 }
206
207 void OnConnectionChanged() override {}
208
209 private:
tbansal180587c2017-02-16 15:13:23210 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38211 bool* rtt_notification_received_;
212
213 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
214};
215
216class TestSocketPerformanceWatcherFactory
217 : public SocketPerformanceWatcherFactory {
218 public:
219 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23220 : watcher_count_(0u),
221 should_notify_updated_rtt_(true),
222 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38223 ~TestSocketPerformanceWatcherFactory() override {}
224
225 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42226 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41227 const Protocol protocol,
228 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51229 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38230 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51231 }
232 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42233 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23234 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
235 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40236 }
237
tbansalc8a94ea2015-11-02 23:58:51238 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40239
tbansalc8a94ea2015-11-02 23:58:51240 bool rtt_notification_received() const { return rtt_notification_received_; }
241
tbansal180587c2017-02-16 15:13:23242 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
243 should_notify_updated_rtt_ = should_notify_updated_rtt;
244 }
245
tbansalc8a94ea2015-11-02 23:58:51246 private:
tbansal0f56a39a2016-04-07 22:03:38247 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23248 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51249 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38250
251 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51252};
253
Ryan Hamilton8d9ee76e2018-05-29 23:52:52254class QuicNetworkTransactionTest
255 : public PlatformTest,
256 public ::testing::WithParamInterface<
257 std::tuple<quic::QuicTransportVersion, bool>>,
258 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00259 protected:
[email protected]1c04f9522013-02-21 20:32:43260 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05261 : version_(std::get<0>(GetParam())),
262 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52263 supported_versions_(quic::test::SupportedTransportVersions(version_)),
David Schinazic8281052019-01-24 06:14:17264 random_generator_(0),
265 client_maker_(
266 version_,
267 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
268 &clock_,
269 kDefaultServerHostName,
270 quic::Perspective::IS_CLIENT,
271 client_headers_include_h2_stream_dependency_),
272 server_maker_(
273 version_,
274 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
275 &clock_,
276 kDefaultServerHostName,
277 quic::Perspective::IS_SERVER,
278 false),
rtenneti052774e2015-11-24 21:00:12279 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43280 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59281 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
[email protected]1c04f9522013-02-21 20:32:43282 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30283 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
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
Renjief49758b2019-01-11 23:32:41676 quic::QuicString ConstructDataHeader(size_t body_len) {
677 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);
683 return quic::QuicString(buffer.get(), header_length);
684 }
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")));
Renjief49758b2019-01-11 23:32:411091 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411128 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411165 quic::QuicString 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
Renjief49758b2019-01-11 23:32:411259 quic::QuicString 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
Renjief49758b2019-01-11 23:32:411318 quic::QuicString header = ConstructDataHeader(6);
1319
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")));
Renjief49758b2019-01-11 23:32:411360 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411395 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411444 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411505 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411595 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411789 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411858 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411921 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:411966 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:412091 quic::QuicString 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")));
Renjief49758b2019-01-11 23:32:412152 quic::QuicString 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));
Renjief49758b2019-01-11 23:32:412195 quic::QuicString 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 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2258
2259 // The request will initially go out over QUIC.
2260 MockQuicData quic_data;
2261 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2262 int packet_num = 1;
2263 quic_data.AddWrite(SYNCHRONOUS,
2264 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2265 // Retranmit the handshake messages.
2266 quic_data.AddWrite(SYNCHRONOUS,
2267 client_maker_.MakeDummyCHLOPacket(packet_num++));
2268 quic_data.AddWrite(SYNCHRONOUS,
2269 client_maker_.MakeDummyCHLOPacket(packet_num++));
2270 quic_data.AddWrite(SYNCHRONOUS,
2271 client_maker_.MakeDummyCHLOPacket(packet_num++));
2272 quic_data.AddWrite(SYNCHRONOUS,
2273 client_maker_.MakeDummyCHLOPacket(packet_num++));
2274 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2275 if (version_ <= quic::QUIC_VERSION_39) {
2276 quic_data.AddWrite(SYNCHRONOUS,
2277 client_maker_.MakeDummyCHLOPacket(packet_num++));
2278 }
2279 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2280 quic_data.AddWrite(SYNCHRONOUS,
2281 client_maker_.MakeConnectionClosePacket(
2282 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2283 "No recent network activity."));
2284 quic_data.AddSocketDataToFactory(&socket_factory_);
2285
2286 // Add successful TCP data so that TCP job will succeed.
2287 MockWrite http_writes[] = {
2288 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2289 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2290 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2291
2292 MockRead http_reads[] = {
2293 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2294 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2295 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2296 SequencedSocketData http_data(http_reads, http_writes);
2297 socket_factory_.AddSocketDataProvider(&http_data);
2298 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2299
2300 // Add data for the second QUIC connection to fail.
2301 MockQuicData quic_data2;
2302 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2303 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2304 quic_data2.AddSocketDataToFactory(&socket_factory_);
2305
2306 // Resolve the host resolution synchronously.
2307 host_resolver_.set_synchronous_mode(true);
2308 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2309 "");
Zhongyi Shia6b68d112018-09-24 07:49:032310
2311 CreateSession();
2312 session_->quic_stream_factory()->set_require_confirmation(true);
2313 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2314 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2315 QuicStreamFactoryPeer::SetAlarmFactory(
2316 session_->quic_stream_factory(),
2317 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2318 &clock_));
2319 // Add alternate protocol mapping to race QUIC and TCP.
2320 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2321 // peer.
2322 AddQuicAlternateProtocolMapping(
2323 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2324
2325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2326 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362327 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2329
2330 // Pump the message loop to get the request started.
2331 // Request will be served with TCP job.
2332 base::RunLoop().RunUntilIdle();
2333 EXPECT_THAT(callback.WaitForResult(), IsOk());
2334 CheckResponseData(&trans, "TCP succeeds");
2335
2336 // Fire the retransmission alarm, from this point, connection will idle
2337 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062338 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182339 quic_fix_time_of_first_packet_sent_after_receiving)) {
2340 quic_task_runner_->RunNextTask();
2341 }
Zhongyi Shia6b68d112018-09-24 07:49:032342 // Fast forward to idle timeout the original connection. A new connection will
2343 // be kicked off on the alternate network.
2344 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2345 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2346 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2347
2348 // Run the message loop to execute posted tasks, which will report job status.
2349 base::RunLoop().RunUntilIdle();
2350
2351 // Verify that QUIC is marked as broken.
2352 ExpectBrokenAlternateProtocolMapping();
2353
2354 // Deliver a message to notify the new network becomes default, the brokenness
2355 // will not expire as QUIC is broken on both networks.
2356 scoped_mock_change_notifier_->mock_network_change_notifier()
2357 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2358 ExpectBrokenAlternateProtocolMapping();
2359
2360 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2361 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2362}
2363
2364// This test verifies that a new QUIC connection will be attempted on the
2365// alternate network if the original QUIC connection fails with idle timeout
2366// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2367// alternate network, QUIC is marked as broken. The brokenness will expire when
2368// the default network changes.
2369TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
Michael Warres167db3e2019-03-01 21:38:032370 if (version_ >= quic::QUIC_VERSION_47) {
2371 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2372 return;
2373 }
Zhongyi Shia6b68d112018-09-24 07:49:032374 SetUpTestForRetryConnectionOnAlternateNetwork();
2375
2376 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032377 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032378 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2379
2380 // The request will initially go out over QUIC.
2381 MockQuicData quic_data;
2382 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2383 int packet_num = 1;
2384 quic_data.AddWrite(SYNCHRONOUS,
2385 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2386 // Retranmit the handshake messages.
2387 quic_data.AddWrite(SYNCHRONOUS,
2388 client_maker_.MakeDummyCHLOPacket(packet_num++));
2389 quic_data.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeDummyCHLOPacket(packet_num++));
2391 quic_data.AddWrite(SYNCHRONOUS,
2392 client_maker_.MakeDummyCHLOPacket(packet_num++));
2393 quic_data.AddWrite(SYNCHRONOUS,
2394 client_maker_.MakeDummyCHLOPacket(packet_num++));
2395 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2396 if (version_ <= quic::QUIC_VERSION_39) {
2397 quic_data.AddWrite(SYNCHRONOUS,
2398 client_maker_.MakeDummyCHLOPacket(packet_num++));
2399 }
2400 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2401 quic_data.AddWrite(SYNCHRONOUS,
2402 client_maker_.MakeConnectionClosePacket(
2403 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2404 "No recent network activity."));
2405 quic_data.AddSocketDataToFactory(&socket_factory_);
2406
2407 // Add successful TCP data so that TCP job will succeed.
2408 MockWrite http_writes[] = {
2409 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2410 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2411 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2412
2413 MockRead http_reads[] = {
2414 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2415 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2416 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2417 SequencedSocketData http_data(http_reads, http_writes);
2418 socket_factory_.AddSocketDataProvider(&http_data);
2419 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2420
2421 // Quic connection will be retried on the alternate network after the initial
2422 // one fails on the default network.
2423 MockQuicData quic_data2;
2424 quic::QuicStreamOffset header_stream_offset = 0;
2425 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2426 quic_data2.AddWrite(SYNCHRONOUS,
2427 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2428
2429 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2430 quic_data2.AddWrite(SYNCHRONOUS,
2431 ConstructInitialSettingsPacket(2, &header_stream_offset));
2432 quic_data2.AddSocketDataToFactory(&socket_factory_);
2433
2434 // Resolve the host resolution synchronously.
2435 host_resolver_.set_synchronous_mode(true);
2436 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2437 "");
Zhongyi Shia6b68d112018-09-24 07:49:032438
2439 CreateSession();
2440 session_->quic_stream_factory()->set_require_confirmation(true);
2441 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2442 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2443 QuicStreamFactoryPeer::SetAlarmFactory(
2444 session_->quic_stream_factory(),
2445 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2446 &clock_));
2447 // Add alternate protocol mapping to race QUIC and TCP.
2448 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2449 // peer.
2450 AddQuicAlternateProtocolMapping(
2451 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2452
2453 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2454 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362455 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032456 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2457
2458 // Pump the message loop to get the request started.
2459 // Request will be served with TCP job.
2460 base::RunLoop().RunUntilIdle();
2461 EXPECT_THAT(callback.WaitForResult(), IsOk());
2462 CheckResponseData(&trans, "TCP succeeds");
2463
2464 // Fire the retransmission alarm, after which connection will idle
2465 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062466 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182467 quic_fix_time_of_first_packet_sent_after_receiving)) {
2468 quic_task_runner_->RunNextTask();
2469 }
Zhongyi Shia6b68d112018-09-24 07:49:032470 // Fast forward to idle timeout the original connection. A new connection will
2471 // be kicked off on the alternate network.
2472 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2473 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2474 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2475
2476 // The second connection hasn't finish handshake, verify that QUIC is not
2477 // marked as broken.
2478 ExpectQuicAlternateProtocolMapping();
2479 // Explicitly confirm the handshake on the second connection.
2480 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2481 quic::QuicSession::HANDSHAKE_CONFIRMED);
2482 // Run message loop to execute posted tasks, which will notify JoController
2483 // about the orphaned job status.
2484 base::RunLoop().RunUntilIdle();
2485
2486 // Verify that QUIC is marked as broken.
2487 ExpectBrokenAlternateProtocolMapping();
2488
2489 // Deliver a message to notify the new network becomes default, the previous
2490 // brokenness will be clear as the brokenness is bond with old default
2491 // network.
2492 scoped_mock_change_notifier_->mock_network_change_notifier()
2493 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2494 ExpectQuicAlternateProtocolMapping();
2495
2496 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2497 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2498}
2499
2500// This test verifies that a new QUIC connection will be attempted on the
2501// alternate network if the original QUIC connection fails with idle timeout
2502// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2503// alternative network succeeds, QUIC is not marked as broken.
2504TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
Michael Warres167db3e2019-03-01 21:38:032505 if (version_ >= quic::QUIC_VERSION_47) {
2506 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
2507 return;
2508 }
Zhongyi Shia6b68d112018-09-24 07:49:032509 SetUpTestForRetryConnectionOnAlternateNetwork();
2510
2511 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032512 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Zhongyi Shia6b68d112018-09-24 07:49:032513 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2514
2515 // The request will initially go out over QUIC.
2516 MockQuicData quic_data;
2517 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2518 int packet_num = 1;
2519 quic_data.AddWrite(SYNCHRONOUS,
2520 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2521 // Retranmit the handshake messages.
2522 quic_data.AddWrite(SYNCHRONOUS,
2523 client_maker_.MakeDummyCHLOPacket(packet_num++));
2524 quic_data.AddWrite(SYNCHRONOUS,
2525 client_maker_.MakeDummyCHLOPacket(packet_num++));
2526 quic_data.AddWrite(SYNCHRONOUS,
2527 client_maker_.MakeDummyCHLOPacket(packet_num++));
2528 quic_data.AddWrite(SYNCHRONOUS,
2529 client_maker_.MakeDummyCHLOPacket(packet_num++));
2530 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2531 // quic_fix_has_pending_crypto_data is introduced and enabled.
2532 if (version_ <= quic::QUIC_VERSION_39) {
2533 quic_data.AddWrite(SYNCHRONOUS,
2534 client_maker_.MakeDummyCHLOPacket(packet_num++));
2535 }
2536 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2537 quic_data.AddWrite(SYNCHRONOUS,
2538 client_maker_.MakeConnectionClosePacket(
2539 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2540 "No recent network activity."));
2541 quic_data.AddSocketDataToFactory(&socket_factory_);
2542
2543 // Add hanging TCP data so that TCP job will never succeeded.
2544 AddHangingNonAlternateProtocolSocketData();
2545
2546 // Quic connection will then be retried on the alternate network.
2547 MockQuicData quic_data2;
2548 quic::QuicStreamOffset header_stream_offset = 0;
2549 quic_data2.AddWrite(SYNCHRONOUS,
2550 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2551
Renjief49758b2019-01-11 23:32:412552 const quic::QuicString body = "hello!";
2553 quic::QuicString header = ConstructDataHeader(body.length());
2554
Zhongyi Shia6b68d112018-09-24 07:49:032555 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2556 quic_data2.AddWrite(SYNCHRONOUS,
2557 ConstructInitialSettingsPacket(2, &header_stream_offset));
2558 quic_data2.AddWrite(
2559 SYNCHRONOUS,
2560 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332561 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032562 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032563 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332564 ASYNC, ConstructServerResponseHeadersPacket(
2565 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2566 GetResponseHeaders("200 OK")));
2567 quic_data2.AddRead(
2568 ASYNC, ConstructServerDataPacket(
2569 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412570 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032571 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2572 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2573 quic_data2.AddSocketDataToFactory(&socket_factory_);
2574
2575 // Resolve the host resolution synchronously.
2576 host_resolver_.set_synchronous_mode(true);
2577 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2578 "");
Zhongyi Shia6b68d112018-09-24 07:49:032579
2580 CreateSession();
2581 session_->quic_stream_factory()->set_require_confirmation(true);
2582 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2583 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2584 QuicStreamFactoryPeer::SetAlarmFactory(
2585 session_->quic_stream_factory(),
2586 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2587 &clock_));
2588 // Add alternate protocol mapping to race QUIC and TCP.
2589 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2590 // peer.
2591 AddQuicAlternateProtocolMapping(
2592 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2593
2594 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2595 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362596 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032597 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2598
2599 // Pump the message loop to get the request started.
2600 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062601 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182602 quic_fix_time_of_first_packet_sent_after_receiving)) {
2603 quic_task_runner_->RunNextTask();
2604 }
Zhongyi Shia6b68d112018-09-24 07:49:032605
2606 // Fast forward to idle timeout the original connection. A new connection will
2607 // be kicked off on the alternate network.
2608 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2609 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2610 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2611
2612 // Verify that QUIC is not marked as broken.
2613 ExpectQuicAlternateProtocolMapping();
2614 // Explicitly confirm the handshake on the second connection.
2615 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2616 quic::QuicSession::HANDSHAKE_CONFIRMED);
2617
2618 // Read the response.
2619 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412620 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032621 // Verify that QUIC is not marked as broken.
2622 ExpectQuicAlternateProtocolMapping();
2623
2624 // Deliver a message to notify the new network becomes default.
2625 scoped_mock_change_notifier_->mock_network_change_notifier()
2626 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2627 ExpectQuicAlternateProtocolMapping();
2628 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2629 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2630}
2631
rch9ecde09b2017-04-08 00:18:232632// Verify that if a QUIC connection times out, the QuicHttpStream will
2633// return QUIC_PROTOCOL_ERROR.
2634TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482635 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412636 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232637
2638 // The request will initially go out over QUIC.
2639 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522640 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132641 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232642 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2643
2644 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032645 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522646 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432647 quic_data.AddWrite(SYNCHRONOUS,
2648 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332649 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2650 true, priority, GetRequestHeaders("GET", "https", "/"),
2651 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232652
2653 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522654 quic::QuicStreamOffset settings_offset = header_stream_offset;
2655 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432656 quic_data.AddWrite(SYNCHRONOUS,
2657 client_maker_.MakeInitialSettingsPacketAndSaveData(
2658 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232659 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092660 quic_data.AddWrite(SYNCHRONOUS,
2661 client_maker_.MakeDataPacket(
2662 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2663 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232664 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092665 quic_data.AddWrite(SYNCHRONOUS,
2666 client_maker_.MakeDataPacket(
2667 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2668 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232669 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092670 quic_data.AddWrite(SYNCHRONOUS,
2671 client_maker_.MakeDataPacket(
2672 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2673 false, 0, request_data));
2674 quic_data.AddWrite(SYNCHRONOUS,
2675 client_maker_.MakeDataPacket(
2676 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2677 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232678 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092679 quic_data.AddWrite(SYNCHRONOUS,
2680 client_maker_.MakeDataPacket(
2681 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2682 false, 0, request_data));
2683 quic_data.AddWrite(SYNCHRONOUS,
2684 client_maker_.MakeDataPacket(
2685 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2686 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232687 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092688 quic_data.AddWrite(SYNCHRONOUS,
2689 client_maker_.MakeDataPacket(
2690 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2691 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522692 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092693 SYNCHRONOUS, client_maker_.MakeDataPacket(
2694 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2695 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232696
Zhongyi Shi32f2fd02018-04-16 18:23:432697 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522698 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432699 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222700
rch9ecde09b2017-04-08 00:18:232701 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2702 quic_data.AddRead(ASYNC, OK);
2703 quic_data.AddSocketDataToFactory(&socket_factory_);
2704
2705 // In order for a new QUIC session to be established via alternate-protocol
2706 // without racing an HTTP connection, we need the host resolution to happen
2707 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2708 // connection to the the server, in this test we require confirmation
2709 // before encrypting so the HTTP job will still start.
2710 host_resolver_.set_synchronous_mode(true);
2711 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2712 "");
rch9ecde09b2017-04-08 00:18:232713
2714 CreateSession();
2715 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552716 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232717 QuicStreamFactoryPeer::SetAlarmFactory(
2718 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192719 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552720 &clock_));
rch9ecde09b2017-04-08 00:18:232721
Ryan Hamilton9835e662018-08-02 05:36:272722 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232723
2724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2725 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362726 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232727 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2728
2729 // Pump the message loop to get the request started.
2730 base::RunLoop().RunUntilIdle();
2731 // Explicitly confirm the handshake.
2732 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522733 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232734
2735 // Run the QUIC session to completion.
2736 quic_task_runner_->RunUntilIdle();
2737
2738 ExpectQuicAlternateProtocolMapping();
2739 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2740 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2741}
2742
2743// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2744// return QUIC_PROTOCOL_ERROR.
2745TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482746 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522747 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232748
2749 // The request will initially go out over QUIC.
2750 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522751 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132752 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232753 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2754
2755 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032756 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522757 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432758 quic_data.AddWrite(SYNCHRONOUS,
2759 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332760 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2761 true, priority, GetRequestHeaders("GET", "https", "/"),
2762 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232763
2764 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522765 quic::QuicStreamOffset settings_offset = header_stream_offset;
2766 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432767 quic_data.AddWrite(SYNCHRONOUS,
2768 client_maker_.MakeInitialSettingsPacketAndSaveData(
2769 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232770 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092771 quic_data.AddWrite(SYNCHRONOUS,
2772 client_maker_.MakeDataPacket(
2773 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2774 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232775 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092776 quic_data.AddWrite(SYNCHRONOUS,
2777 client_maker_.MakeDataPacket(
2778 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2779 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232780 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092781 quic_data.AddWrite(SYNCHRONOUS,
2782 client_maker_.MakeDataPacket(
2783 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2784 false, 0, request_data));
2785 quic_data.AddWrite(SYNCHRONOUS,
2786 client_maker_.MakeDataPacket(
2787 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2788 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232789 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092790 quic_data.AddWrite(SYNCHRONOUS,
2791 client_maker_.MakeDataPacket(
2792 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2793 false, 0, request_data));
2794 quic_data.AddWrite(SYNCHRONOUS,
2795 client_maker_.MakeDataPacket(
2796 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2797 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232798 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092799 quic_data.AddWrite(SYNCHRONOUS,
2800 client_maker_.MakeDataPacket(
2801 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2802 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522803 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092804 SYNCHRONOUS, client_maker_.MakeDataPacket(
2805 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2806 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232807 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522808 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092809 SYNCHRONOUS, client_maker_.MakeDataPacket(
2810 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2811 false, 0, request_data));
2812 quic_data.AddWrite(
2813 SYNCHRONOUS, client_maker_.MakeDataPacket(
2814 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2815 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232816 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432817 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522818 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432819 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232820
2821 quic_data.AddRead(ASYNC, OK);
2822 quic_data.AddSocketDataToFactory(&socket_factory_);
2823
2824 // In order for a new QUIC session to be established via alternate-protocol
2825 // without racing an HTTP connection, we need the host resolution to happen
2826 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2827 // connection to the the server, in this test we require confirmation
2828 // before encrypting so the HTTP job will still start.
2829 host_resolver_.set_synchronous_mode(true);
2830 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2831 "");
rch9ecde09b2017-04-08 00:18:232832
2833 CreateSession();
2834 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552835 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232836 QuicStreamFactoryPeer::SetAlarmFactory(
2837 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192838 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552839 &clock_));
rch9ecde09b2017-04-08 00:18:232840
Ryan Hamilton9835e662018-08-02 05:36:272841 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232842
2843 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2844 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362845 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2847
2848 // Pump the message loop to get the request started.
2849 base::RunLoop().RunUntilIdle();
2850 // Explicitly confirm the handshake.
2851 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522852 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232853
2854 // Run the QUIC session to completion.
2855 quic_task_runner_->RunUntilIdle();
2856
2857 ExpectQuicAlternateProtocolMapping();
2858 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2859 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2860}
2861
2862// Verify that if a QUIC connection RTOs, while there are no active streams
2863// QUIC will not be marked as broken.
2864TEST_P(QuicNetworkTransactionTest,
2865 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522866 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232867
2868 // The request will initially go out over QUIC.
2869 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522870 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132871 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232872 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2873
2874 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:032875 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522876 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432877 quic_data.AddWrite(SYNCHRONOUS,
2878 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332879 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2880 true, priority, GetRequestHeaders("GET", "https", "/"),
2881 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232882
2883 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522884 quic::QuicStreamOffset settings_offset = header_stream_offset;
2885 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432886 quic_data.AddWrite(SYNCHRONOUS,
2887 client_maker_.MakeInitialSettingsPacketAndSaveData(
2888 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232889
Fan Yang32c5a112018-12-10 20:06:332890 quic_data.AddWrite(SYNCHRONOUS,
2891 client_maker_.MakeRstPacket(
2892 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2893 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232894 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092895 quic_data.AddWrite(SYNCHRONOUS,
2896 client_maker_.MakeDataPacket(
2897 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2898 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232899 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092900 quic_data.AddWrite(SYNCHRONOUS,
2901 client_maker_.MakeDataPacket(
2902 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2903 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232904 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332905 quic_data.AddWrite(SYNCHRONOUS,
2906 client_maker_.MakeRstPacket(
2907 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2908 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092909 quic_data.AddWrite(SYNCHRONOUS,
2910 client_maker_.MakeDataPacket(
2911 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2912 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232913 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092914 quic_data.AddWrite(SYNCHRONOUS,
2915 client_maker_.MakeDataPacket(
2916 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2917 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332918 quic_data.AddWrite(SYNCHRONOUS,
2919 client_maker_.MakeRstPacket(
2920 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2921 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232922 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522923 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092924 SYNCHRONOUS, client_maker_.MakeDataPacket(
2925 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2926 false, 0, request_data));
2927 quic_data.AddWrite(
2928 SYNCHRONOUS, client_maker_.MakeDataPacket(
2929 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2930 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232931 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432932 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332933 SYNCHRONOUS, client_maker_.MakeRstPacket(
2934 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2935 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522936 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092937 SYNCHRONOUS, client_maker_.MakeDataPacket(
2938 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2939 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232940 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432941 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522942 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432943 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232944
2945 quic_data.AddRead(ASYNC, OK);
2946 quic_data.AddSocketDataToFactory(&socket_factory_);
2947
2948 // In order for a new QUIC session to be established via alternate-protocol
2949 // without racing an HTTP connection, we need the host resolution to happen
2950 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2951 // connection to the the server, in this test we require confirmation
2952 // before encrypting so the HTTP job will still start.
2953 host_resolver_.set_synchronous_mode(true);
2954 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2955 "");
rch9ecde09b2017-04-08 00:18:232956
2957 CreateSession();
2958 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552959 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232960 QuicStreamFactoryPeer::SetAlarmFactory(
2961 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192962 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552963 &clock_));
rch9ecde09b2017-04-08 00:18:232964
Ryan Hamilton9835e662018-08-02 05:36:272965 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232966
Jeremy Roman0579ed62017-08-29 15:56:192967 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232968 session_.get());
2969 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362970 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232971 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2972
2973 // Pump the message loop to get the request started.
2974 base::RunLoop().RunUntilIdle();
2975 // Explicitly confirm the handshake.
2976 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522977 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232978
2979 // Now cancel the request.
2980 trans.reset();
2981
2982 // Run the QUIC session to completion.
2983 quic_task_runner_->RunUntilIdle();
2984
2985 ExpectQuicAlternateProtocolMapping();
2986
2987 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2988}
2989
rch2f2991c2017-04-13 19:28:172990// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2991// the request fails with QUIC_PROTOCOL_ERROR.
2992TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482993 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172994 // The request will initially go out over QUIC.
2995 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522996 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:032997 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522998 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432999 quic_data.AddWrite(
3000 SYNCHRONOUS,
3001 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333002 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433003 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523004 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433005 quic_data.AddWrite(SYNCHRONOUS,
3006 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173007 // Peer sending data from an non-existing stream causes this end to raise
3008 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333009 quic_data.AddRead(
3010 ASYNC, ConstructServerRstPacket(
3011 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3012 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173013 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433014 quic_data.AddWrite(SYNCHRONOUS,
3015 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523016 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3017 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173018 quic_data.AddSocketDataToFactory(&socket_factory_);
3019
3020 // In order for a new QUIC session to be established via alternate-protocol
3021 // without racing an HTTP connection, we need the host resolution to happen
3022 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3023 // connection to the the server, in this test we require confirmation
3024 // before encrypting so the HTTP job will still start.
3025 host_resolver_.set_synchronous_mode(true);
3026 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3027 "");
rch2f2991c2017-04-13 19:28:173028
3029 CreateSession();
3030
Ryan Hamilton9835e662018-08-02 05:36:273031 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173032
3033 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3034 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363035 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173036 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3037
3038 // Pump the message loop to get the request started.
3039 base::RunLoop().RunUntilIdle();
3040 // Explicitly confirm the handshake.
3041 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523042 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173043
3044 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3045
3046 // Run the QUIC session to completion.
3047 base::RunLoop().RunUntilIdle();
3048 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3049 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3050
3051 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3052 ExpectQuicAlternateProtocolMapping();
3053 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3054}
3055
rch9ecde09b2017-04-08 00:18:233056// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3057// connection times out, then QUIC will be marked as broken and the request
3058// retried over TCP.
3059TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413060 session_params_.mark_quic_broken_when_network_blackholes = true;
3061 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233062
3063 // The request will initially go out over QUIC.
3064 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523065 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133066 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233067 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3068
3069 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033070 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523071 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433072 quic_data.AddWrite(SYNCHRONOUS,
3073 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333074 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3075 true, priority, GetRequestHeaders("GET", "https", "/"),
3076 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233077
3078 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523079 quic::QuicStreamOffset settings_offset = header_stream_offset;
3080 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433081 quic_data.AddWrite(SYNCHRONOUS,
3082 client_maker_.MakeInitialSettingsPacketAndSaveData(
3083 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233084 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093085 quic_data.AddWrite(SYNCHRONOUS,
3086 client_maker_.MakeDataPacket(
3087 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3088 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233089 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093090 quic_data.AddWrite(SYNCHRONOUS,
3091 client_maker_.MakeDataPacket(
3092 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3093 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233094 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093095 quic_data.AddWrite(SYNCHRONOUS,
3096 client_maker_.MakeDataPacket(
3097 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3098 false, 0, request_data));
3099 quic_data.AddWrite(SYNCHRONOUS,
3100 client_maker_.MakeDataPacket(
3101 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3102 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233103 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093104 quic_data.AddWrite(SYNCHRONOUS,
3105 client_maker_.MakeDataPacket(
3106 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3107 false, 0, request_data));
3108 quic_data.AddWrite(SYNCHRONOUS,
3109 client_maker_.MakeDataPacket(
3110 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3111 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233112 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093113 quic_data.AddWrite(SYNCHRONOUS,
3114 client_maker_.MakeDataPacket(
3115 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3116 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523117 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093118 SYNCHRONOUS, client_maker_.MakeDataPacket(
3119 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3120 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233121
Zhongyi Shi32f2fd02018-04-16 18:23:433122 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523123 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433124 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223125
rch9ecde09b2017-04-08 00:18:233126 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3127 quic_data.AddRead(ASYNC, OK);
3128 quic_data.AddSocketDataToFactory(&socket_factory_);
3129
3130 // After that fails, it will be resent via TCP.
3131 MockWrite http_writes[] = {
3132 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3133 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3134 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3135
3136 MockRead http_reads[] = {
3137 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3138 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3139 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013140 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233141 socket_factory_.AddSocketDataProvider(&http_data);
3142 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3143
3144 // In order for a new QUIC session to be established via alternate-protocol
3145 // without racing an HTTP connection, we need the host resolution to happen
3146 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3147 // connection to the the server, in this test we require confirmation
3148 // before encrypting so the HTTP job will still start.
3149 host_resolver_.set_synchronous_mode(true);
3150 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3151 "");
rch9ecde09b2017-04-08 00:18:233152
3153 CreateSession();
3154 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553155 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233156 QuicStreamFactoryPeer::SetAlarmFactory(
3157 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193158 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553159 &clock_));
rch9ecde09b2017-04-08 00:18:233160
Ryan Hamilton9835e662018-08-02 05:36:273161 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233162
3163 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3164 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363165 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233166 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3167
3168 // Pump the message loop to get the request started.
3169 base::RunLoop().RunUntilIdle();
3170 // Explicitly confirm the handshake.
3171 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523172 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233173
3174 // Run the QUIC session to completion.
3175 quic_task_runner_->RunUntilIdle();
3176 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3177
3178 // Let the transaction proceed which will result in QUIC being marked
3179 // as broken and the request falling back to TCP.
3180 EXPECT_THAT(callback.WaitForResult(), IsOk());
3181
3182 ExpectBrokenAlternateProtocolMapping();
3183 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3184 ASSERT_FALSE(http_data.AllReadDataConsumed());
3185
3186 // Read the response body over TCP.
3187 CheckResponseData(&trans, "hello world");
3188 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3189 ASSERT_TRUE(http_data.AllReadDataConsumed());
3190}
3191
rch2f2991c2017-04-13 19:28:173192// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3193// connection times out, then QUIC will be marked as broken and the request
3194// retried over TCP.
3195TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413196 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173197
3198 // The request will initially go out over QUIC.
3199 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523200 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133201 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173202 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3203
3204 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033205 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523206 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433207 quic_data.AddWrite(SYNCHRONOUS,
3208 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333209 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3210 true, priority, GetRequestHeaders("GET", "https", "/"),
3211 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173212
3213 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523214 quic::QuicStreamOffset settings_offset = header_stream_offset;
3215 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433216 quic_data.AddWrite(SYNCHRONOUS,
3217 client_maker_.MakeInitialSettingsPacketAndSaveData(
3218 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173219 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093220 quic_data.AddWrite(SYNCHRONOUS,
3221 client_maker_.MakeDataPacket(
3222 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3223 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173224 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093225 quic_data.AddWrite(SYNCHRONOUS,
3226 client_maker_.MakeDataPacket(
3227 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3228 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173229 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093230 quic_data.AddWrite(SYNCHRONOUS,
3231 client_maker_.MakeDataPacket(
3232 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3233 false, 0, request_data));
3234 quic_data.AddWrite(SYNCHRONOUS,
3235 client_maker_.MakeDataPacket(
3236 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3237 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173238 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093239 quic_data.AddWrite(SYNCHRONOUS,
3240 client_maker_.MakeDataPacket(
3241 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3242 false, 0, request_data));
3243 quic_data.AddWrite(SYNCHRONOUS,
3244 client_maker_.MakeDataPacket(
3245 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3246 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173247 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093248 quic_data.AddWrite(SYNCHRONOUS,
3249 client_maker_.MakeDataPacket(
3250 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3251 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523252 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093253 SYNCHRONOUS, client_maker_.MakeDataPacket(
3254 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3255 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173256
Zhongyi Shi32f2fd02018-04-16 18:23:433257 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523258 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433259 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223260
rch2f2991c2017-04-13 19:28:173261 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3262 quic_data.AddRead(ASYNC, OK);
3263 quic_data.AddSocketDataToFactory(&socket_factory_);
3264
3265 // After that fails, it will be resent via TCP.
3266 MockWrite http_writes[] = {
3267 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3268 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3269 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3270
3271 MockRead http_reads[] = {
3272 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3273 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3274 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013275 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173276 socket_factory_.AddSocketDataProvider(&http_data);
3277 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3278
3279 // In order for a new QUIC session to be established via alternate-protocol
3280 // without racing an HTTP connection, we need the host resolution to happen
3281 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3282 // connection to the the server, in this test we require confirmation
3283 // before encrypting so the HTTP job will still start.
3284 host_resolver_.set_synchronous_mode(true);
3285 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3286 "");
rch2f2991c2017-04-13 19:28:173287
3288 CreateSession();
3289 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553290 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173291 QuicStreamFactoryPeer::SetAlarmFactory(
3292 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193293 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553294 &clock_));
rch2f2991c2017-04-13 19:28:173295
Ryan Hamilton9835e662018-08-02 05:36:273296 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173297
3298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3299 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363300 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173301 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3302
3303 // Pump the message loop to get the request started.
3304 base::RunLoop().RunUntilIdle();
3305 // Explicitly confirm the handshake.
3306 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523307 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173308
3309 // Run the QUIC session to completion.
3310 quic_task_runner_->RunUntilIdle();
3311 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3312
3313 ExpectQuicAlternateProtocolMapping();
3314
3315 // Let the transaction proceed which will result in QUIC being marked
3316 // as broken and the request falling back to TCP.
3317 EXPECT_THAT(callback.WaitForResult(), IsOk());
3318
3319 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3320 ASSERT_FALSE(http_data.AllReadDataConsumed());
3321
3322 // Read the response body over TCP.
3323 CheckResponseData(&trans, "hello world");
3324 ExpectBrokenAlternateProtocolMapping();
3325 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3326 ASSERT_TRUE(http_data.AllReadDataConsumed());
3327}
3328
rch9ecde09b2017-04-08 00:18:233329// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3330// connection times out, then QUIC will be marked as broken but the request
3331// will not be retried over TCP.
3332TEST_P(QuicNetworkTransactionTest,
3333 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413334 session_params_.mark_quic_broken_when_network_blackholes = true;
3335 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233336
3337 // The request will initially go out over QUIC.
3338 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523339 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133340 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233341 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3342
3343 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033344 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523345 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433346 quic_data.AddWrite(SYNCHRONOUS,
3347 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333348 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3349 true, priority, GetRequestHeaders("GET", "https", "/"),
3350 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233351
3352 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523353 quic::QuicStreamOffset settings_offset = header_stream_offset;
3354 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433355 quic_data.AddWrite(SYNCHRONOUS,
3356 client_maker_.MakeInitialSettingsPacketAndSaveData(
3357 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233358
Zhongyi Shi32f2fd02018-04-16 18:23:433359 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333360 1, GetNthClientInitiatedBidirectionalStreamId(0),
3361 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433362 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523363 quic_data.AddWrite(
3364 SYNCHRONOUS,
3365 ConstructClientAckPacket(3, 1, 1, 1,
3366 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233367
3368 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523369 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093370 SYNCHRONOUS, client_maker_.MakeDataPacket(
3371 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3372 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233373 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093374 quic_data.AddWrite(
3375 SYNCHRONOUS, client_maker_.MakeDataPacket(
3376 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3377 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233378 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523379 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093380 SYNCHRONOUS, client_maker_.MakeDataPacket(
3381 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3382 false, 0, request_data));
3383 quic_data.AddWrite(
3384 SYNCHRONOUS, client_maker_.MakeDataPacket(
3385 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3386 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233387 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523388 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093389 SYNCHRONOUS, client_maker_.MakeDataPacket(
3390 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3391 false, 0, request_data));
3392 quic_data.AddWrite(
3393 SYNCHRONOUS, client_maker_.MakeDataPacket(
3394 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3395 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233396 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523397 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093398 SYNCHRONOUS, client_maker_.MakeDataPacket(
3399 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3400 false, 0, request_data));
3401 quic_data.AddWrite(
3402 SYNCHRONOUS, client_maker_.MakeDataPacket(
3403 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3404 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233405
Michael Warres112212822018-12-26 17:51:063406 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183407 quic_fix_time_of_first_packet_sent_after_receiving)) {
3408 quic_data.AddWrite(
3409 SYNCHRONOUS,
3410 client_maker_.MakeAckAndConnectionClosePacket(
3411 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3412 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3413
3414 } else {
3415 quic_data.AddWrite(
3416 SYNCHRONOUS,
3417 client_maker_.MakeAckAndConnectionClosePacket(
3418 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3419 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3420 }
Fan Yang928f1632017-12-14 18:55:223421
rch9ecde09b2017-04-08 00:18:233422 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3423 quic_data.AddRead(ASYNC, OK);
3424 quic_data.AddSocketDataToFactory(&socket_factory_);
3425
3426 // In order for a new QUIC session to be established via alternate-protocol
3427 // without racing an HTTP connection, we need the host resolution to happen
3428 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3429 // connection to the the server, in this test we require confirmation
3430 // before encrypting so the HTTP job will still start.
3431 host_resolver_.set_synchronous_mode(true);
3432 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3433 "");
rch9ecde09b2017-04-08 00:18:233434
3435 CreateSession();
3436 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553437 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233438 QuicStreamFactoryPeer::SetAlarmFactory(
3439 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193440 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553441 &clock_));
rch9ecde09b2017-04-08 00:18:233442
Ryan Hamilton9835e662018-08-02 05:36:273443 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233444
3445 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3446 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363447 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3449
3450 // Pump the message loop to get the request started.
3451 base::RunLoop().RunUntilIdle();
3452 // Explicitly confirm the handshake.
3453 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523454 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233455
3456 // Pump the message loop to get the request started.
3457 base::RunLoop().RunUntilIdle();
3458
3459 // Run the QUIC session to completion.
3460 quic_task_runner_->RunUntilIdle();
3461 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3462
3463 // Let the transaction proceed which will result in QUIC being marked
3464 // as broken and the request falling back to TCP.
3465 EXPECT_THAT(callback.WaitForResult(), IsOk());
3466
3467 ExpectBrokenAlternateProtocolMapping();
3468 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3469
3470 std::string response_data;
3471 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3472 IsError(ERR_QUIC_PROTOCOL_ERROR));
3473}
3474
3475// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3476// connection RTOs, then QUIC will be marked as broken and the request retried
3477// over TCP.
3478TEST_P(QuicNetworkTransactionTest,
3479 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413480 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523481 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233482
3483 // The request will initially go out over QUIC.
3484 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523485 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133486 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233487 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3488
3489 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033490 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523491 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433492 quic_data.AddWrite(SYNCHRONOUS,
3493 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333494 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3495 true, priority, GetRequestHeaders("GET", "https", "/"),
3496 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233497
3498 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523499 quic::QuicStreamOffset settings_offset = header_stream_offset;
3500 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433501 quic_data.AddWrite(SYNCHRONOUS,
3502 client_maker_.MakeInitialSettingsPacketAndSaveData(
3503 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233504 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093505 quic_data.AddWrite(SYNCHRONOUS,
3506 client_maker_.MakeDataPacket(
3507 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3508 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233509 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093510 quic_data.AddWrite(SYNCHRONOUS,
3511 client_maker_.MakeDataPacket(
3512 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3513 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233514 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093515 quic_data.AddWrite(SYNCHRONOUS,
3516 client_maker_.MakeDataPacket(
3517 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3518 false, 0, request_data));
3519 quic_data.AddWrite(SYNCHRONOUS,
3520 client_maker_.MakeDataPacket(
3521 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3522 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233523 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093524 quic_data.AddWrite(SYNCHRONOUS,
3525 client_maker_.MakeDataPacket(
3526 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3527 false, 0, request_data));
3528 quic_data.AddWrite(SYNCHRONOUS,
3529 client_maker_.MakeDataPacket(
3530 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3531 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233532 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093533 quic_data.AddWrite(SYNCHRONOUS,
3534 client_maker_.MakeDataPacket(
3535 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3536 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523537 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093538 SYNCHRONOUS, client_maker_.MakeDataPacket(
3539 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3540 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233541 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523542 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093543 SYNCHRONOUS, client_maker_.MakeDataPacket(
3544 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3545 false, 0, request_data));
3546 quic_data.AddWrite(
3547 SYNCHRONOUS, client_maker_.MakeDataPacket(
3548 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3549 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233550
Zhongyi Shi32f2fd02018-04-16 18:23:433551 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523552 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433553 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233554
3555 quic_data.AddRead(ASYNC, OK);
3556 quic_data.AddSocketDataToFactory(&socket_factory_);
3557
3558 // After that fails, it will be resent via TCP.
3559 MockWrite http_writes[] = {
3560 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3561 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3562 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3563
3564 MockRead http_reads[] = {
3565 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3566 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3567 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013568 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233569 socket_factory_.AddSocketDataProvider(&http_data);
3570 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3571
3572 // In order for a new QUIC session to be established via alternate-protocol
3573 // without racing an HTTP connection, we need the host resolution to happen
3574 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3575 // connection to the the server, in this test we require confirmation
3576 // before encrypting so the HTTP job will still start.
3577 host_resolver_.set_synchronous_mode(true);
3578 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3579 "");
rch9ecde09b2017-04-08 00:18:233580
3581 CreateSession();
3582 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553583 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233584 QuicStreamFactoryPeer::SetAlarmFactory(
3585 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193586 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553587 &clock_));
rch9ecde09b2017-04-08 00:18:233588
Ryan Hamilton9835e662018-08-02 05:36:273589 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233590
3591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3592 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363593 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3595
3596 // Pump the message loop to get the request started.
3597 base::RunLoop().RunUntilIdle();
3598 // Explicitly confirm the handshake.
3599 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523600 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233601
3602 // Run the QUIC session to completion.
3603 quic_task_runner_->RunUntilIdle();
3604 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3605
3606 // Let the transaction proceed which will result in QUIC being marked
3607 // as broken and the request falling back to TCP.
3608 EXPECT_THAT(callback.WaitForResult(), IsOk());
3609
3610 ExpectBrokenAlternateProtocolMapping();
3611 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3612 ASSERT_FALSE(http_data.AllReadDataConsumed());
3613
3614 // Read the response body over TCP.
3615 CheckResponseData(&trans, "hello world");
3616 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3617 ASSERT_TRUE(http_data.AllReadDataConsumed());
3618}
3619
3620// Verify that if a QUIC connection RTOs, while there are no active streams
3621// QUIC will be marked as broken.
3622TEST_P(QuicNetworkTransactionTest,
3623 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413624 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523625 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233626
3627 // The request will initially go out over QUIC.
3628 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523629 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133630 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233631 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3632
3633 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033634 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523635 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433636 quic_data.AddWrite(SYNCHRONOUS,
3637 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333638 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3639 true, priority, GetRequestHeaders("GET", "https", "/"),
3640 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233641
3642 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523643 quic::QuicStreamOffset settings_offset = header_stream_offset;
3644 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433645 quic_data.AddWrite(SYNCHRONOUS,
3646 client_maker_.MakeInitialSettingsPacketAndSaveData(
3647 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233648
Fan Yang32c5a112018-12-10 20:06:333649 quic_data.AddWrite(SYNCHRONOUS,
3650 client_maker_.MakeRstPacket(
3651 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3652 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233653 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093654 quic_data.AddWrite(SYNCHRONOUS,
3655 client_maker_.MakeDataPacket(
3656 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3657 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233658 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093659 quic_data.AddWrite(SYNCHRONOUS,
3660 client_maker_.MakeDataPacket(
3661 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3662 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233663 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333664 quic_data.AddWrite(SYNCHRONOUS,
3665 client_maker_.MakeRstPacket(
3666 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3667 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093668 quic_data.AddWrite(SYNCHRONOUS,
3669 client_maker_.MakeDataPacket(
3670 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3671 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233672 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093673 quic_data.AddWrite(SYNCHRONOUS,
3674 client_maker_.MakeDataPacket(
3675 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3676 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333677 quic_data.AddWrite(SYNCHRONOUS,
3678 client_maker_.MakeRstPacket(
3679 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3680 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233681 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523682 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093683 SYNCHRONOUS, client_maker_.MakeDataPacket(
3684 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3685 false, 0, request_data));
3686 quic_data.AddWrite(
3687 SYNCHRONOUS, client_maker_.MakeDataPacket(
3688 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3689 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233690 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433691 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333692 SYNCHRONOUS, client_maker_.MakeRstPacket(
3693 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3694 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523695 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093696 SYNCHRONOUS, client_maker_.MakeDataPacket(
3697 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3698 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233699 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433700 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523701 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433702 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233703
3704 quic_data.AddRead(ASYNC, OK);
3705 quic_data.AddSocketDataToFactory(&socket_factory_);
3706
3707 // In order for a new QUIC session to be established via alternate-protocol
3708 // without racing an HTTP connection, we need the host resolution to happen
3709 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3710 // connection to the the server, in this test we require confirmation
3711 // before encrypting so the HTTP job will still start.
3712 host_resolver_.set_synchronous_mode(true);
3713 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3714 "");
rch9ecde09b2017-04-08 00:18:233715
3716 CreateSession();
3717 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553718 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233719 QuicStreamFactoryPeer::SetAlarmFactory(
3720 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193721 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553722 &clock_));
rch9ecde09b2017-04-08 00:18:233723
Ryan Hamilton9835e662018-08-02 05:36:273724 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233725
Jeremy Roman0579ed62017-08-29 15:56:193726 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233727 session_.get());
3728 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363729 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3731
3732 // Pump the message loop to get the request started.
3733 base::RunLoop().RunUntilIdle();
3734 // Explicitly confirm the handshake.
3735 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523736 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233737
3738 // Now cancel the request.
3739 trans.reset();
3740
3741 // Run the QUIC session to completion.
3742 quic_task_runner_->RunUntilIdle();
3743
3744 ExpectBrokenAlternateProtocolMapping();
3745
3746 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3747}
3748
rch2f2991c2017-04-13 19:28:173749// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3750// protocol error occurs after the handshake is confirmed, the request
3751// retried over TCP and the QUIC will be marked as broken.
3752TEST_P(QuicNetworkTransactionTest,
3753 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413754 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173755
3756 // The request will initially go out over QUIC.
3757 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523758 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:033759 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523760 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433761 quic_data.AddWrite(
3762 SYNCHRONOUS,
3763 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333764 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433765 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523766 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433767 quic_data.AddWrite(SYNCHRONOUS,
3768 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173769 // Peer sending data from an non-existing stream causes this end to raise
3770 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333771 quic_data.AddRead(
3772 ASYNC, ConstructServerRstPacket(
3773 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3774 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173775 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433776 quic_data.AddWrite(SYNCHRONOUS,
3777 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523778 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3779 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173780 quic_data.AddSocketDataToFactory(&socket_factory_);
3781
3782 // After that fails, it will be resent via TCP.
3783 MockWrite http_writes[] = {
3784 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3785 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3786 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3787
3788 MockRead http_reads[] = {
3789 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3790 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3791 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013792 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173793 socket_factory_.AddSocketDataProvider(&http_data);
3794 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3795
3796 // In order for a new QUIC session to be established via alternate-protocol
3797 // without racing an HTTP connection, we need the host resolution to happen
3798 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3799 // connection to the the server, in this test we require confirmation
3800 // before encrypting so the HTTP job will still start.
3801 host_resolver_.set_synchronous_mode(true);
3802 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3803 "");
rch2f2991c2017-04-13 19:28:173804
3805 CreateSession();
3806
Ryan Hamilton9835e662018-08-02 05:36:273807 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173808
3809 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3810 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363811 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3813
3814 // Pump the message loop to get the request started.
3815 base::RunLoop().RunUntilIdle();
3816 // Explicitly confirm the handshake.
3817 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523818 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173819
3820 // Run the QUIC session to completion.
3821 base::RunLoop().RunUntilIdle();
3822 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3823
3824 ExpectQuicAlternateProtocolMapping();
3825
3826 // Let the transaction proceed which will result in QUIC being marked
3827 // as broken and the request falling back to TCP.
3828 EXPECT_THAT(callback.WaitForResult(), IsOk());
3829
3830 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3831 ASSERT_FALSE(http_data.AllReadDataConsumed());
3832
3833 // Read the response body over TCP.
3834 CheckResponseData(&trans, "hello world");
3835 ExpectBrokenAlternateProtocolMapping();
3836 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3837 ASSERT_TRUE(http_data.AllReadDataConsumed());
3838}
3839
rch30943ee2017-06-12 21:28:443840// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3841// request is reset from, then QUIC will be marked as broken and the request
3842// retried over TCP.
3843TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443844 // The request will initially go out over QUIC.
3845 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523846 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133847 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443848 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3849
3850 std::string request_data;
Michael Warres167db3e2019-03-01 21:38:033851 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523852 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433853 quic_data.AddWrite(SYNCHRONOUS,
3854 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333855 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3856 true, priority, GetRequestHeaders("GET", "https", "/"),
3857 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443858
3859 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523860 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3861 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433862 quic_data.AddWrite(SYNCHRONOUS,
3863 client_maker_.MakeInitialSettingsPacketAndSaveData(
3864 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443865
Fan Yang32c5a112018-12-10 20:06:333866 quic_data.AddRead(ASYNC,
3867 ConstructServerRstPacket(
3868 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3869 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443870
3871 quic_data.AddRead(ASYNC, OK);
3872 quic_data.AddSocketDataToFactory(&socket_factory_);
3873
3874 // After that fails, it will be resent via TCP.
3875 MockWrite http_writes[] = {
3876 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3877 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3878 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3879
3880 MockRead http_reads[] = {
3881 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3882 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3883 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013884 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443885 socket_factory_.AddSocketDataProvider(&http_data);
3886 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3887
3888 // In order for a new QUIC session to be established via alternate-protocol
3889 // without racing an HTTP connection, we need the host resolution to happen
3890 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3891 // connection to the the server, in this test we require confirmation
3892 // before encrypting so the HTTP job will still start.
3893 host_resolver_.set_synchronous_mode(true);
3894 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3895 "");
rch30943ee2017-06-12 21:28:443896
3897 CreateSession();
3898
Ryan Hamilton9835e662018-08-02 05:36:273899 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443900
3901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3902 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363903 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3905
3906 // Pump the message loop to get the request started.
3907 base::RunLoop().RunUntilIdle();
3908 // Explicitly confirm the handshake.
3909 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523910 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443911
3912 // Run the QUIC session to completion.
3913 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3914
3915 ExpectQuicAlternateProtocolMapping();
3916
3917 // Let the transaction proceed which will result in QUIC being marked
3918 // as broken and the request falling back to TCP.
3919 EXPECT_THAT(callback.WaitForResult(), IsOk());
3920
3921 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3922 ASSERT_FALSE(http_data.AllReadDataConsumed());
3923
3924 // Read the response body over TCP.
3925 CheckResponseData(&trans, "hello world");
3926 ExpectBrokenAlternateProtocolMapping();
3927 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3928 ASSERT_TRUE(http_data.AllReadDataConsumed());
3929}
3930
Ryan Hamilton6c2a2a82017-12-15 02:06:283931// Verify that when an origin has two alt-svc advertisements, one local and one
3932// remote, that when the local is broken the request will go over QUIC via
3933// the remote Alt-Svc.
3934// This is a regression test for crbug/825646.
3935TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3936 session_params_.quic_allow_remote_alt_svc = true;
3937
3938 GURL origin1 = request_.url; // mail.example.org
3939 GURL origin2("https://www.example.org/");
3940 ASSERT_NE(origin1.host(), origin2.host());
3941
3942 scoped_refptr<X509Certificate> cert(
3943 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243944 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3945 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283946
3947 ProofVerifyDetailsChromium verify_details;
3948 verify_details.cert_verify_result.verified_cert = cert;
3949 verify_details.cert_verify_result.is_issued_by_known_root = true;
3950 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3951
3952 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523953 quic::QuicStreamOffset request_header_offset(0);
3954 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283955 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433956 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3957 mock_quic_data.AddWrite(
3958 SYNCHRONOUS,
3959 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333960 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433961 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3962 mock_quic_data.AddRead(
3963 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433965 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:413966 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433967 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333968 ASYNC, ConstructServerDataPacket(
3969 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:413970 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433971 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283972 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3973 mock_quic_data.AddRead(ASYNC, 0); // EOF
3974
3975 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3976 MockQuicData mock_quic_data2;
3977 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3978 AddHangingNonAlternateProtocolSocketData();
3979
3980 CreateSession();
3981
3982 // Set up alternative service for |origin1|.
3983 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3984 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3985 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3986 AlternativeServiceInfoVector alternative_services;
3987 alternative_services.push_back(
3988 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3989 local_alternative, expiration,
3990 session_->params().quic_supported_versions));
3991 alternative_services.push_back(
3992 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3993 remote_alternative, expiration,
3994 session_->params().quic_supported_versions));
3995 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3996 alternative_services);
3997
3998 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3999
4000 SendRequestAndExpectQuicResponse("hello!");
4001}
4002
rch30943ee2017-06-12 21:28:444003// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4004// request is reset from, then QUIC will be marked as broken and the request
4005// retried over TCP. Then, subsequent requests will go over a new QUIC
4006// connection instead of going back to the broken QUIC connection.
4007// This is a regression tests for crbug/731303.
4008TEST_P(QuicNetworkTransactionTest,
4009 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344010 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444011
4012 GURL origin1 = request_.url;
4013 GURL origin2("https://www.example.org/");
4014 ASSERT_NE(origin1.host(), origin2.host());
4015
4016 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524017 quic::QuicStreamOffset request_header_offset(0);
4018 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444019
4020 scoped_refptr<X509Certificate> cert(
4021 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244022 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4023 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444024
4025 ProofVerifyDetailsChromium verify_details;
4026 verify_details.cert_verify_result.verified_cert = cert;
4027 verify_details.cert_verify_result.is_issued_by_known_root = true;
4028 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4029
4030 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434031 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444032 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434033 mock_quic_data.AddWrite(
4034 SYNCHRONOUS,
4035 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334036 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434037 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4038 mock_quic_data.AddRead(
4039 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334040 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434041 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414042 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434043 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334044 ASYNC, ConstructServerDataPacket(
4045 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414046 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434047 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444048
4049 // Second request will go over the pooled QUIC connection, but will be
4050 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054051 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174052 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4053 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054054 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174055 QuicTestPacketMaker server_maker2(
4056 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4057 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434058 mock_quic_data.AddWrite(
4059 SYNCHRONOUS,
4060 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334061 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434062 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334063 GetNthClientInitiatedBidirectionalStreamId(0),
4064 &request_header_offset));
4065 mock_quic_data.AddRead(
4066 ASYNC, ConstructServerRstPacket(
4067 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4068 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444069 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4070 mock_quic_data.AddRead(ASYNC, 0); // EOF
4071
4072 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4073
4074 // After that fails, it will be resent via TCP.
4075 MockWrite http_writes[] = {
4076 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4077 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4078 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4079
4080 MockRead http_reads[] = {
4081 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4082 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4083 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014084 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444085 socket_factory_.AddSocketDataProvider(&http_data);
4086 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4087
Ryan Hamilton6c2a2a82017-12-15 02:06:284088 // Then the next request to the second origin will be sent over TCP.
4089 socket_factory_.AddSocketDataProvider(&http_data);
4090 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444091
4092 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564093 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4094 QuicStreamFactoryPeer::SetAlarmFactory(
4095 session_->quic_stream_factory(),
4096 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4097 &clock_));
rch30943ee2017-06-12 21:28:444098
4099 // Set up alternative service for |origin1|.
4100 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244101 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214102 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244103 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444104 supported_versions_);
rch30943ee2017-06-12 21:28:444105
4106 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244107 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214108 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244109 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444110 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344111
rch30943ee2017-06-12 21:28:444112 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524113 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444114 SendRequestAndExpectQuicResponse("hello!");
4115
4116 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524117 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444118 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4119 request_.url = origin2;
4120 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284121 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244122 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284123 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244124 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444125
4126 // The third request should use a new QUIC connection, not the broken
4127 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284128 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444129}
4130
bnc8be55ebb2015-10-30 14:12:074131TEST_P(QuicNetworkTransactionTest,
4132 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4133 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444134 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074135 MockRead http_reads[] = {
4136 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4137 MockRead("hello world"),
4138 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4139 MockRead(ASYNC, OK)};
4140
Ryan Sleevib8d7ea02018-05-07 20:01:014141 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074142 socket_factory_.AddSocketDataProvider(&http_data);
4143 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4144 socket_factory_.AddSocketDataProvider(&http_data);
4145 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4146
rch3f4b8452016-02-23 16:59:324147 CreateSession();
bnc8be55ebb2015-10-30 14:12:074148
4149 SendRequestAndExpectHttpResponse("hello world");
4150 SendRequestAndExpectHttpResponse("hello world");
4151}
4152
Xida Chen9bfe0b62018-04-24 19:52:214153// When multiple alternative services are advertised, HttpStreamFactory should
4154// select the alternative service which uses existing QUIC session if available.
4155// If no existing QUIC session can be used, use the first alternative service
4156// from the list.
zhongyi32569c62016-01-08 02:54:304157TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344158 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524159 MockRead http_reads[] = {
4160 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294161 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524162 MockRead("hello world"),
4163 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4164 MockRead(ASYNC, OK)};
4165
Ryan Sleevib8d7ea02018-05-07 20:01:014166 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524167 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084168 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564169 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524170
Ryan Hamilton8d9ee76e2018-05-29 23:52:524171 quic::QuicStreamOffset request_header_offset = 0;
4172 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304173 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294174 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304175 // alternative service list.
bncc958faa2015-07-31 18:14:524176 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364177 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434178 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4179 mock_quic_data.AddWrite(
4180 SYNCHRONOUS,
4181 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334182 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434183 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304184
4185 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294186 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4187 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434188 mock_quic_data.AddRead(
4189 ASYNC,
4190 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334191 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434192 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414193 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434194 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334195 ASYNC, ConstructServerDataPacket(
4196 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414197 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434198 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304199
4200 // Second QUIC request data.
4201 // Connection pooling, using existing session, no need to include version
4202 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584203 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334204 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4205 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4206 true, GetRequestHeaders("GET", "https", "/"),
4207 GetNthClientInitiatedBidirectionalStreamId(0),
4208 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434209 mock_quic_data.AddRead(
4210 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334211 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434212 GetResponseHeaders("200 OK"), &response_header_offset));
4213 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334214 ASYNC, ConstructServerDataPacket(
4215 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414216 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434217 mock_quic_data.AddWrite(
4218 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524219 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594220 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524221
4222 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4223
rtennetib8e80fb2016-05-16 00:12:094224 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324225 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564226 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4227 QuicStreamFactoryPeer::SetAlarmFactory(
4228 session_->quic_stream_factory(),
4229 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4230 &clock_));
bncc958faa2015-07-31 18:14:524231
4232 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304233
bnc359ed2a2016-04-29 20:43:454234 SendRequestAndExpectQuicResponse("hello!");
4235 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304236}
4237
tbansal6490783c2016-09-20 17:55:274238// Check that an existing QUIC connection to an alternative proxy server is
4239// used.
4240TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4241 base::HistogramTester histogram_tester;
4242
Ryan Hamilton8d9ee76e2018-05-29 23:52:524243 quic::QuicStreamOffset request_header_offset = 0;
4244 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274245 // First QUIC request data.
4246 // Open a session to foo.example.org:443 using the first entry of the
4247 // alternative service list.
4248 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364249 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434250 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4251 mock_quic_data.AddWrite(
4252 SYNCHRONOUS,
4253 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334254 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434255 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274256
4257 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434258 mock_quic_data.AddRead(
4259 ASYNC,
4260 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334261 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434262 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414263 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434264 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334265 ASYNC, ConstructServerDataPacket(
4266 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414267 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434268 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274269
4270 // Second QUIC request data.
4271 // Connection pooling, using existing session, no need to include version
4272 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274273 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334274 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4275 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4276 true, GetRequestHeaders("GET", "http", "/"),
4277 GetNthClientInitiatedBidirectionalStreamId(0),
4278 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434279 mock_quic_data.AddRead(
4280 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334281 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434282 GetResponseHeaders("200 OK"), &response_header_offset));
4283 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334284 ASYNC, ConstructServerDataPacket(
4285 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414286 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434287 mock_quic_data.AddWrite(
4288 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274289 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4290 mock_quic_data.AddRead(ASYNC, 0); // EOF
4291
4292 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4293
4294 AddHangingNonAlternateProtocolSocketData();
4295
4296 TestProxyDelegate test_proxy_delegate;
4297
Lily Houghton8c2f97d2018-01-22 05:06:594298 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494299 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274300
4301 test_proxy_delegate.set_alternative_proxy_server(
4302 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524303 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274304
4305 request_.url = GURL("http://mail.example.org/");
4306
4307 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564308 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4309 QuicStreamFactoryPeer::SetAlarmFactory(
4310 session_->quic_stream_factory(),
4311 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4312 &clock_));
tbansal6490783c2016-09-20 17:55:274313
4314 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4315 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4316 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4317 1);
4318
4319 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4320 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4321 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4322 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4323 1);
4324}
4325
Ryan Hamilton8d9ee76e2018-05-29 23:52:524326// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454327// even if alternative service destination is different.
4328TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344329 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304330 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524331 quic::QuicStreamOffset request_header_offset(0);
4332 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454333
rch5cb522462017-04-25 20:18:364334 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434335 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454336 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434337 mock_quic_data.AddWrite(
4338 SYNCHRONOUS,
4339 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334340 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434341 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4342 mock_quic_data.AddRead(
4343 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334344 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434345 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414346 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434347 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334348 ASYNC, ConstructServerDataPacket(
4349 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414350 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434351 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304352
bnc359ed2a2016-04-29 20:43:454353 // Second request.
alyssar2adf3ac2016-05-03 17:12:584354 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334355 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4356 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4357 true, GetRequestHeaders("GET", "https", "/"),
4358 GetNthClientInitiatedBidirectionalStreamId(0),
4359 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434360 mock_quic_data.AddRead(
4361 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334362 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434363 GetResponseHeaders("200 OK"), &response_header_offset));
4364 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334365 ASYNC, ConstructServerDataPacket(
4366 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414367 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434368 mock_quic_data.AddWrite(
4369 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304370 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4371 mock_quic_data.AddRead(ASYNC, 0); // EOF
4372
4373 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454374
4375 AddHangingNonAlternateProtocolSocketData();
4376 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304377
rch3f4b8452016-02-23 16:59:324378 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564379 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4380 QuicStreamFactoryPeer::SetAlarmFactory(
4381 session_->quic_stream_factory(),
4382 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4383 &clock_));
zhongyi32569c62016-01-08 02:54:304384
bnc359ed2a2016-04-29 20:43:454385 const char destination1[] = "first.example.com";
4386 const char destination2[] = "second.example.com";
4387
4388 // Set up alternative service entry to destination1.
4389 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214390 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454391 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214392 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444393 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454394 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524395 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454396 SendRequestAndExpectQuicResponse("hello!");
4397
4398 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214399 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214400 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444401 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524402 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454403 // even though alternative service destination is different.
4404 SendRequestAndExpectQuicResponse("hello!");
4405}
4406
4407// Pool to existing session with matching destination and matching certificate
4408// even if origin is different, and even if the alternative service with
4409// matching destination is not the first one on the list.
4410TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344411 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454412 GURL origin1 = request_.url;
4413 GURL origin2("https://www.example.org/");
4414 ASSERT_NE(origin1.host(), origin2.host());
4415
4416 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524417 quic::QuicStreamOffset request_header_offset(0);
4418 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454419
rch5cb522462017-04-25 20:18:364420 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434421 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454422 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434423 mock_quic_data.AddWrite(
4424 SYNCHRONOUS,
4425 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334426 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434427 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4428 mock_quic_data.AddRead(
4429 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334430 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434431 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414432 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434433 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334434 ASYNC, ConstructServerDataPacket(
4435 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414436 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434437 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454438
4439 // Second request.
Yixin Wang079ad542018-01-11 04:06:054440 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174441 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4442 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054443 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174444 QuicTestPacketMaker server_maker2(
4445 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4446 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584447 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434448 SYNCHRONOUS,
4449 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334450 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434451 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334452 GetNthClientInitiatedBidirectionalStreamId(0),
4453 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434454 mock_quic_data.AddRead(
4455 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334456 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434457 GetResponseHeaders("200 OK"), &response_header_offset));
4458 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334459 ASYNC, ConstructServerDataPacket(
4460 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414461 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434462 mock_quic_data.AddWrite(
4463 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454464 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4465 mock_quic_data.AddRead(ASYNC, 0); // EOF
4466
4467 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4468
4469 AddHangingNonAlternateProtocolSocketData();
4470 AddHangingNonAlternateProtocolSocketData();
4471
4472 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564473 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4474 QuicStreamFactoryPeer::SetAlarmFactory(
4475 session_->quic_stream_factory(),
4476 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4477 &clock_));
bnc359ed2a2016-04-29 20:43:454478
4479 const char destination1[] = "first.example.com";
4480 const char destination2[] = "second.example.com";
4481
4482 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214483 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454484 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214485 http_server_properties_.SetQuicAlternativeService(
4486 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444487 supported_versions_);
bnc359ed2a2016-04-29 20:43:454488
4489 // Set up multiple alternative service entries for |origin2|,
4490 // the first one with a different destination as for |origin1|,
4491 // the second one with the same. The second one should be used,
4492 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214493 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454494 AlternativeServiceInfoVector alternative_services;
4495 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214496 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4497 alternative_service2, expiration,
4498 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454499 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214500 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4501 alternative_service1, expiration,
4502 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454503 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4504 alternative_services);
bnc359ed2a2016-04-29 20:43:454505 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524506 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454507 SendRequestAndExpectQuicResponse("hello!");
4508
4509 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524510 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454511 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584512
bnc359ed2a2016-04-29 20:43:454513 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304514}
4515
4516// Multiple origins have listed the same alternative services. When there's a
4517// existing QUIC session opened by a request to other origin,
4518// if the cert is valid, should select this QUIC session to make the request
4519// if this is also the first existing QUIC session.
4520TEST_P(QuicNetworkTransactionTest,
4521 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344522 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294523 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304524
rch9ae5b3b2016-02-11 00:36:294525 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304526 MockRead http_reads[] = {
4527 MockRead("HTTP/1.1 200 OK\r\n"),
4528 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294529 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304530 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4531 MockRead(ASYNC, OK)};
4532
Ryan Sleevib8d7ea02018-05-07 20:01:014533 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304534 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084535 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304536 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4537
4538 // HTTP data for request to mail.example.org.
4539 MockRead http_reads2[] = {
4540 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294541 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304542 MockRead("hello world from mail.example.org"),
4543 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4544 MockRead(ASYNC, OK)};
4545
Ryan Sleevib8d7ea02018-05-07 20:01:014546 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304547 socket_factory_.AddSocketDataProvider(&http_data2);
4548 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4549
Ryan Hamilton8d9ee76e2018-05-29 23:52:524550 quic::QuicStreamOffset request_header_offset = 0;
4551 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304552
Yixin Wang079ad542018-01-11 04:06:054553 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174554 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4555 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054556 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584557 server_maker_.set_hostname("www.example.org");
4558 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304559 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364560 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434561 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304562 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584563 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434564 SYNCHRONOUS,
4565 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334566 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434567 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4568
4569 mock_quic_data.AddRead(
4570 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334571 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434572 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414573 quic::QuicString header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334574 mock_quic_data.AddRead(
4575 ASYNC, ConstructServerDataPacket(
4576 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414577 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434578 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4579 // Second QUIC request data.
4580 mock_quic_data.AddWrite(
4581 SYNCHRONOUS,
4582 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334583 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434584 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334585 GetNthClientInitiatedBidirectionalStreamId(0),
4586 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434587 mock_quic_data.AddRead(
4588 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334589 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434590 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334591 mock_quic_data.AddRead(
4592 ASYNC, ConstructServerDataPacket(
4593 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414594 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434595 mock_quic_data.AddWrite(
4596 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304597 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4598 mock_quic_data.AddRead(ASYNC, 0); // EOF
4599
4600 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304601
rtennetib8e80fb2016-05-16 00:12:094602 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324603 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564604 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4605 QuicStreamFactoryPeer::SetAlarmFactory(
4606 session_->quic_stream_factory(),
4607 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4608 &clock_));
zhongyi32569c62016-01-08 02:54:304609
4610 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294611 request_.url = GURL("https://www.example.org/");
4612 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304613 request_.url = GURL("https://mail.example.org/");
4614 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4615
rch9ae5b3b2016-02-11 00:36:294616 // Open a QUIC session to mail.example.org:443 when making request
4617 // to mail.example.org.
4618 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454619 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304620
rch9ae5b3b2016-02-11 00:36:294621 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304622 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454623 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524624}
4625
4626TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524627 MockRead http_reads[] = {
4628 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564629 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524630 MockRead("hello world"),
4631 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4632 MockRead(ASYNC, OK)};
4633
Ryan Sleevib8d7ea02018-05-07 20:01:014634 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524635 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084636 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564637 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524638
rtennetib8e80fb2016-05-16 00:12:094639 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324640 CreateSession();
bncc958faa2015-07-31 18:14:524641
4642 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454643
4644 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344645 AlternativeServiceInfoVector alternative_service_info_vector =
4646 http_server_properties_.GetAlternativeServiceInfos(http_server);
4647 ASSERT_EQ(1u, alternative_service_info_vector.size());
4648 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544649 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344650 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4651 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4652 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524653}
4654
4655TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524656 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564657 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4658 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524659 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4660 MockRead(ASYNC, OK)};
4661
Ryan Sleevib8d7ea02018-05-07 20:01:014662 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524663 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084664 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564665 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524666
4667 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524668 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364669 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434670 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4671 mock_quic_data.AddWrite(
4672 SYNCHRONOUS,
4673 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334674 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434675 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434676 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334677 ASYNC, ConstructServerResponseHeadersPacket(
4678 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4679 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414680 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334681 mock_quic_data.AddRead(
4682 ASYNC, ConstructServerDataPacket(
4683 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414684 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434685 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524686 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4687 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524688
4689 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4690
rtennetib8e80fb2016-05-16 00:12:094691 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324692 CreateSession();
bncc958faa2015-07-31 18:14:524693
bnc3472afd2016-11-17 15:27:214694 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524695 HostPortPair::FromURL(request_.url));
4696 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4697 alternative_service);
4698 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4699 alternative_service));
4700
4701 SendRequestAndExpectHttpResponse("hello world");
4702 SendRequestAndExpectQuicResponse("hello!");
4703
mmenkee24011922015-12-17 22:12:594704 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524705
4706 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4707 alternative_service));
rchac7f35e2017-03-15 20:42:304708 EXPECT_NE(nullptr,
4709 http_server_properties_.GetServerNetworkStats(
4710 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524711}
4712
bncc958faa2015-07-31 18:14:524713TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524714 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564715 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4716 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524717 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4718 MockRead(ASYNC, OK)};
4719
Ryan Sleevib8d7ea02018-05-07 20:01:014720 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524721 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564722 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524723
4724 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524725 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364726 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434727 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4728 mock_quic_data.AddWrite(
4729 SYNCHRONOUS,
4730 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334731 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434732 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434733 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334734 ASYNC, ConstructServerResponseHeadersPacket(
4735 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4736 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414737 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334738 mock_quic_data.AddRead(
4739 ASYNC, ConstructServerDataPacket(
4740 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414741 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434742 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524743 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4744
4745 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4746
4747 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324748 CreateSession();
bncc958faa2015-07-31 18:14:524749
4750 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4751 SendRequestAndExpectHttpResponse("hello world");
4752}
4753
tbansalc3308d72016-08-27 10:25:044754// Tests that the connection to an HTTPS proxy is raced with an available
4755// alternative proxy server.
4756TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274757 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594758 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494759 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044760
4761 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524762 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364763 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434764 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4765 mock_quic_data.AddWrite(
4766 SYNCHRONOUS,
4767 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334768 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434769 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434770 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334771 ASYNC, ConstructServerResponseHeadersPacket(
4772 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4773 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414774 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334775 mock_quic_data.AddRead(
4776 ASYNC, ConstructServerDataPacket(
4777 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414778 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434779 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044780 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4781 mock_quic_data.AddRead(ASYNC, 0); // EOF
4782
4783 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4784
4785 // There is no need to set up main job, because no attempt will be made to
4786 // speak to the proxy over TCP.
4787 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044788 TestProxyDelegate test_proxy_delegate;
4789 const HostPortPair host_port_pair("mail.example.org", 443);
4790
4791 test_proxy_delegate.set_alternative_proxy_server(
4792 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524793 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044794 CreateSession();
4795 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4796
4797 // The main job needs to hang in order to guarantee that the alternative
4798 // proxy server job will "win".
4799 AddHangingNonAlternateProtocolSocketData();
4800
4801 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4802
4803 // Verify that the alternative proxy server is not marked as broken.
4804 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4805
4806 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594807 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274808
4809 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4810 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4811 1);
tbansalc3308d72016-08-27 10:25:044812}
4813
bnc1c196c6e2016-05-28 13:51:484814TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304815 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274816 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304817
4818 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564819 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294820 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564821 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304822
4823 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564824 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484825 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564826 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304827
Ryan Sleevib8d7ea02018-05-07 20:01:014828 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504829 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084830 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504831 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304832
4833 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454834 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304835 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454836 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304837 };
Ryan Sleevib8d7ea02018-05-07 20:01:014838 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504839 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304840
4841 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014842 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504843 socket_factory_.AddSocketDataProvider(&http_data2);
4844 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304845
bnc912a04b2016-04-20 14:19:504846 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304847
4848 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304849 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174850 ASSERT_TRUE(http_data.AllReadDataConsumed());
4851 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304852
4853 // Now run the second request in which the QUIC socket hangs,
4854 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304855 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454856 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304857
rch37de576c2015-05-17 20:28:174858 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4859 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454860 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304861}
4862
[email protected]1e960032013-12-20 19:00:204863TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204864 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524865 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:034866 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524867 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434868 mock_quic_data.AddWrite(
4869 SYNCHRONOUS,
4870 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334871 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434872 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434873 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334874 ASYNC, ConstructServerResponseHeadersPacket(
4875 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4876 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414877 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334878 mock_quic_data.AddRead(
4879 ASYNC, ConstructServerDataPacket(
4880 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414881 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434882 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504883 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594884 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484885
rcha5399e02015-04-21 19:32:044886 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484887
rtennetib8e80fb2016-05-16 00:12:094888 // The non-alternate protocol job needs to hang in order to guarantee that
4889 // the alternate-protocol job will "win".
4890 AddHangingNonAlternateProtocolSocketData();
4891
rch3f4b8452016-02-23 16:59:324892 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274893 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194894 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304895
4896 EXPECT_EQ(nullptr,
4897 http_server_properties_.GetServerNetworkStats(
4898 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484899}
4900
[email protected]1e960032013-12-20 19:00:204901TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204902 MockQuicData mock_quic_data;
Michael Warres167db3e2019-03-01 21:38:034903 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524904 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334905 mock_quic_data.AddWrite(
4906 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4907 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4908 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434909 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334910 ASYNC, ConstructServerResponseHeadersPacket(
4911 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4912 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414913 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334914 mock_quic_data.AddRead(
4915 ASYNC, ConstructServerDataPacket(
4916 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414917 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434918 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504919 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594920 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044921 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274922
4923 // In order for a new QUIC session to be established via alternate-protocol
4924 // without racing an HTTP connection, we need the host resolution to happen
4925 // synchronously.
4926 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294927 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564928 "");
[email protected]3a120a6b2013-06-25 01:08:274929
rtennetib8e80fb2016-05-16 00:12:094930 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324931 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274932 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274933 SendRequestAndExpectQuicResponse("hello!");
4934}
4935
[email protected]0fc924b2014-03-31 04:34:154936TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494937 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4938 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154939
4940 // Since we are using a proxy, the QUIC job will not succeed.
4941 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294942 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4943 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564944 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154945
4946 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564947 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484948 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564949 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154950
Ryan Sleevib8d7ea02018-05-07 20:01:014951 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154952 socket_factory_.AddSocketDataProvider(&http_data);
4953
4954 // In order for a new QUIC session to be established via alternate-protocol
4955 // without racing an HTTP connection, we need the host resolution to happen
4956 // synchronously.
4957 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294958 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564959 "");
[email protected]0fc924b2014-03-31 04:34:154960
rch9ae5b3b2016-02-11 00:36:294961 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324962 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274963 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154964 SendRequestAndExpectHttpResponse("hello world");
4965}
4966
[email protected]1e960032013-12-20 19:00:204967TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204968 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524969 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364970 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434971 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4972 mock_quic_data.AddWrite(
4973 SYNCHRONOUS,
4974 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334975 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434976 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434977 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334978 ASYNC, ConstructServerResponseHeadersPacket(
4979 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4980 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414981 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334982 mock_quic_data.AddRead(
4983 ASYNC, ConstructServerDataPacket(
4984 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414985 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434986 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594987 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044988 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124989
rtennetib8e80fb2016-05-16 00:12:094990 // The non-alternate protocol job needs to hang in order to guarantee that
4991 // the alternate-protocol job will "win".
4992 AddHangingNonAlternateProtocolSocketData();
4993
[email protected]11c05872013-08-20 02:04:124994 // In order for a new QUIC session to be established via alternate-protocol
4995 // without racing an HTTP connection, we need the host resolution to happen
4996 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4997 // connection to the the server, in this test we require confirmation
4998 // before encrypting so the HTTP job will still start.
4999 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295000 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565001 "");
[email protected]11c05872013-08-20 02:04:125002
rch3f4b8452016-02-23 16:59:325003 CreateSession();
[email protected]11c05872013-08-20 02:04:125004 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275005 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125006
bnc691fda62016-08-12 00:43:165007 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125008 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365009 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125011
5012 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525013 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015014 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505015
bnc691fda62016-08-12 00:43:165016 CheckWasQuicResponse(&trans);
5017 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125018}
5019
Steven Valdez58097ec32018-07-16 18:29:045020TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5021 MockQuicData mock_quic_data;
5022 quic::QuicStreamOffset client_header_stream_offset = 0;
5023 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035024 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045025 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045026 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335027 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5028 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5029 true, GetRequestHeaders("GET", "https", "/"),
5030 &client_header_stream_offset));
5031 mock_quic_data.AddRead(
5032 ASYNC,
5033 ConstructServerResponseHeadersPacket(
5034 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5035 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5036 mock_quic_data.AddWrite(SYNCHRONOUS,
5037 ConstructClientAckAndRstPacket(
5038 2, GetNthClientInitiatedBidirectionalStreamId(0),
5039 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045040
5041 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5042
5043 spdy::SpdySettingsIR settings_frame;
5044 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5045 quic::kDefaultMaxUncompressedHeaderSize);
5046 spdy::SpdySerializedFrame spdy_frame(
5047 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5048 mock_quic_data.AddWrite(
5049 SYNCHRONOUS,
5050 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385051 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5052 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045053 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5054 client_header_stream_offset += spdy_frame.size();
5055
5056 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335057 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5058 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5059 true, GetRequestHeaders("GET", "https", "/"),
5060 GetNthClientInitiatedBidirectionalStreamId(0),
5061 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045062 mock_quic_data.AddRead(
5063 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335064 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045065 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:415066 quic::QuicString header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045067 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335068 ASYNC, ConstructServerDataPacket(
5069 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415070 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045071 mock_quic_data.AddWrite(
5072 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5073 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5074 mock_quic_data.AddRead(ASYNC, 0); // EOF
5075
5076 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5077
5078 // In order for a new QUIC session to be established via alternate-protocol
5079 // without racing an HTTP connection, we need the host resolution to happen
5080 // synchronously.
5081 host_resolver_.set_synchronous_mode(true);
5082 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5083 "");
Steven Valdez58097ec32018-07-16 18:29:045084
5085 AddHangingNonAlternateProtocolSocketData();
5086 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275087 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565088 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5089 QuicStreamFactoryPeer::SetAlarmFactory(
5090 session_->quic_stream_factory(),
5091 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5092 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045093
5094 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5095 TestCompletionCallback callback;
5096 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5098
5099 // Confirm the handshake after the 425 Too Early.
5100 base::RunLoop().RunUntilIdle();
5101
5102 // The handshake hasn't been confirmed yet, so the retry should not have
5103 // succeeded.
5104 EXPECT_FALSE(callback.have_result());
5105
5106 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5107 quic::QuicSession::HANDSHAKE_CONFIRMED);
5108
5109 EXPECT_THAT(callback.WaitForResult(), IsOk());
5110 CheckWasQuicResponse(&trans);
5111 CheckResponseData(&trans, "hello!");
5112}
5113
5114TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5115 MockQuicData mock_quic_data;
5116 quic::QuicStreamOffset client_header_stream_offset = 0;
5117 quic::QuicStreamOffset server_header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035118 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Steven Valdez58097ec32018-07-16 18:29:045119 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045120 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335121 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5122 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5123 true, GetRequestHeaders("GET", "https", "/"),
5124 &client_header_stream_offset));
5125 mock_quic_data.AddRead(
5126 ASYNC,
5127 ConstructServerResponseHeadersPacket(
5128 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5129 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5130 mock_quic_data.AddWrite(SYNCHRONOUS,
5131 ConstructClientAckAndRstPacket(
5132 2, GetNthClientInitiatedBidirectionalStreamId(0),
5133 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045134
5135 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5136
5137 spdy::SpdySettingsIR settings_frame;
5138 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5139 quic::kDefaultMaxUncompressedHeaderSize);
5140 spdy::SpdySerializedFrame spdy_frame(
5141 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5142 mock_quic_data.AddWrite(
5143 SYNCHRONOUS,
5144 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385145 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5146 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045147 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5148 client_header_stream_offset += spdy_frame.size();
5149
5150 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335151 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5152 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5153 true, GetRequestHeaders("GET", "https", "/"),
5154 GetNthClientInitiatedBidirectionalStreamId(0),
5155 &client_header_stream_offset));
5156 mock_quic_data.AddRead(
5157 ASYNC,
5158 ConstructServerResponseHeadersPacket(
5159 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5160 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5161 mock_quic_data.AddWrite(SYNCHRONOUS,
5162 ConstructClientAckAndRstPacket(
5163 5, GetNthClientInitiatedBidirectionalStreamId(1),
5164 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045165 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5166 mock_quic_data.AddRead(ASYNC, 0); // EOF
5167
5168 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5169
5170 // In order for a new QUIC session to be established via alternate-protocol
5171 // without racing an HTTP connection, we need the host resolution to happen
5172 // synchronously.
5173 host_resolver_.set_synchronous_mode(true);
5174 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5175 "");
Steven Valdez58097ec32018-07-16 18:29:045176
5177 AddHangingNonAlternateProtocolSocketData();
5178 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275179 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565180 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5181 QuicStreamFactoryPeer::SetAlarmFactory(
5182 session_->quic_stream_factory(),
5183 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5184 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045185
5186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5187 TestCompletionCallback callback;
5188 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5190
5191 // Confirm the handshake after the 425 Too Early.
5192 base::RunLoop().RunUntilIdle();
5193
5194 // The handshake hasn't been confirmed yet, so the retry should not have
5195 // succeeded.
5196 EXPECT_FALSE(callback.have_result());
5197
5198 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5199 quic::QuicSession::HANDSHAKE_CONFIRMED);
5200
5201 EXPECT_THAT(callback.WaitForResult(), IsOk());
5202 const HttpResponseInfo* response = trans.GetResponseInfo();
5203 ASSERT_TRUE(response != nullptr);
5204 ASSERT_TRUE(response->headers.get() != nullptr);
5205 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5206 EXPECT_TRUE(response->was_fetched_via_spdy);
5207 EXPECT_TRUE(response->was_alpn_negotiated);
5208 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5209 response->connection_info);
5210}
5211
zhongyica364fbb2015-12-12 03:39:125212TEST_P(QuicNetworkTransactionTest,
5213 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485214 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125215 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525216 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365217 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435218 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5219 mock_quic_data.AddWrite(
5220 SYNCHRONOUS,
5221 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335222 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435223 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125224 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525225 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435226 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125227 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5228
5229 // The non-alternate protocol job needs to hang in order to guarantee that
5230 // the alternate-protocol job will "win".
5231 AddHangingNonAlternateProtocolSocketData();
5232
5233 // In order for a new QUIC session to be established via alternate-protocol
5234 // without racing an HTTP connection, we need the host resolution to happen
5235 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5236 // connection to the the server, in this test we require confirmation
5237 // before encrypting so the HTTP job will still start.
5238 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295239 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125240 "");
zhongyica364fbb2015-12-12 03:39:125241
rch3f4b8452016-02-23 16:59:325242 CreateSession();
zhongyica364fbb2015-12-12 03:39:125243 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275244 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125245
bnc691fda62016-08-12 00:43:165246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125247 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365248 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125250
5251 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525252 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015253 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125254
5255 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525256 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125257
bnc691fda62016-08-12 00:43:165258 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125259 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525260 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5261 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125262}
5263
5264TEST_P(QuicNetworkTransactionTest,
5265 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485266 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125267 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525268 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365269 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435270 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5271 mock_quic_data.AddWrite(
5272 SYNCHRONOUS,
5273 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335274 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435275 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215276 // Peer sending data from an non-existing stream causes this end to raise
5277 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335278 mock_quic_data.AddRead(
5279 ASYNC, ConstructServerRstPacket(
5280 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5281 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215282 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525283 mock_quic_data.AddWrite(
5284 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5285 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5286 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125287 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5288
5289 // The non-alternate protocol job needs to hang in order to guarantee that
5290 // the alternate-protocol job will "win".
5291 AddHangingNonAlternateProtocolSocketData();
5292
5293 // In order for a new QUIC session to be established via alternate-protocol
5294 // without racing an HTTP connection, we need the host resolution to happen
5295 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5296 // connection to the the server, in this test we require confirmation
5297 // before encrypting so the HTTP job will still start.
5298 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295299 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125300 "");
zhongyica364fbb2015-12-12 03:39:125301
rch3f4b8452016-02-23 16:59:325302 CreateSession();
zhongyica364fbb2015-12-12 03:39:125303 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275304 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125305
bnc691fda62016-08-12 00:43:165306 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125307 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365308 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015309 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125310
5311 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525312 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015313 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125314 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525315 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125316
bnc691fda62016-08-12 00:43:165317 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525318 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125319}
5320
rchcd5f1c62016-06-23 02:43:485321TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5322 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525323 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365324 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435325 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5326 mock_quic_data.AddWrite(
5327 SYNCHRONOUS,
5328 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335329 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435330 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485331 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335332 mock_quic_data.AddRead(
5333 ASYNC, ConstructServerResponseHeadersPacket(
5334 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5335 GetResponseHeaders("200 OK")));
5336 mock_quic_data.AddRead(
5337 ASYNC, ConstructServerRstPacket(
5338 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5339 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435340 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485341 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5342 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5343
5344 // The non-alternate protocol job needs to hang in order to guarantee that
5345 // the alternate-protocol job will "win".
5346 AddHangingNonAlternateProtocolSocketData();
5347
5348 // In order for a new QUIC session to be established via alternate-protocol
5349 // without racing an HTTP connection, we need the host resolution to happen
5350 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5351 // connection to the the server, in this test we require confirmation
5352 // before encrypting so the HTTP job will still start.
5353 host_resolver_.set_synchronous_mode(true);
5354 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5355 "");
rchcd5f1c62016-06-23 02:43:485356
5357 CreateSession();
5358 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275359 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485360
bnc691fda62016-08-12 00:43:165361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485362 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365363 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485365
5366 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525367 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485368 // Read the headers.
robpercival214763f2016-07-01 23:27:015369 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485370
bnc691fda62016-08-12 00:43:165371 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485372 ASSERT_TRUE(response != nullptr);
5373 ASSERT_TRUE(response->headers.get() != nullptr);
5374 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5375 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525376 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445377 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5378 response->connection_info);
rchcd5f1c62016-06-23 02:43:485379
5380 std::string response_data;
bnc691fda62016-08-12 00:43:165381 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485382}
5383
5384TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485385 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485386 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525387 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365388 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435389 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5390 mock_quic_data.AddWrite(
5391 SYNCHRONOUS,
5392 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335393 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435394 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335395 mock_quic_data.AddRead(
5396 ASYNC, ConstructServerRstPacket(
5397 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5398 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485399 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5400 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5401
5402 // The non-alternate protocol job needs to hang in order to guarantee that
5403 // the alternate-protocol job will "win".
5404 AddHangingNonAlternateProtocolSocketData();
5405
5406 // In order for a new QUIC session to be established via alternate-protocol
5407 // without racing an HTTP connection, we need the host resolution to happen
5408 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5409 // connection to the the server, in this test we require confirmation
5410 // before encrypting so the HTTP job will still start.
5411 host_resolver_.set_synchronous_mode(true);
5412 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5413 "");
rchcd5f1c62016-06-23 02:43:485414
5415 CreateSession();
5416 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275417 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485418
bnc691fda62016-08-12 00:43:165419 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485420 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365421 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015422 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485423
5424 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525425 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485426 // Read the headers.
robpercival214763f2016-07-01 23:27:015427 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485428}
5429
[email protected]1e960032013-12-20 19:00:205430TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305431 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525432 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585433 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305434 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505435 MockRead(ASYNC, close->data(), close->length()),
5436 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5437 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305438 };
Ryan Sleevib8d7ea02018-05-07 20:01:015439 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305440 socket_factory_.AddSocketDataProvider(&quic_data);
5441
5442 // Main job which will succeed even though the alternate job fails.
5443 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025444 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5445 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5446 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305447
Ryan Sleevib8d7ea02018-05-07 20:01:015448 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305449 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565450 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305451
rch3f4b8452016-02-23 16:59:325452 CreateSession();
David Schinazic8281052019-01-24 06:14:175453 AddQuicAlternateProtocolMapping(
5454 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195455 SendRequestAndExpectHttpResponse("hello from http");
5456 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305457}
5458
[email protected]1e960032013-12-20 19:00:205459TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595460 // Alternate-protocol job
5461 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025462 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595463 };
Ryan Sleevib8d7ea02018-05-07 20:01:015464 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595465 socket_factory_.AddSocketDataProvider(&quic_data);
5466
5467 // Main job which will succeed even though the alternate job fails.
5468 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025469 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5470 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5471 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595472
Ryan Sleevib8d7ea02018-05-07 20:01:015473 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595474 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565475 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595476
rch3f4b8452016-02-23 16:59:325477 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595478
Ryan Hamilton9835e662018-08-02 05:36:275479 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195480 SendRequestAndExpectHttpResponse("hello from http");
5481 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595482}
5483
[email protected]00c159f2014-05-21 22:38:165484TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535485 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165486 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025487 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165488 };
Ryan Sleevib8d7ea02018-05-07 20:01:015489 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165490 socket_factory_.AddSocketDataProvider(&quic_data);
5491
[email protected]eb71ab62014-05-23 07:57:535492 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165493 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025494 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165495 };
5496
Ryan Sleevib8d7ea02018-05-07 20:01:015497 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165498 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5499 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565500 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165501
rtennetib8e80fb2016-05-16 00:12:095502 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325503 CreateSession();
[email protected]00c159f2014-05-21 22:38:165504
Ryan Hamilton9835e662018-08-02 05:36:275505 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165507 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165508 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015509 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5510 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165511 ExpectQuicAlternateProtocolMapping();
5512}
5513
Zhongyi Shia0cef1082017-08-25 01:49:505514TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5515 // Tests that TCP job is delayed and QUIC job does not require confirmation
5516 // if QUIC was recently supported on the same IP on start.
5517
5518 // Set QUIC support on the last IP address, which is same with the local IP
5519 // address. Require confirmation mode will be turned off immediately when
5520 // local IP address is sorted out after we configure the UDP socket.
5521 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5522
5523 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525524 quic::QuicStreamOffset header_stream_offset = 0;
Michael Warres167db3e2019-03-01 21:38:035525 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525526 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435527 mock_quic_data.AddWrite(
5528 SYNCHRONOUS,
5529 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335530 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435531 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435532 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335533 ASYNC, ConstructServerResponseHeadersPacket(
5534 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5535 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415536 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335537 mock_quic_data.AddRead(
5538 ASYNC, ConstructServerDataPacket(
5539 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415540 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435541 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505542 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5543 mock_quic_data.AddRead(ASYNC, 0); // EOF
5544
5545 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5546 // No HTTP data is mocked as TCP job never starts in this case.
5547
5548 CreateSession();
5549 // QuicStreamFactory by default requires confirmation on construction.
5550 session_->quic_stream_factory()->set_require_confirmation(true);
5551
Ryan Hamilton9835e662018-08-02 05:36:275552 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505553
5554 // Stall host resolution so that QUIC job will not succeed synchronously.
5555 // Socket will not be configured immediately and QUIC support is not sorted
5556 // out, TCP job will still be delayed as server properties indicates QUIC
5557 // support on last IP address.
5558 host_resolver_.set_synchronous_mode(false);
5559
5560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5561 TestCompletionCallback callback;
5562 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5563 IsError(ERR_IO_PENDING));
5564 // Complete host resolution in next message loop so that QUIC job could
5565 // proceed.
5566 base::RunLoop().RunUntilIdle();
5567 EXPECT_THAT(callback.WaitForResult(), IsOk());
5568
5569 CheckWasQuicResponse(&trans);
5570 CheckResponseData(&trans, "hello!");
5571}
5572
5573TEST_P(QuicNetworkTransactionTest,
5574 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5575 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5576 // was recently supported on a different IP address on start.
5577
5578 // Set QUIC support on the last IP address, which is different with the local
5579 // IP address. Require confirmation mode will remain when local IP address is
5580 // sorted out after we configure the UDP socket.
5581 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5582
5583 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525584 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505585 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435586 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5587 mock_quic_data.AddWrite(
5588 SYNCHRONOUS,
5589 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335590 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435591 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435592 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335593 ASYNC, ConstructServerResponseHeadersPacket(
5594 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5595 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415596 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335597 mock_quic_data.AddRead(
5598 ASYNC, ConstructServerDataPacket(
5599 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415600 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435601 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505602 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5603 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5604 // No HTTP data is mocked as TCP job will be delayed and never starts.
5605
5606 CreateSession();
5607 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275608 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505609
5610 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5611 // Socket will not be configured immediately and QUIC support is not sorted
5612 // out, TCP job will still be delayed as server properties indicates QUIC
5613 // support on last IP address.
5614 host_resolver_.set_synchronous_mode(false);
5615
5616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5617 TestCompletionCallback callback;
5618 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5619 IsError(ERR_IO_PENDING));
5620
5621 // Complete host resolution in next message loop so that QUIC job could
5622 // proceed.
5623 base::RunLoop().RunUntilIdle();
5624 // Explicitly confirm the handshake so that QUIC job could succeed.
5625 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525626 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505627 EXPECT_THAT(callback.WaitForResult(), IsOk());
5628
5629 CheckWasQuicResponse(&trans);
5630 CheckResponseData(&trans, "hello!");
5631}
5632
Ryan Hamilton75f197262017-08-17 14:00:075633TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5634 // Test that NetErrorDetails is correctly populated, even if the
5635 // handshake has not yet been confirmed and no stream has been created.
5636
5637 // QUIC job will pause. When resumed, it will fail.
5638 MockQuicData mock_quic_data;
5639 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5640 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5641 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5642
5643 // Main job will also fail.
5644 MockRead http_reads[] = {
5645 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5646 };
5647
Ryan Sleevib8d7ea02018-05-07 20:01:015648 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075649 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5650 socket_factory_.AddSocketDataProvider(&http_data);
5651 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5652
5653 AddHangingNonAlternateProtocolSocketData();
5654 CreateSession();
5655 // Require handshake confirmation to ensure that no QUIC streams are
5656 // created, and to ensure that the TCP job does not wait for the QUIC
5657 // job to fail before it starts.
5658 session_->quic_stream_factory()->set_require_confirmation(true);
5659
Ryan Hamilton9835e662018-08-02 05:36:275660 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5662 TestCompletionCallback callback;
5663 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5665 // Allow the TCP job to fail.
5666 base::RunLoop().RunUntilIdle();
5667 // Now let the QUIC job fail.
5668 mock_quic_data.Resume();
5669 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5670 ExpectQuicAlternateProtocolMapping();
5671 NetErrorDetails details;
5672 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525673 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075674}
5675
[email protected]1e960032013-12-20 19:00:205676TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455677 // Alternate-protocol job
5678 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025679 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455680 };
Ryan Sleevib8d7ea02018-05-07 20:01:015681 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455682 socket_factory_.AddSocketDataProvider(&quic_data);
5683
[email protected]c92c1b52014-05-31 04:16:065684 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015685 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065686 socket_factory_.AddSocketDataProvider(&quic_data2);
5687
[email protected]4d283b32013-10-17 12:57:275688 // Final job that will proceed when the QUIC job fails.
5689 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025690 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5691 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5692 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275693
Ryan Sleevib8d7ea02018-05-07 20:01:015694 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275695 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565696 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275697
rtennetiafccbc062016-05-16 18:21:145698 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325699 CreateSession();
[email protected]77c6c162013-08-17 02:57:455700
Ryan Hamilton9835e662018-08-02 05:36:275701 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455702
[email protected]4d283b32013-10-17 12:57:275703 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455704
5705 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275706
rch37de576c2015-05-17 20:28:175707 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5708 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455709}
5710
[email protected]93b31772014-06-19 08:03:355711TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035712 // Alternate-protocol job
5713 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595714 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035715 };
Ryan Sleevib8d7ea02018-05-07 20:01:015716 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035717 socket_factory_.AddSocketDataProvider(&quic_data);
5718
5719 // Main job that will proceed when the QUIC job fails.
5720 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025721 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5722 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5723 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035724
Ryan Sleevib8d7ea02018-05-07 20:01:015725 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035726 socket_factory_.AddSocketDataProvider(&http_data);
5727
rtennetib8e80fb2016-05-16 00:12:095728 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325729 CreateSession();
[email protected]65768442014-06-06 23:37:035730
Ryan Hamilton9835e662018-08-02 05:36:275731 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035732
5733 SendRequestAndExpectHttpResponse("hello from http");
5734}
5735
[email protected]eb71ab62014-05-23 07:57:535736TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335737 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015738 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495739 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335740 socket_factory_.AddSocketDataProvider(&quic_data);
5741
5742 // Main job which will succeed even though the alternate job fails.
5743 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025744 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5745 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5746 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335747
Ryan Sleevib8d7ea02018-05-07 20:01:015748 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335749 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565750 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335751
rch3f4b8452016-02-23 16:59:325752 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275753 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335754 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535755
5756 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335757}
5758
[email protected]4fee9672014-01-08 14:47:155759TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
Michael Warres167db3e2019-03-01 21:38:035760 if (version_ >= quic::QUIC_VERSION_47) {
5761 // TODO(nharper): reenable once MakeDummyCHLOPacket() fixed
5762 return;
5763 }
[email protected]4fee9672014-01-08 14:47:155764 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175765 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5766 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045767 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155768
5769 // When the QUIC connection fails, we will try the request again over HTTP.
5770 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485771 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565772 MockRead("hello world"),
5773 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5774 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155775
Ryan Sleevib8d7ea02018-05-07 20:01:015776 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155777 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565778 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155779
5780 // In order for a new QUIC session to be established via alternate-protocol
5781 // without racing an HTTP connection, we need the host resolution to happen
5782 // synchronously.
5783 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295784 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565785 "");
[email protected]4fee9672014-01-08 14:47:155786
rch3f4b8452016-02-23 16:59:325787 CreateSession();
David Schinazic8281052019-01-24 06:14:175788 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5789 AddQuicAlternateProtocolMapping(
5790 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155791 SendRequestAndExpectHttpResponse("hello world");
5792}
5793
tbansalc3308d72016-08-27 10:25:045794// For an alternative proxy that supports QUIC, test that the request is
5795// successfully fetched by the main job when the alternate proxy job encounters
5796// an error.
5797TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5798 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5799}
5800TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5801 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5802}
5803TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5804 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5805}
5806TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5807 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5808}
5809TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5810 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5811}
5812TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5813 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5814}
5815TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5816 TestAlternativeProxy(ERR_IO_PENDING);
5817}
5818TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5819 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5820}
5821
5822TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5823 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175824 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5825 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335826 mock_quic_data.AddWrite(
5827 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5828 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5829 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435830 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045831 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5832
5833 // When the QUIC connection fails, we will try the request again over HTTP.
5834 MockRead http_reads[] = {
5835 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5836 MockRead("hello world"),
5837 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5838 MockRead(ASYNC, OK)};
5839
Ryan Sleevib8d7ea02018-05-07 20:01:015840 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045841 socket_factory_.AddSocketDataProvider(&http_data);
5842 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5843
5844 TestProxyDelegate test_proxy_delegate;
5845 const HostPortPair host_port_pair("myproxy.org", 443);
5846 test_proxy_delegate.set_alternative_proxy_server(
5847 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5848 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5849
Ramin Halavatica8d5252018-03-12 05:33:495850 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5851 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525852 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045853 request_.url = GURL("http://mail.example.org/");
5854
5855 // In order for a new QUIC session to be established via alternate-protocol
5856 // without racing an HTTP connection, we need the host resolution to happen
5857 // synchronously.
5858 host_resolver_.set_synchronous_mode(true);
5859 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045860
5861 CreateSession();
David Schinazic8281052019-01-24 06:14:175862 crypto_client_stream_factory_.set_handshake_mode(
5863 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045864 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595865 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165866 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045867}
5868
bnc508835902015-05-12 20:10:295869TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585870 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385871 EXPECT_FALSE(
5872 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295873 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525874 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365875 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435876 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5877 mock_quic_data.AddWrite(
5878 SYNCHRONOUS,
5879 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335880 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435881 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435882 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335883 ASYNC, ConstructServerResponseHeadersPacket(
5884 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5885 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415886 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335887 mock_quic_data.AddRead(
5888 ASYNC, ConstructServerDataPacket(
5889 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415890 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435891 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505892 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295893 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5894
bncb07c05532015-05-14 19:07:205895 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095896 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325897 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275898 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295899 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385900 EXPECT_TRUE(
5901 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295902}
5903
zhongyi363c91c2017-03-23 23:16:085904// TODO(zhongyi): disabled this broken test as it was not testing the correct
5905// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5906TEST_P(QuicNetworkTransactionTest,
5907 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275908 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595909 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495910 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045911
5912 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045913
5914 test_proxy_delegate.set_alternative_proxy_server(
5915 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525916 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045917
5918 request_.url = GURL("http://mail.example.org/");
5919
5920 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5921 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015922 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045923 socket_factory_.AddSocketDataProvider(&socket_data);
5924
5925 // The non-alternate protocol job needs to hang in order to guarantee that
5926 // the alternate-protocol job will "win".
5927 AddHangingNonAlternateProtocolSocketData();
5928
5929 CreateSession();
5930 request_.method = "POST";
5931 ChunkedUploadDataStream upload_data(0);
5932 upload_data.AppendData("1", 1, true);
5933
5934 request_.upload_data_stream = &upload_data;
5935
5936 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5937 TestCompletionCallback callback;
5938 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5939 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5940 EXPECT_NE(OK, callback.WaitForResult());
5941
5942 // Verify that the alternative proxy server is not marked as broken.
5943 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5944
5945 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595946 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275947
5948 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5949 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5950 1);
tbansalc3308d72016-08-27 10:25:045951}
5952
rtenneti56977812016-01-15 19:26:565953TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415954 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575955 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565956
5957 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5958 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015959 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565960 socket_factory_.AddSocketDataProvider(&socket_data);
5961
rtennetib8e80fb2016-05-16 00:12:095962 // The non-alternate protocol job needs to hang in order to guarantee that
5963 // the alternate-protocol job will "win".
5964 AddHangingNonAlternateProtocolSocketData();
5965
rtenneti56977812016-01-15 19:26:565966 CreateSession();
5967 request_.method = "POST";
5968 ChunkedUploadDataStream upload_data(0);
5969 upload_data.AppendData("1", 1, true);
5970
5971 request_.upload_data_stream = &upload_data;
5972
bnc691fda62016-08-12 00:43:165973 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565974 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165975 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015976 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565977 EXPECT_NE(OK, callback.WaitForResult());
5978}
5979
rche11300ef2016-09-02 01:44:285980TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485981 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285982 ScopedMockNetworkChangeNotifier network_change_notifier;
5983 MockNetworkChangeNotifier* mock_ncn =
5984 network_change_notifier.mock_network_change_notifier();
5985 mock_ncn->ForceNetworkHandlesSupported();
5986 mock_ncn->SetConnectedNetworksList(
5987 {kDefaultNetworkForTests, kNewNetworkForTests});
5988
mmenke6ddfbea2017-05-31 21:48:415989 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285990 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315991 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285992
5993 MockQuicData socket_data;
5994 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525995 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435996 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:335997 socket_data.AddWrite(
5998 SYNCHRONOUS,
5999 ConstructClientRequestHeadersPacket(
6000 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6001 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286002 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6003 socket_data.AddSocketDataToFactory(&socket_factory_);
6004
6005 MockQuicData socket_data2;
6006 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6007 socket_data2.AddSocketDataToFactory(&socket_factory_);
6008
6009 // The non-alternate protocol job needs to hang in order to guarantee that
6010 // the alternate-protocol job will "win".
6011 AddHangingNonAlternateProtocolSocketData();
6012
6013 CreateSession();
6014 request_.method = "POST";
6015 ChunkedUploadDataStream upload_data(0);
6016
6017 request_.upload_data_stream = &upload_data;
6018
rdsmith1d343be52016-10-21 20:37:506019 std::unique_ptr<HttpNetworkTransaction> trans(
6020 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286021 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506022 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6024
6025 base::RunLoop().RunUntilIdle();
6026 upload_data.AppendData("1", 1, true);
6027 base::RunLoop().RunUntilIdle();
6028
6029 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506030 trans.reset();
rche11300ef2016-09-02 01:44:286031 session_.reset();
6032}
6033
Ryan Hamilton4b3574532017-10-30 20:17:256034TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6035 session_params_.origins_to_force_quic_on.insert(
6036 HostPortPair::FromString("mail.example.org:443"));
6037
6038 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526039 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436040 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256041 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336042 socket_data.AddWrite(
6043 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6044 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6045 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436046 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336047 ASYNC, ConstructServerResponseHeadersPacket(
6048 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6049 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416050 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336051 socket_data.AddRead(
6052 ASYNC, ConstructServerDataPacket(
6053 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416054 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436055 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256056 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166057 socket_data.AddWrite(
6058 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6059 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6060 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256061
6062 socket_data.AddSocketDataToFactory(&socket_factory_);
6063
6064 CreateSession();
6065
6066 SendRequestAndExpectQuicResponse("hello!");
6067 session_.reset();
6068}
6069
6070TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6071 session_params_.origins_to_force_quic_on.insert(
6072 HostPortPair::FromString("mail.example.org:443"));
6073
6074 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526075 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436076 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256077 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336078 socket_data.AddWrite(
6079 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6080 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6081 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436082 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336083 ASYNC, ConstructServerResponseHeadersPacket(
6084 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6085 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416086 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336087 socket_data.AddRead(
6088 ASYNC, ConstructServerDataPacket(
6089 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416090 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436091 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256092 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166093 socket_data.AddWrite(
6094 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6095 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6096 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256097
6098 socket_data.AddSocketDataToFactory(&socket_factory_);
6099
6100 CreateSession();
6101
6102 SendRequestAndExpectQuicResponse("hello!");
6103 session_.reset();
6104}
6105
Ryan Hamilton9edcf1a2017-11-22 05:55:176106TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486107 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256108 session_params_.origins_to_force_quic_on.insert(
6109 HostPortPair::FromString("mail.example.org:443"));
6110
6111 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526112 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256113 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436114 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176115 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256116 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6117 }
6118 socket_data.AddSocketDataToFactory(&socket_factory_);
6119
6120 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176121 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6122 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6123 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6124 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256125
Ryan Hamilton8d9ee76e2018-05-29 23:52:526126 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6128 TestCompletionCallback callback;
6129 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6130 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176131 while (!callback.have_result()) {
6132 base::RunLoop().RunUntilIdle();
6133 quic_task_runner_->RunUntilIdle();
6134 }
6135 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256136 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176137 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6138 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6139 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526140 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6141 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256142}
6143
Ryan Hamilton9edcf1a2017-11-22 05:55:176144TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486145 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256146 session_params_.origins_to_force_quic_on.insert(
6147 HostPortPair::FromString("mail.example.org:443"));
6148
6149 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526150 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256151 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436152 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176153 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256154 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6155 }
6156 socket_data.AddSocketDataToFactory(&socket_factory_);
6157
6158 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176159 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6160 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6161 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6162 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256163
Ryan Hamilton8d9ee76e2018-05-29 23:52:526164 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256165 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6166 TestCompletionCallback callback;
6167 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6168 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176169 while (!callback.have_result()) {
6170 base::RunLoop().RunUntilIdle();
6171 quic_task_runner_->RunUntilIdle();
6172 }
6173 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256174 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176175 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6176 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6177 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526178 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6179 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256180}
6181
Cherie Shi7596de632018-02-22 07:28:186182TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486183 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186184 session_params_.origins_to_force_quic_on.insert(
6185 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526186 const quic::QuicString error_details =
6187 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6188 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186189
6190 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526191 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186192 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436193 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186194 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6195 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526196 socket_data.AddWrite(
6197 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6198 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186199 socket_data.AddSocketDataToFactory(&socket_factory_);
6200
6201 CreateSession();
6202
6203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6204 TestCompletionCallback callback;
6205 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6207 base::RunLoop().RunUntilIdle();
6208 ASSERT_TRUE(callback.have_result());
6209 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6210 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6211 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6212}
6213
ckrasic769733c2016-06-30 00:42:136214// Adds coverage to catch regression such as https://crbug.com/622043
6215TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416216 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136217 HostPortPair::FromString("mail.example.org:443"));
6218
6219 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526220 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236221 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436222 mock_quic_data.AddWrite(
6223 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6224 &header_stream_offset));
6225 mock_quic_data.AddWrite(
6226 SYNCHRONOUS,
6227 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336228 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6229 true, true, GetRequestHeaders("GET", "https", "/"),
6230 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526231 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436232 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336233 ASYNC, ConstructServerPushPromisePacket(
6234 1, GetNthClientInitiatedBidirectionalStreamId(0),
6235 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6236 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6237 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576238 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266239 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336240 mock_quic_data.AddWrite(SYNCHRONOUS,
6241 ConstructClientPriorityPacket(
6242 client_packet_number++, false,
6243 GetNthServerInitiatedUnidirectionalStreamId(0),
6244 GetNthClientInitiatedBidirectionalStreamId(0),
6245 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576246 }
Zhongyi Shi32f2fd02018-04-16 18:23:436247 mock_quic_data.AddRead(
6248 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336249 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436250 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576251 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436252 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6253 mock_quic_data.AddRead(
6254 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336255 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6256 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416257 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436258 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336259 ASYNC, ConstructServerDataPacket(
6260 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416261 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576262 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436263 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416264 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436265 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336266 ASYNC, ConstructServerDataPacket(
6267 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416268 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336269 mock_quic_data.AddWrite(SYNCHRONOUS,
6270 ConstructClientAckAndRstPacket(
6271 client_packet_number++,
6272 GetNthServerInitiatedUnidirectionalStreamId(0),
6273 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136274 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6275 mock_quic_data.AddRead(ASYNC, 0); // EOF
6276 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6277
6278 // The non-alternate protocol job needs to hang in order to guarantee that
6279 // the alternate-protocol job will "win".
6280 AddHangingNonAlternateProtocolSocketData();
6281
6282 CreateSession();
6283
6284 // PUSH_PROMISE handling in the http layer gets exercised here.
6285 SendRequestAndExpectQuicResponse("hello!");
6286
6287 request_.url = GURL("https://mail.example.org/pushed.jpg");
6288 SendRequestAndExpectQuicResponse("and hello!");
6289
6290 // Check that the NetLog was filled reasonably.
6291 TestNetLogEntry::List entries;
6292 net_log_.GetEntries(&entries);
6293 EXPECT_LT(0u, entries.size());
6294
6295 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6296 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006297 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6298 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136299 EXPECT_LT(0, pos);
6300}
6301
rch56ec40a2017-06-23 14:48:446302// Regression test for http://crbug.com/719461 in which a promised stream
6303// is closed before the pushed headers arrive, but after the connection
6304// is closed and before the callbacks are executed.
6305TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486306 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446307 session_params_.origins_to_force_quic_on.insert(
6308 HostPortPair::FromString("mail.example.org:443"));
6309
6310 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526311 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236312 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446313 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436314 mock_quic_data.AddWrite(
6315 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6316 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446317 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436318 mock_quic_data.AddWrite(
6319 SYNCHRONOUS,
6320 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336321 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6322 true, true, GetRequestHeaders("GET", "https", "/"),
6323 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526324 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446325 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436326 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336327 ASYNC, ConstructServerPushPromisePacket(
6328 1, GetNthClientInitiatedBidirectionalStreamId(0),
6329 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6330 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6331 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576332 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266333 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336334 mock_quic_data.AddWrite(SYNCHRONOUS,
6335 ConstructClientPriorityPacket(
6336 client_packet_number++, false,
6337 GetNthServerInitiatedUnidirectionalStreamId(0),
6338 GetNthClientInitiatedBidirectionalStreamId(0),
6339 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576340 }
rch56ec40a2017-06-23 14:48:446341 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436342 mock_quic_data.AddRead(
6343 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336344 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436345 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446346 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576347 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436348 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446349 // Response body for first request.
Renjief49758b2019-01-11 23:32:416350 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436351 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336352 ASYNC, ConstructServerDataPacket(
6353 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416354 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446355 // Write error for the third request.
6356 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6357 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6358 mock_quic_data.AddRead(ASYNC, 0); // EOF
6359 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6360
6361 CreateSession();
6362
6363 // Send a request which triggers a push promise from the server.
6364 SendRequestAndExpectQuicResponse("hello!");
6365
6366 // Start a push transaction that will be cancelled after the connection
6367 // is closed, but before the callback is executed.
6368 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196369 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446370 session_.get());
6371 TestCompletionCallback callback2;
6372 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6374 base::RunLoop().RunUntilIdle();
6375
6376 // Cause the connection to close on a write error.
6377 HttpRequestInfo request3;
6378 request3.method = "GET";
6379 request3.url = GURL("https://mail.example.org/");
6380 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106381 request3.traffic_annotation =
6382 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446383 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6384 TestCompletionCallback callback3;
6385 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6386 IsError(ERR_IO_PENDING));
6387
6388 base::RunLoop().RunUntilIdle();
6389
6390 // When |trans2| is destroyed, the underlying stream will be closed.
6391 EXPECT_FALSE(callback2.have_result());
6392 trans2 = nullptr;
6393
6394 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6395}
6396
ckrasicda193a82016-07-09 00:39:366397TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416398 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366399 HostPortPair::FromString("mail.example.org:443"));
6400
6401 MockQuicData mock_quic_data;
6402
Ryan Hamilton8d9ee76e2018-05-29 23:52:526403 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416404 int write_packet_index = 1;
6405 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6406 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366407
Renjief49758b2019-01-11 23:32:416408 quic::QuicString header = ConstructDataHeader(1);
6409 if (version_ != quic::QUIC_VERSION_99) {
6410 mock_quic_data.AddWrite(
6411 SYNCHRONOUS,
6412 ConstructClientRequestHeadersAndDataFramesPacket(
6413 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6414 true, true, DEFAULT_PRIORITY,
6415 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6416 {"1"}));
6417 } else {
6418 mock_quic_data.AddWrite(
6419 SYNCHRONOUS,
6420 ConstructClientRequestHeadersAndDataFramesPacket(
6421 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6422 true, true, DEFAULT_PRIORITY,
6423 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6424 {header, "1"}));
6425 }
ckrasicda193a82016-07-09 00:39:366426
Zhongyi Shi32f2fd02018-04-16 18:23:436427 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336428 ASYNC, ConstructServerResponseHeadersPacket(
6429 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6430 GetResponseHeaders("200 OK")));
6431
Renjief49758b2019-01-11 23:32:416432 quic::QuicString header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336433 mock_quic_data.AddRead(
6434 ASYNC, ConstructServerDataPacket(
6435 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416436 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366437
Renjief49758b2019-01-11 23:32:416438 mock_quic_data.AddWrite(
6439 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366440
6441 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6442 mock_quic_data.AddRead(ASYNC, 0); // EOF
6443 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6444
6445 // The non-alternate protocol job needs to hang in order to guarantee that
6446 // the alternate-protocol job will "win".
6447 AddHangingNonAlternateProtocolSocketData();
6448
6449 CreateSession();
6450 request_.method = "POST";
6451 ChunkedUploadDataStream upload_data(0);
6452 upload_data.AppendData("1", 1, true);
6453
6454 request_.upload_data_stream = &upload_data;
6455
6456 SendRequestAndExpectQuicResponse("hello!");
6457}
6458
allada71b2efb2016-09-09 04:57:486459class QuicURLRequestContext : public URLRequestContext {
6460 public:
6461 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6462 MockClientSocketFactory* socket_factory)
6463 : storage_(this) {
6464 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076465 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046466 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486467 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046468 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596469 storage_.set_proxy_resolution_service(
6470 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076471 storage_.set_ssl_config_service(
6472 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486473 storage_.set_http_auth_handler_factory(
6474 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6475 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076476 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046477 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486478 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046479 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6480 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6481 false));
allada71b2efb2016-09-09 04:57:486482 }
6483
6484 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6485
6486 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6487
6488 private:
6489 MockClientSocketFactory* socket_factory_;
6490 URLRequestContextStorage storage_;
6491};
6492
6493TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416494 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486495 HostPortPair::FromString("mail.example.org:443"));
6496
6497 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526498 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366499 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436500 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136501 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486502 headers["user-agent"] = "";
6503 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336504 mock_quic_data.AddWrite(
6505 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6506 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6507 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486508
Ryan Hamilton8d9ee76e2018-05-29 23:52:526509 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336510 mock_quic_data.AddRead(
6511 ASYNC,
6512 ConstructServerResponseHeadersPacket(
6513 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6514 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486515
Renjief49758b2019-01-11 23:32:416516 quic::QuicString header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366517 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336518 ASYNC, ConstructServerDataPacket(
6519 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6520 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436521 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486522
6523 mock_quic_data.AddRead(ASYNC, 0); // EOF
6524
6525 CreateSession();
6526
6527 TestDelegate delegate;
6528 QuicURLRequestContext quic_url_request_context(std::move(session_),
6529 &socket_factory_);
6530
6531 mock_quic_data.AddSocketDataToFactory(
6532 &quic_url_request_context.socket_factory());
6533 TestNetworkDelegate network_delegate;
6534 quic_url_request_context.set_network_delegate(&network_delegate);
6535
6536 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296537 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6538 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486539 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6540 &ssl_data_);
6541
6542 request->Start();
Wez2a31b222018-06-07 22:07:156543 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486544
6545 EXPECT_LT(0, request->GetTotalSentBytes());
6546 EXPECT_LT(0, request->GetTotalReceivedBytes());
6547 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6548 request->GetTotalSentBytes());
6549 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6550 request->GetTotalReceivedBytes());
6551 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6552 request->raw_header_size());
Wez0e717112018-06-18 23:09:226553
6554 // Pump the message loop to allow all data to be consumed.
6555 base::RunLoop().RunUntilIdle();
6556
allada71b2efb2016-09-09 04:57:486557 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6558 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6559}
6560
6561TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416562 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486563 HostPortPair::FromString("mail.example.org:443"));
6564
6565 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526566 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236567 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436568 mock_quic_data.AddWrite(
6569 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6570 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136571 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486572 headers["user-agent"] = "";
6573 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436574 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336575 SYNCHRONOUS,
6576 ConstructClientRequestHeadersPacket(
6577 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6578 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486579
Ryan Hamilton8d9ee76e2018-05-29 23:52:526580 quic::QuicStreamOffset server_header_offset = 0;
6581 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486582
Zhongyi Shi32f2fd02018-04-16 18:23:436583 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336584 ASYNC, ConstructServerPushPromisePacket(
6585 1, GetNthClientInitiatedBidirectionalStreamId(0),
6586 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6587 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6588 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486589
Yixin Wangb470bc882018-02-15 18:43:576590 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266591 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336592 mock_quic_data.AddWrite(SYNCHRONOUS,
6593 ConstructClientPriorityPacket(
6594 client_packet_number++, false,
6595 GetNthServerInitiatedUnidirectionalStreamId(0),
6596 GetNthClientInitiatedBidirectionalStreamId(0),
6597 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576598 }
6599
allada71b2efb2016-09-09 04:57:486600 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436601 mock_quic_data.AddRead(
6602 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336603 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436604 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486605 expected_raw_header_response_size =
6606 server_header_offset - expected_raw_header_response_size;
6607
Yixin Wangb470bc882018-02-15 18:43:576608 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436609 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486610
ckrasicbf2f59c2017-05-04 23:54:366611 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436612 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336613 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6614 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416615 quic::QuicString header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436616 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336617 ASYNC, ConstructServerDataPacket(
6618 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416619 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486620
Yixin Wangb470bc882018-02-15 18:43:576621 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436622 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416623 quic::QuicString header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366624 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336625 ASYNC, ConstructServerDataPacket(
6626 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416627 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486628
Zhongyi Shi32f2fd02018-04-16 18:23:436629 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486630
6631 CreateSession();
6632
6633 TestDelegate delegate;
6634 QuicURLRequestContext quic_url_request_context(std::move(session_),
6635 &socket_factory_);
6636
6637 mock_quic_data.AddSocketDataToFactory(
6638 &quic_url_request_context.socket_factory());
6639 TestNetworkDelegate network_delegate;
6640 quic_url_request_context.set_network_delegate(&network_delegate);
6641
6642 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296643 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6644 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486645 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6646 &ssl_data_);
6647
6648 request->Start();
Wez2a31b222018-06-07 22:07:156649 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486650
6651 EXPECT_LT(0, request->GetTotalSentBytes());
6652 EXPECT_LT(0, request->GetTotalReceivedBytes());
6653 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6654 request->GetTotalSentBytes());
6655 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6656 request->GetTotalReceivedBytes());
6657 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6658 request->raw_header_size());
Wez0e717112018-06-18 23:09:226659
6660 // Pump the message loop to allow all data to be consumed.
6661 base::RunLoop().RunUntilIdle();
6662
allada71b2efb2016-09-09 04:57:486663 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6664 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6665}
6666
Yixin Wang10f477ed2017-11-21 04:20:206667TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6668 session_params_.quic_host_whitelist.insert("mail.example.org");
6669
6670 MockRead http_reads[] = {
6671 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6672 MockRead("hello world"),
6673 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6674 MockRead(ASYNC, OK)};
6675
Ryan Sleevib8d7ea02018-05-07 20:01:016676 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206677 socket_factory_.AddSocketDataProvider(&http_data);
6678 AddCertificate(&ssl_data_);
6679 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6680
6681 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526682 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206683 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436684 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6685 mock_quic_data.AddWrite(
6686 SYNCHRONOUS,
6687 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336688 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436689 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436690 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336691 ASYNC, ConstructServerResponseHeadersPacket(
6692 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6693 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416694 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336695 mock_quic_data.AddRead(
6696 ASYNC, ConstructServerDataPacket(
6697 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416698 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436699 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206700 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6701 mock_quic_data.AddRead(ASYNC, 0); // EOF
6702
6703 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6704
6705 AddHangingNonAlternateProtocolSocketData();
6706 CreateSession();
6707
6708 SendRequestAndExpectHttpResponse("hello world");
6709 SendRequestAndExpectQuicResponse("hello!");
6710}
6711
6712TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6713 session_params_.quic_host_whitelist.insert("mail.example.com");
6714
6715 MockRead http_reads[] = {
6716 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6717 MockRead("hello world"),
6718 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6719 MockRead(ASYNC, OK)};
6720
Ryan Sleevib8d7ea02018-05-07 20:01:016721 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206722 socket_factory_.AddSocketDataProvider(&http_data);
6723 AddCertificate(&ssl_data_);
6724 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6725 socket_factory_.AddSocketDataProvider(&http_data);
6726 AddCertificate(&ssl_data_);
6727 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6728
6729 AddHangingNonAlternateProtocolSocketData();
6730 CreateSession();
6731
6732 SendRequestAndExpectHttpResponse("hello world");
6733 SendRequestAndExpectHttpResponse("hello world");
6734}
6735
bnc359ed2a2016-04-29 20:43:456736class QuicNetworkTransactionWithDestinationTest
6737 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016738 public ::testing::WithParamInterface<PoolingTestParams>,
6739 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456740 protected:
6741 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556742 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056743 client_headers_include_h2_stream_dependency_(
6744 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526745 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456746 destination_type_(GetParam().destination_type),
6747 cert_transparency_verifier_(new MultiLogCTVerifier()),
6748 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596749 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456750 auth_handler_factory_(
6751 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6752 random_generator_(0),
6753 ssl_data_(ASYNC, OK) {}
6754
6755 void SetUp() override {
6756 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556757 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456758
mmenke6ddfbea2017-05-31 21:48:416759 HttpNetworkSession::Params session_params;
6760 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346761 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446762 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056763 session_params.quic_headers_include_h2_stream_dependency =
6764 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416765
6766 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456767
Ryan Hamilton8d9ee76e2018-05-29 23:52:526768 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416769 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456770
6771 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276772 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416773 session_context.quic_crypto_client_stream_factory =
6774 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456775
mmenke6ddfbea2017-05-31 21:48:416776 session_context.quic_random = &random_generator_;
6777 session_context.client_socket_factory = &socket_factory_;
6778 session_context.host_resolver = &host_resolver_;
6779 session_context.cert_verifier = &cert_verifier_;
6780 session_context.transport_security_state = &transport_security_state_;
6781 session_context.cert_transparency_verifier =
6782 cert_transparency_verifier_.get();
6783 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6784 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456785 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416786 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596787 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416788 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6789 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456790
mmenke6ddfbea2017-05-31 21:48:416791 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456792 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456793 }
6794
6795 void TearDown() override {
6796 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6797 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556798 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456799 PlatformTest::TearDown();
6800 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556801 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406802 session_.reset();
bnc359ed2a2016-04-29 20:43:456803 }
6804
zhongyie537a002017-06-27 16:48:216805 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456806 HostPortPair destination;
6807 switch (destination_type_) {
6808 case SAME_AS_FIRST:
6809 destination = HostPortPair(origin1_, 443);
6810 break;
6811 case SAME_AS_SECOND:
6812 destination = HostPortPair(origin2_, 443);
6813 break;
6814 case DIFFERENT:
6815 destination = HostPortPair(kDifferentHostname, 443);
6816 break;
6817 }
bnc3472afd2016-11-17 15:27:216818 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456819 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216820 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456821 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446822 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456823 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526824 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236825 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526826 quic::QuicStreamId stream_id,
6827 bool should_include_version,
6828 quic::QuicStreamOffset* offset,
6829 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486830 return ConstructClientRequestHeadersPacket(
6831 packet_number, stream_id, should_include_version, 0, offset, maker);
6832 }
bnc359ed2a2016-04-29 20:43:456833
Ryan Hamilton8d9ee76e2018-05-29 23:52:526834 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236835 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526836 quic::QuicStreamId stream_id,
6837 bool should_include_version,
6838 quic::QuicStreamId parent_stream_id,
6839 quic::QuicStreamOffset* offset,
6840 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136841 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456842 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136843 spdy::SpdyHeaderBlock headers(
6844 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456845 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6846 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486847 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456848 }
6849
Ryan Hamilton8d9ee76e2018-05-29 23:52:526850 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236851 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526852 quic::QuicStreamId stream_id,
6853 bool should_include_version,
6854 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586855 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456856 packet_number, stream_id, should_include_version, nullptr, maker);
6857 }
6858
Ryan Hamilton8d9ee76e2018-05-29 23:52:526859 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236860 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526861 quic::QuicStreamId stream_id,
6862 quic::QuicStreamOffset* offset,
6863 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136864 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456865 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266866 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456867 }
6868
Ryan Hamilton8d9ee76e2018-05-29 23:52:526869 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236870 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526871 quic::QuicStreamId stream_id,
6872 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586873 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6874 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456875 }
6876
Ryan Hamilton8d9ee76e2018-05-29 23:52:526877 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236878 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526879 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456880 QuicTestPacketMaker* maker) {
Renjief49758b2019-01-11 23:32:416881 quic::QuicString header = "";
6882 if (version_ == quic::QUIC_VERSION_99) {
6883 quic::HttpEncoder encoder;
6884 std::unique_ptr<char[]> buffer;
6885 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
6886 header = quic::QuicString(buffer.get(), header_length);
6887 }
bnc359ed2a2016-04-29 20:43:456888 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416889 header + "hello");
bnc359ed2a2016-04-29 20:43:456890 }
6891
Ryan Hamilton8d9ee76e2018-05-29 23:52:526892 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236893 uint64_t packet_number,
6894 uint64_t largest_received,
6895 uint64_t smallest_received,
6896 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456897 QuicTestPacketMaker* maker) {
6898 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496899 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456900 }
6901
Ryan Hamilton8d9ee76e2018-05-29 23:52:526902 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236903 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526904 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376905 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366906 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376907 }
6908
bnc359ed2a2016-04-29 20:43:456909 void AddRefusedSocketData() {
6910 std::unique_ptr<StaticSocketDataProvider> refused_data(
6911 new StaticSocketDataProvider());
6912 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6913 refused_data->set_connect_data(refused_connect);
6914 socket_factory_.AddSocketDataProvider(refused_data.get());
6915 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6916 }
6917
6918 void AddHangingSocketData() {
6919 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6920 new StaticSocketDataProvider());
6921 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6922 hanging_data->set_connect_data(hanging_connect);
6923 socket_factory_.AddSocketDataProvider(hanging_data.get());
6924 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6925 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6926 }
6927
6928 bool AllDataConsumed() {
6929 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6930 if (!socket_data_ptr->AllReadDataConsumed() ||
6931 !socket_data_ptr->AllWriteDataConsumed()) {
6932 return false;
6933 }
6934 }
6935 return true;
6936 }
6937
6938 void SendRequestAndExpectQuicResponse(const std::string& host) {
6939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6940 HttpRequestInfo request;
6941 std::string url("https://");
6942 url.append(host);
6943 request.url = GURL(url);
6944 request.load_flags = 0;
6945 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106946 request.traffic_annotation =
6947 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456948 TestCompletionCallback callback;
6949 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016950 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456951
6952 std::string response_data;
robpercival214763f2016-07-01 23:27:016953 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456954 EXPECT_EQ("hello", response_data);
6955
6956 const HttpResponseInfo* response = trans.GetResponseInfo();
6957 ASSERT_TRUE(response != nullptr);
6958 ASSERT_TRUE(response->headers.get() != nullptr);
6959 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6960 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526961 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446962 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456963 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376964 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456965 }
6966
Fan Yang32c5a112018-12-10 20:06:336967 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
6968 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366969 }
6970
Ryan Hamilton8d9ee76e2018-05-29 23:52:526971 quic::MockClock clock_;
6972 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056973 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526974 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456975 DestinationType destination_type_;
6976 std::string origin1_;
6977 std::string origin2_;
6978 std::unique_ptr<HttpNetworkSession> session_;
6979 MockClientSocketFactory socket_factory_;
6980 MockHostResolver host_resolver_;
6981 MockCertVerifier cert_verifier_;
6982 TransportSecurityState transport_security_state_;
6983 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236984 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456985 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076986 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596987 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456988 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526989 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456990 HttpServerPropertiesImpl http_server_properties_;
6991 BoundTestNetLog net_log_;
6992 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6993 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6994 static_socket_data_provider_vector_;
6995 SSLSocketDataProvider ssl_data_;
6996};
6997
Victor Costane635086f2019-01-27 05:20:306998INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6999 QuicNetworkTransactionWithDestinationTest,
7000 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457001
7002// A single QUIC request fails because the certificate does not match the origin
7003// hostname, regardless of whether it matches the alternative service hostname.
7004TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7005 if (destination_type_ == DIFFERENT)
7006 return;
7007
7008 GURL url("https://mail.example.com/");
7009 origin1_ = url.host();
7010
7011 // Not used for requests, but this provides a test case where the certificate
7012 // is valid for the hostname of the alternative service.
7013 origin2_ = "mail.example.org";
7014
zhongyie537a002017-06-27 16:48:217015 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457016
7017 scoped_refptr<X509Certificate> cert(
7018 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247019 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7020 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457021
7022 ProofVerifyDetailsChromium verify_details;
7023 verify_details.cert_verify_result.verified_cert = cert;
7024 verify_details.cert_verify_result.is_issued_by_known_root = true;
7025 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7026
7027 MockQuicData mock_quic_data;
7028 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7029 mock_quic_data.AddRead(ASYNC, 0);
7030
7031 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7032
7033 AddRefusedSocketData();
7034
7035 HttpRequestInfo request;
7036 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107037 request.traffic_annotation =
7038 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457039
7040 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7041 TestCompletionCallback callback;
7042 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017043 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457044
7045 EXPECT_TRUE(AllDataConsumed());
7046}
7047
7048// First request opens QUIC session to alternative service. Second request
7049// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527050// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457051TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7052 origin1_ = "mail.example.org";
7053 origin2_ = "news.example.org";
7054
zhongyie537a002017-06-27 16:48:217055 SetQuicAlternativeService(origin1_);
7056 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457057
7058 scoped_refptr<X509Certificate> cert(
7059 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247060 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7061 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7062 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457063
7064 ProofVerifyDetailsChromium verify_details;
7065 verify_details.cert_verify_result.verified_cert = cert;
7066 verify_details.cert_verify_result.is_issued_by_known_root = true;
7067 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7068
Yixin Wang079ad542018-01-11 04:06:057069 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177070 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7071 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057072 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177073 QuicTestPacketMaker server_maker(
7074 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7075 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457076
Ryan Hamilton8d9ee76e2018-05-29 23:52:527077 quic::QuicStreamOffset request_header_offset(0);
7078 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457079
7080 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057081 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437082 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057083 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337084 mock_quic_data.AddWrite(
7085 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7086 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7087 &request_header_offset, &client_maker));
7088 mock_quic_data.AddRead(ASYNC,
7089 ConstructServerResponseHeadersPacket(
7090 1, GetNthClientInitiatedBidirectionalStreamId(0),
7091 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437092 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337093 ASYNC,
7094 ConstructServerDataPacket(
7095 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437096 mock_quic_data.AddWrite(SYNCHRONOUS,
7097 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457098
Yixin Wang079ad542018-01-11 04:06:057099 client_maker.set_hostname(origin2_);
7100 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457101
Zhongyi Shi32f2fd02018-04-16 18:23:437102 mock_quic_data.AddWrite(
7103 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337104 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7105 GetNthClientInitiatedBidirectionalStreamId(0),
7106 &request_header_offset, &client_maker));
7107 mock_quic_data.AddRead(ASYNC,
7108 ConstructServerResponseHeadersPacket(
7109 3, GetNthClientInitiatedBidirectionalStreamId(1),
7110 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437111 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337112 ASYNC,
7113 ConstructServerDataPacket(
7114 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437115 mock_quic_data.AddWrite(SYNCHRONOUS,
7116 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457117 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7118 mock_quic_data.AddRead(ASYNC, 0); // EOF
7119
7120 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7121
7122 AddHangingSocketData();
7123 AddHangingSocketData();
7124
Fan Yangc9e00dc2018-10-09 14:17:567125 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7126 QuicStreamFactoryPeer::SetAlarmFactory(
7127 session_->quic_stream_factory(),
7128 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7129 &clock_));
7130
bnc359ed2a2016-04-29 20:43:457131 SendRequestAndExpectQuicResponse(origin1_);
7132 SendRequestAndExpectQuicResponse(origin2_);
7133
7134 EXPECT_TRUE(AllDataConsumed());
7135}
7136
7137// First request opens QUIC session to alternative service. Second request does
7138// not pool to it, even though destination matches, because certificate is not
7139// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527140// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457141TEST_P(QuicNetworkTransactionWithDestinationTest,
7142 DoNotPoolIfCertificateInvalid) {
7143 origin1_ = "news.example.org";
7144 origin2_ = "mail.example.com";
7145
zhongyie537a002017-06-27 16:48:217146 SetQuicAlternativeService(origin1_);
7147 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457148
7149 scoped_refptr<X509Certificate> cert1(
7150 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247151 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7152 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7153 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457154
7155 scoped_refptr<X509Certificate> cert2(
7156 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247157 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7158 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457159
7160 ProofVerifyDetailsChromium verify_details1;
7161 verify_details1.cert_verify_result.verified_cert = cert1;
7162 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7163 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7164
7165 ProofVerifyDetailsChromium verify_details2;
7166 verify_details2.cert_verify_result.verified_cert = cert2;
7167 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7168 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7169
Yixin Wang079ad542018-01-11 04:06:057170 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177171 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7172 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057173 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177174 QuicTestPacketMaker server_maker1(
7175 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7176 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457177
7178 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527179 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457180 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437181 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7182 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337183 mock_quic_data1.AddWrite(
7184 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7185 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7186 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437187 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337188 ASYNC,
7189 ConstructServerResponseHeadersPacket(
7190 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437191 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337192 ASYNC,
7193 ConstructServerDataPacket(
7194 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437195 mock_quic_data1.AddWrite(
7196 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457197 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7198 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7199
7200 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7201
Yixin Wang079ad542018-01-11 04:06:057202 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177203 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7204 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057205 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177206 QuicTestPacketMaker server_maker2(
7207 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7208 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457209
7210 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527211 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457212 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437213 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7214 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337215 mock_quic_data2.AddWrite(
7216 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7217 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7218 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437219 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337220 ASYNC,
7221 ConstructServerResponseHeadersPacket(
7222 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437223 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337224 ASYNC,
7225 ConstructServerDataPacket(
7226 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437227 mock_quic_data2.AddWrite(
7228 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457229 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7230 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7231
7232 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7233
bnc359ed2a2016-04-29 20:43:457234 SendRequestAndExpectQuicResponse(origin1_);
7235 SendRequestAndExpectQuicResponse(origin2_);
7236
7237 EXPECT_TRUE(AllDataConsumed());
7238}
7239
ckrasicdee37572017-04-06 22:42:277240// crbug.com/705109 - this confirms that matching request with a body
7241// triggers a crash (pre-fix).
7242TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417243 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277244 HostPortPair::FromString("mail.example.org:443"));
7245
7246 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527247 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237248 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437249 mock_quic_data.AddWrite(
7250 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7251 &header_stream_offset));
7252 mock_quic_data.AddWrite(
7253 SYNCHRONOUS,
7254 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337255 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7256 true, true, GetRequestHeaders("GET", "https", "/"),
7257 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527258 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437259 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337260 ASYNC, ConstructServerPushPromisePacket(
7261 1, GetNthClientInitiatedBidirectionalStreamId(0),
7262 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7263 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7264 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577265 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267266 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337267 mock_quic_data.AddWrite(SYNCHRONOUS,
7268 ConstructClientPriorityPacket(
7269 client_packet_number++, false,
7270 GetNthServerInitiatedUnidirectionalStreamId(0),
7271 GetNthClientInitiatedBidirectionalStreamId(0),
7272 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577273 }
Zhongyi Shi32f2fd02018-04-16 18:23:437274 mock_quic_data.AddRead(
7275 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337276 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437277 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577278 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437279 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7280 mock_quic_data.AddRead(
7281 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337282 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7283 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417284 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437285 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337286 ASYNC, ConstructServerDataPacket(
7287 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417288 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577289 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437290 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417291
7292 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437293 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337294 ASYNC, ConstructServerDataPacket(
7295 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417296 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277297
7298 // Because the matching request has a body, we will see the push
7299 // stream get cancelled, and the matching request go out on the
7300 // wire.
Fan Yang32c5a112018-12-10 20:06:337301 mock_quic_data.AddWrite(SYNCHRONOUS,
7302 ConstructClientAckAndRstPacket(
7303 client_packet_number++,
7304 GetNthServerInitiatedUnidirectionalStreamId(0),
7305 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277306 const char kBody[] = "1";
Renjief49758b2019-01-11 23:32:417307 quic::QuicString header3 = ConstructDataHeader(1);
7308 if (version_ != quic::QUIC_VERSION_99) {
7309 mock_quic_data.AddWrite(
7310 SYNCHRONOUS,
7311 ConstructClientRequestHeadersAndDataFramesPacket(
7312 client_packet_number++,
7313 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7314 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7315 GetNthServerInitiatedUnidirectionalStreamId(0),
7316 &header_stream_offset, nullptr, {kBody}));
7317 } else {
7318 mock_quic_data.AddWrite(
7319 SYNCHRONOUS,
7320 ConstructClientRequestHeadersAndDataFramesPacket(
7321 client_packet_number++,
7322 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7323 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7324 GetNthServerInitiatedUnidirectionalStreamId(0),
7325 &header_stream_offset, nullptr, {header3, kBody}));
7326 }
ckrasicdee37572017-04-06 22:42:277327
7328 // We see the same response as for the earlier pushed and cancelled
7329 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437330 mock_quic_data.AddRead(
7331 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337332 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437333 GetResponseHeaders("200 OK"), &server_header_offset));
7334 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337335 ASYNC, ConstructServerDataPacket(
7336 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417337 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277338
Yixin Wangb470bc882018-02-15 18:43:577339 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437340 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277341 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7342 mock_quic_data.AddRead(ASYNC, 0); // EOF
7343 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7344
7345 // The non-alternate protocol job needs to hang in order to guarantee that
7346 // the alternate-protocol job will "win".
7347 AddHangingNonAlternateProtocolSocketData();
7348
7349 CreateSession();
7350
7351 // PUSH_PROMISE handling in the http layer gets exercised here.
7352 SendRequestAndExpectQuicResponse("hello!");
7353
7354 request_.url = GURL("https://mail.example.org/pushed.jpg");
7355 ChunkedUploadDataStream upload_data(0);
7356 upload_data.AppendData("1", 1, true);
7357 request_.upload_data_stream = &upload_data;
7358 SendRequestAndExpectQuicResponse("and hello!");
7359}
7360
Bence Béky7538a952018-02-01 16:59:527361// Regression test for https://crbug.com/797825: If pushed headers describe a
7362// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7363// not be called (otherwise a DCHECK fails).
7364TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137365 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527366 pushed_request_headers[":authority"] = "";
7367 pushed_request_headers[":method"] = "GET";
7368 pushed_request_headers[":path"] = "/";
7369 pushed_request_headers[":scheme"] = "nosuchscheme";
7370
7371 session_params_.origins_to_force_quic_on.insert(
7372 HostPortPair::FromString("mail.example.org:443"));
7373
7374 MockQuicData mock_quic_data;
7375
Ryan Hamilton8d9ee76e2018-05-29 23:52:527376 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527377 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437378 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7379 mock_quic_data.AddWrite(
7380 SYNCHRONOUS,
7381 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337382 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437383 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527384
Ryan Hamilton8d9ee76e2018-05-29 23:52:527385 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337386 mock_quic_data.AddRead(
7387 ASYNC, ConstructServerPushPromisePacket(
7388 1, GetNthClientInitiatedBidirectionalStreamId(0),
7389 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7390 std::move(pushed_request_headers), &server_header_offset,
7391 &server_maker_));
7392 mock_quic_data.AddWrite(SYNCHRONOUS,
7393 ConstructClientRstPacket(
7394 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7395 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527396
Zhongyi Shi32f2fd02018-04-16 18:23:437397 mock_quic_data.AddRead(
7398 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337399 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437400 GetResponseHeaders("200 OK"), &server_header_offset));
7401 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527402
Zhongyi Shi32f2fd02018-04-16 18:23:437403 mock_quic_data.AddRead(
7404 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337405 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7406 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417407 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437408 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337409 ASYNC, ConstructServerDataPacket(
7410 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417411 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437412 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527413
7414 mock_quic_data.AddRead(ASYNC, 0);
7415 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7416
7417 // The non-alternate protocol job needs to hang in order to guarantee that
7418 // the alternate-protocol job will "win".
7419 AddHangingNonAlternateProtocolSocketData();
7420
7421 CreateSession();
7422
7423 // PUSH_PROMISE handling in the http layer gets exercised here.
7424 SendRequestAndExpectQuicResponse("hello!");
7425
7426 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7427 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7428}
7429
Yixin Wang46a273ec302018-01-23 17:59:567430// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147431TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567432 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147433 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567434 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497435 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567436
7437 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527438 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567439 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357440 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337441 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357442 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7443 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7444 false, ConnectRequestHeaders("mail.example.org:443"),
7445 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337446 mock_quic_data.AddRead(
7447 ASYNC, ConstructServerResponseHeadersPacket(
7448 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7449 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567450
7451 const char get_request[] =
7452 "GET / HTTP/1.1\r\n"
7453 "Host: mail.example.org\r\n"
7454 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417455 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7456 if (version_ != quic::QUIC_VERSION_99) {
7457 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357458 SYNCHRONOUS,
7459 ConstructClientAckAndDataPacket(
7460 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7461 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417462 } else {
7463 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417464 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357465 ConstructClientAckAndMultipleDataFramesPacket(
7466 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7467 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417468 }
7469
Yixin Wang46a273ec302018-01-23 17:59:567470 const char get_response[] =
7471 "HTTP/1.1 200 OK\r\n"
7472 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417473 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437474 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337475 ASYNC, ConstructServerDataPacket(
7476 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417477 0, header2 + quic::QuicString(get_response)));
7478 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337479 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417480 SYNCHRONOUS, ConstructServerDataPacket(
7481 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7482 false, strlen(get_response) + header2.length(),
7483 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357484 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567485 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7486
7487 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417488 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357489 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7490 quic::QUIC_STREAM_CANCELLED,
7491 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567492
7493 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7494
7495 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7496
7497 CreateSession();
7498
7499 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097500 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567501 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7502 HeadersHandler headers_handler;
7503 trans.SetBeforeHeadersSentCallback(
7504 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7505 base::Unretained(&headers_handler)));
7506 RunTransaction(&trans);
7507 CheckWasHttpResponse(&trans);
7508 CheckResponsePort(&trans, 70);
7509 CheckResponseData(&trans, "0123456789");
7510 EXPECT_TRUE(headers_handler.was_proxied());
7511 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7512
7513 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7514 // proxy socket to disconnect.
7515 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7516
7517 base::RunLoop().RunUntilIdle();
7518 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7519 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7520}
7521
7522// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147523TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567524 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147525 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567526 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497527 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567528
7529 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527530 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567531 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357532 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337533 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357534 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7535 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7536 false, ConnectRequestHeaders("mail.example.org:443"),
7537 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337538 mock_quic_data.AddRead(
7539 ASYNC, ConstructServerResponseHeadersPacket(
7540 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7541 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567542
7543 SpdyTestUtil spdy_util;
7544
Ryan Hamilton0239aac2018-05-19 00:03:137545 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567546 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417547 quic::QuicString header = ConstructDataHeader(get_frame.size());
7548 if (version_ != quic::QUIC_VERSION_99) {
7549 mock_quic_data.AddWrite(
7550 SYNCHRONOUS,
7551 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357552 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7553 false, 0,
Renjief49758b2019-01-11 23:32:417554 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7555 } else {
7556 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417557 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357558 ConstructClientAckAndMultipleDataFramesPacket(
7559 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7560 false, 0,
7561 {header, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417562 }
Ryan Hamilton0239aac2018-05-19 00:03:137563 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567564 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417565 quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437566 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337567 ASYNC,
7568 ConstructServerDataPacket(
7569 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Renjief49758b2019-01-11 23:32:417570 header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567571
Ryan Hamilton0239aac2018-05-19 00:03:137572 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197573 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Renjief49758b2019-01-11 23:32:417574 quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437575 mock_quic_data.AddRead(
7576 SYNCHRONOUS,
7577 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337578 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417579 resp_frame.size() + header2.length(),
7580 header3 + quic::QuicString(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357581 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567582 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7583
7584 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437585 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357586 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7587 quic::QUIC_STREAM_CANCELLED,
7588 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567589
7590 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7591
7592 SSLSocketDataProvider ssl_data(ASYNC, OK);
7593 ssl_data.next_proto = kProtoHTTP2;
7594 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7595
7596 CreateSession();
7597
7598 request_.url = GURL("https://mail.example.org/");
7599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7600 HeadersHandler headers_handler;
7601 trans.SetBeforeHeadersSentCallback(
7602 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7603 base::Unretained(&headers_handler)));
7604 RunTransaction(&trans);
7605 CheckWasSpdyResponse(&trans);
7606 CheckResponsePort(&trans, 70);
7607 CheckResponseData(&trans, "0123456789");
7608 EXPECT_TRUE(headers_handler.was_proxied());
7609 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7610
Wez0e717112018-06-18 23:09:227611 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7612 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567613 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7614
7615 base::RunLoop().RunUntilIdle();
7616 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7617 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7618}
7619
7620// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7621// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147622TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567623 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147624 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567625 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497626 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567627
7628 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527629 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417630 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567631 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417632 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7633 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337634 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417635 SYNCHRONOUS,
7636 ConstructClientRequestHeadersPacket(
7637 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7638 true, false, ConnectRequestHeaders("mail.example.org:443"),
7639 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337640 mock_quic_data.AddRead(
7641 ASYNC, ConstructServerResponseHeadersPacket(
7642 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7643 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567644
Ryan Hamilton8d9ee76e2018-05-29 23:52:527645 quic::QuicStreamOffset client_data_offset = 0;
7646 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567647 const char get_request_1[] =
7648 "GET / HTTP/1.1\r\n"
7649 "Host: mail.example.org\r\n"
7650 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417651 quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
7652 if (version_ != quic::QUIC_VERSION_99) {
7653 mock_quic_data.AddWrite(
7654 SYNCHRONOUS,
7655 ConstructClientAckAndDataPacket(
7656 write_packet_index++, false,
7657 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7658 client_data_offset, quic::QuicStringPiece(get_request_1)));
7659 } else {
7660 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417661 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357662 ConstructClientAckAndMultipleDataFramesPacket(
7663 write_packet_index++, false,
7664 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7665 client_data_offset, {header, quic::QuicString(get_request_1)}));
Renjief49758b2019-01-11 23:32:417666 }
7667
7668 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567669
7670 const char get_response_1[] =
7671 "HTTP/1.1 200 OK\r\n"
7672 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417673 quic::QuicString header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437674 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417675 ASYNC,
7676 ConstructServerDataPacket(
7677 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7678 server_data_offset, header2 + quic::QuicString(get_response_1)));
7679 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567680
Renjief49758b2019-01-11 23:32:417681 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337682 mock_quic_data.AddRead(
7683 SYNCHRONOUS,
7684 ConstructServerDataPacket(
7685 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417686 server_data_offset, header3 + quic::QuicString("0123456789")));
7687 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567688
Renjief49758b2019-01-11 23:32:417689 mock_quic_data.AddWrite(
7690 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567691
7692 const char get_request_2[] =
7693 "GET /2 HTTP/1.1\r\n"
7694 "Host: mail.example.org\r\n"
7695 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417696 quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
7697 if (version_ == quic::QUIC_VERSION_99) {
7698 mock_quic_data.AddWrite(
7699 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357700 ConstructClientMultipleDataFramesPacket(
7701 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7702 false, false, client_data_offset,
7703 {header4, quic::QuicString(get_request_2)}));
7704 client_data_offset += header4.length() + strlen(get_request_2);
7705 } else {
7706 mock_quic_data.AddWrite(
7707 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417708 ConstructClientDataPacket(write_packet_index++,
7709 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357710 false, false, client_data_offset,
7711 quic::QuicStringPiece(get_request_2)));
7712 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417713 }
Yixin Wang46a273ec302018-01-23 17:59:567714
7715 const char get_response_2[] =
7716 "HTTP/1.1 200 OK\r\n"
7717 "Content-Length: 7\r\n\r\n";
Renjief49758b2019-01-11 23:32:417718 quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437719 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417720 ASYNC,
7721 ConstructServerDataPacket(
7722 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7723 server_data_offset, header5 + quic::QuicString(get_response_2)));
7724 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567725
Renjief49758b2019-01-11 23:32:417726 quic::QuicString header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527727 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337728 SYNCHRONOUS,
7729 ConstructServerDataPacket(
7730 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417731 server_data_offset, header6 + quic::QuicString("0123456")));
7732 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567733
Renjief49758b2019-01-11 23:32:417734 mock_quic_data.AddWrite(
7735 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567736 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7737
Renjief49758b2019-01-11 23:32:417738 mock_quic_data.AddWrite(
7739 SYNCHRONOUS,
7740 ConstructClientRstPacket(
7741 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7742 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567743
7744 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7745
7746 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7747
7748 CreateSession();
7749
7750 request_.url = GURL("https://mail.example.org/");
7751 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7752 HeadersHandler headers_handler_1;
7753 trans_1.SetBeforeHeadersSentCallback(
7754 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7755 base::Unretained(&headers_handler_1)));
7756 RunTransaction(&trans_1);
7757 CheckWasHttpResponse(&trans_1);
7758 CheckResponsePort(&trans_1, 70);
7759 CheckResponseData(&trans_1, "0123456789");
7760 EXPECT_TRUE(headers_handler_1.was_proxied());
7761 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7762
7763 request_.url = GURL("https://mail.example.org/2");
7764 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7765 HeadersHandler headers_handler_2;
7766 trans_2.SetBeforeHeadersSentCallback(
7767 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7768 base::Unretained(&headers_handler_2)));
7769 RunTransaction(&trans_2);
7770 CheckWasHttpResponse(&trans_2);
7771 CheckResponsePort(&trans_2, 70);
7772 CheckResponseData(&trans_2, "0123456");
7773 EXPECT_TRUE(headers_handler_2.was_proxied());
7774 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7775
7776 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7777 // proxy socket to disconnect.
7778 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7779
7780 base::RunLoop().RunUntilIdle();
7781 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7782 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7783}
7784
7785// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7786// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7787// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147788TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567789 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147790 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567791 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497792 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567793
7794 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527795 quic::QuicStreamOffset client_header_stream_offset = 0;
7796 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357797 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7798 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567799
7800 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337801 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357802 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7803 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7804 false, ConnectRequestHeaders("mail.example.org:443"),
7805 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437806 mock_quic_data.AddRead(
7807 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337808 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437809 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567810
7811 // GET request, response, and data over QUIC tunnel for first request
7812 const char get_request[] =
7813 "GET / HTTP/1.1\r\n"
7814 "Host: mail.example.org\r\n"
7815 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417816 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7817 if (version_ != quic::QUIC_VERSION_99) {
7818 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357819 SYNCHRONOUS,
7820 ConstructClientAckAndDataPacket(
7821 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7822 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417823 } else {
7824 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417825 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357826 ConstructClientAckAndMultipleDataFramesPacket(
7827 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7828 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417829 }
7830
Yixin Wang46a273ec302018-01-23 17:59:567831 const char get_response[] =
7832 "HTTP/1.1 200 OK\r\n"
7833 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417834 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567835 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337836 ASYNC, ConstructServerDataPacket(
7837 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417838 0, header2 + quic::QuicString(get_response)));
7839 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337840 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417841 SYNCHRONOUS, ConstructServerDataPacket(
7842 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7843 false, strlen(get_response) + header2.length(),
7844 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357845 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567846
7847 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437848 mock_quic_data.AddWrite(
7849 SYNCHRONOUS,
7850 ConstructClientRequestHeadersPacket(
Renjied172e812019-01-16 05:12:357851 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7852 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:337853 GetNthClientInitiatedBidirectionalStreamId(0),
7854 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437855 mock_quic_data.AddRead(
7856 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337857 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437858 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567859
7860 // GET request, response, and data over QUIC tunnel for second request
7861 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137862 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567863 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417864 quic::QuicString header4 = ConstructDataHeader(get_frame.size());
7865 if (version_ != quic::QUIC_VERSION_99) {
7866 mock_quic_data.AddWrite(
7867 SYNCHRONOUS,
7868 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357869 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7870 false, 0,
Renjief49758b2019-01-11 23:32:417871 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7872 } else {
7873 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417874 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357875 ConstructClientAckAndMultipleDataFramesPacket(
7876 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7877 false, 0,
7878 {header4, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417879 }
Yixin Wang46a273ec302018-01-23 17:59:567880
Ryan Hamilton0239aac2018-05-19 00:03:137881 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567882 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417883 quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437884 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337885 ASYNC,
7886 ConstructServerDataPacket(
7887 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Renjief49758b2019-01-11 23:32:417888 header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567889
Ryan Hamilton0239aac2018-05-19 00:03:137890 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197891 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Renjief49758b2019-01-11 23:32:417892 quic::QuicString header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437893 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417894 ASYNC,
7895 ConstructServerDataPacket(
7896 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7897 resp_frame.size() + header5.length(),
7898 header6 + quic::QuicString(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567899
Renjied172e812019-01-16 05:12:357900 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567901 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7902
7903 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417904 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357905 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7906 quic::QUIC_STREAM_CANCELLED,
7907 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567908 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437909 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357910 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7911 quic::QUIC_STREAM_CANCELLED,
7912 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567913
7914 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7915
7916 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7917
7918 SSLSocketDataProvider ssl_data(ASYNC, OK);
7919 ssl_data.next_proto = kProtoHTTP2;
7920 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7921
7922 CreateSession();
7923
7924 request_.url = GURL("https://mail.example.org/");
7925 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7926 HeadersHandler headers_handler_1;
7927 trans_1.SetBeforeHeadersSentCallback(
7928 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7929 base::Unretained(&headers_handler_1)));
7930 RunTransaction(&trans_1);
7931 CheckWasHttpResponse(&trans_1);
7932 CheckResponsePort(&trans_1, 70);
7933 CheckResponseData(&trans_1, "0123456789");
7934 EXPECT_TRUE(headers_handler_1.was_proxied());
7935 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7936
7937 request_.url = GURL("https://different.example.org/");
7938 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7939 HeadersHandler headers_handler_2;
7940 trans_2.SetBeforeHeadersSentCallback(
7941 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7942 base::Unretained(&headers_handler_2)));
7943 RunTransaction(&trans_2);
7944 CheckWasSpdyResponse(&trans_2);
7945 CheckResponsePort(&trans_2, 70);
7946 CheckResponseData(&trans_2, "0123456");
7947 EXPECT_TRUE(headers_handler_2.was_proxied());
7948 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7949
7950 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7951 // proxy socket to disconnect.
7952 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7953
7954 base::RunLoop().RunUntilIdle();
7955 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7956 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7957}
7958
7959// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147960TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567961 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147962 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567963 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497964 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567965
7966 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527967 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567968 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437969 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527970 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337971 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7972 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7973 false, ConnectRequestHeaders("mail.example.org:443"),
7974 &header_stream_offset));
7975 mock_quic_data.AddRead(
7976 ASYNC, ConstructServerResponseHeadersPacket(
7977 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7978 GetResponseHeaders("500")));
7979 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7980 mock_quic_data.AddWrite(SYNCHRONOUS,
7981 ConstructClientAckAndRstPacket(
7982 3, GetNthClientInitiatedBidirectionalStreamId(0),
7983 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567984
7985 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7986
7987 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7988
7989 CreateSession();
7990
7991 request_.url = GURL("https://mail.example.org/");
7992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7993 HeadersHandler headers_handler;
7994 trans.SetBeforeHeadersSentCallback(
7995 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7996 base::Unretained(&headers_handler)));
7997 TestCompletionCallback callback;
7998 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7999 EXPECT_EQ(ERR_IO_PENDING, rv);
8000 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8001 EXPECT_EQ(false, headers_handler.was_proxied());
8002
8003 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8004 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8005}
8006
8007// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148008TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568009 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148010 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568011 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498012 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568013
8014 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528015 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568016 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438017 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338018 mock_quic_data.AddWrite(
8019 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8020 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8021 false, ConnectRequestHeaders("mail.example.org:443"),
8022 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568023 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8024
8025 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8026
8027 CreateSession();
8028
8029 request_.url = GURL("https://mail.example.org/");
8030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8031 HeadersHandler headers_handler;
8032 trans.SetBeforeHeadersSentCallback(
8033 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8034 base::Unretained(&headers_handler)));
8035 TestCompletionCallback callback;
8036 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8037 EXPECT_EQ(ERR_IO_PENDING, rv);
8038 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8039
8040 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8041 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8042}
8043
8044// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8045// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148046TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568047 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148048 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568049 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498050 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568051
8052 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528053 quic::QuicStreamOffset client_header_stream_offset = 0;
8054 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358055 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8056 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338057 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358058 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8059 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8060 false, ConnectRequestHeaders("mail.example.org:443"),
8061 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438062 mock_quic_data.AddRead(
8063 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338064 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438065 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358066 mock_quic_data.AddWrite(SYNCHRONOUS,
8067 ConstructClientAckAndRstPacket(
8068 3, GetNthClientInitiatedBidirectionalStreamId(0),
8069 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568070
Zhongyi Shi32f2fd02018-04-16 18:23:438071 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358072 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8073 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8074 false, ConnectRequestHeaders("mail.example.org:443"),
8075 GetNthClientInitiatedBidirectionalStreamId(0),
8076 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438077 mock_quic_data.AddRead(
8078 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338079 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438080 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568081
8082 const char get_request[] =
8083 "GET / HTTP/1.1\r\n"
8084 "Host: mail.example.org\r\n"
8085 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:418086 quic::QuicString header = ConstructDataHeader(strlen(get_request));
8087 if (version_ != quic::QUIC_VERSION_99) {
8088 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358089 SYNCHRONOUS,
8090 ConstructClientAckAndDataPacket(
8091 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8092 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418093 } else {
8094 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418095 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358096 ConstructClientAckAndMultipleDataFramesPacket(
8097 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8098 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:418099 }
Yixin Wang46a273ec302018-01-23 17:59:568100 const char get_response[] =
8101 "HTTP/1.1 200 OK\r\n"
8102 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:418103 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438104 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338105 ASYNC, ConstructServerDataPacket(
8106 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Renjief49758b2019-01-11 23:32:418107 0, header2 + quic::QuicString(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528108
Renjief49758b2019-01-11 23:32:418109 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338110 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418111 SYNCHRONOUS, ConstructServerDataPacket(
8112 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8113 false, strlen(get_response) + header2.length(),
8114 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358115 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568116 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8117
8118 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418119 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358120 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8121 quic::QUIC_STREAM_CANCELLED,
8122 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568123
8124 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8125
8126 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8127 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8128
8129 SSLSocketDataProvider ssl_data(ASYNC, OK);
8130 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8131
8132 CreateSession();
8133
8134 request_.url = GURL("https://mail.example.org/");
8135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8136 HeadersHandler headers_handler;
8137 trans.SetBeforeHeadersSentCallback(
8138 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8139 base::Unretained(&headers_handler)));
8140 TestCompletionCallback callback;
8141 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8142 EXPECT_EQ(ERR_IO_PENDING, rv);
8143 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8144
8145 rv = trans.RestartIgnoringLastError(callback.callback());
8146 EXPECT_EQ(ERR_IO_PENDING, rv);
8147 EXPECT_EQ(OK, callback.WaitForResult());
8148
8149 CheckWasHttpResponse(&trans);
8150 CheckResponsePort(&trans, 70);
8151 CheckResponseData(&trans, "0123456789");
8152 EXPECT_EQ(true, headers_handler.was_proxied());
8153 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8154
8155 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8156 // proxy socket to disconnect.
8157 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8158
8159 base::RunLoop().RunUntilIdle();
8160 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8161 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8162}
8163
8164// Checks if a request's specified "user-agent" header shows up correctly in the
8165// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148166TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Yixin Wang46a273ec302018-01-23 17:59:568167 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148168 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568169 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498170 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568171
8172 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528173 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568174 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438175 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568176
Ryan Hamilton0239aac2018-05-19 00:03:138177 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568178 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338179 mock_quic_data.AddWrite(
8180 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8181 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8182 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568183 // Return an error, so the transaction stops here (this test isn't interested
8184 // in the rest).
8185 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8186
8187 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8188
8189 CreateSession();
8190
8191 request_.url = GURL("https://mail.example.org/");
8192 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8193 "Chromium Ultra Awesome X Edition");
8194 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8195 HeadersHandler headers_handler;
8196 trans.SetBeforeHeadersSentCallback(
8197 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8198 base::Unretained(&headers_handler)));
8199 TestCompletionCallback callback;
8200 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8201 EXPECT_EQ(ERR_IO_PENDING, rv);
8202 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8203
8204 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8205 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8206}
8207
Yixin Wang00fc44c2018-01-23 21:12:208208// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8209// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148210TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208211 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148212 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208213 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498214 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208215
8216 const RequestPriority request_priority = MEDIUM;
8217
8218 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528219 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208220 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438221 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8222 mock_quic_data.AddWrite(
8223 SYNCHRONOUS,
8224 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338225 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8226 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438227 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208228 // Return an error, so the transaction stops here (this test isn't interested
8229 // in the rest).
8230 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8231
8232 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8233
8234 CreateSession();
8235
8236 request_.url = GURL("https://mail.example.org/");
8237 HttpNetworkTransaction trans(request_priority, session_.get());
8238 TestCompletionCallback callback;
8239 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8240 EXPECT_EQ(ERR_IO_PENDING, rv);
8241 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8242
8243 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8244 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8245}
8246
Yixin Wang46a273ec302018-01-23 17:59:568247// Test the request-challenge-retry sequence for basic auth, over a QUIC
8248// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148249TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568250 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8251 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138252 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568253 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8254
8255 std::unique_ptr<QuicTestPacketMaker> client_maker;
8256 std::unique_ptr<QuicTestPacketMaker> server_maker;
8257
8258 // On the second pass, the body read of the auth challenge is synchronous, so
8259 // IsConnectedAndIdle returns false. The socket should still be drained and
8260 // reused. See http://crbug.com/544255.
8261 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338262 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178263 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8264 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338265 client_headers_include_h2_stream_dependency_));
8266 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178267 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8268 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568269
8270 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148271 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568272 proxy_resolution_service_ =
8273 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498274 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568275
8276 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528277 quic::QuicStreamOffset client_header_stream_offset = 0;
8278 quic::QuicStreamOffset server_header_stream_offset = 0;
8279 quic::QuicStreamOffset client_data_offset = 0;
8280 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568281
Zhongyi Shi32f2fd02018-04-16 18:23:438282 mock_quic_data.AddWrite(SYNCHRONOUS,
8283 client_maker->MakeInitialSettingsPacket(
8284 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568285
8286 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438287 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568288 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338289 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8290 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568291 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8292 &client_header_stream_offset));
8293
Ryan Hamilton0239aac2018-05-19 00:03:138294 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568295 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8296 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8297 headers["content-length"] = "10";
8298 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438299 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338300 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8301 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568302
8303 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438304 mock_quic_data.AddRead(
8305 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338306 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8307 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568308 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438309 mock_quic_data.AddRead(
8310 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338311 2, GetNthClientInitiatedBidirectionalStreamId(0),
8312 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568313 }
8314 server_data_offset += 10;
8315
Zhongyi Shi32f2fd02018-04-16 18:23:438316 mock_quic_data.AddWrite(SYNCHRONOUS,
8317 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568318
8319 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338320 SYNCHRONOUS,
8321 client_maker->MakeRstPacket(
8322 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188323 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8324 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568325
8326 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8327 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8328 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338329 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8330 5, GetNthClientInitiatedBidirectionalStreamId(1),
8331 false, false, default_priority, std::move(headers),
8332 GetNthClientInitiatedBidirectionalStreamId(0),
8333 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568334
8335 // Response to wrong password
8336 headers =
8337 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8338 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8339 headers["content-length"] = "10";
8340 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438341 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338342 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8343 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568344 mock_quic_data.AddRead(SYNCHRONOUS,
8345 ERR_IO_PENDING); // No more data to read
8346
Fan Yang32c5a112018-12-10 20:06:338347 mock_quic_data.AddWrite(
8348 SYNCHRONOUS,
8349 client_maker->MakeAckAndRstPacket(
8350 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8351 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568352
8353 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8354 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8355
8356 CreateSession();
8357
8358 request_.url = GURL("https://mail.example.org/");
8359 // Ensure that proxy authentication is attempted even
8360 // when the no authentication data flag is set.
8361 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8362 {
8363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8364 HeadersHandler headers_handler;
8365 trans.SetBeforeHeadersSentCallback(
8366 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8367 base::Unretained(&headers_handler)));
8368 RunTransaction(&trans);
8369
8370 const HttpResponseInfo* response = trans.GetResponseInfo();
8371 ASSERT_TRUE(response != nullptr);
8372 ASSERT_TRUE(response->headers.get() != nullptr);
8373 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8374 response->headers->GetStatusLine());
8375 EXPECT_TRUE(response->headers->IsKeepAlive());
8376 EXPECT_EQ(407, response->headers->response_code());
8377 EXPECT_EQ(10, response->headers->GetContentLength());
8378 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8379 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8380 ASSERT_TRUE(auth_challenge != nullptr);
8381 EXPECT_TRUE(auth_challenge->is_proxy);
8382 EXPECT_EQ("https://proxy.example.org:70",
8383 auth_challenge->challenger.Serialize());
8384 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8385 EXPECT_EQ("basic", auth_challenge->scheme);
8386
8387 TestCompletionCallback callback;
8388 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8389 callback.callback());
8390 EXPECT_EQ(ERR_IO_PENDING, rv);
8391 EXPECT_EQ(OK, callback.WaitForResult());
8392
8393 response = trans.GetResponseInfo();
8394 ASSERT_TRUE(response != nullptr);
8395 ASSERT_TRUE(response->headers.get() != nullptr);
8396 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8397 response->headers->GetStatusLine());
8398 EXPECT_TRUE(response->headers->IsKeepAlive());
8399 EXPECT_EQ(407, response->headers->response_code());
8400 EXPECT_EQ(10, response->headers->GetContentLength());
8401 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8402 auth_challenge = response->auth_challenge.get();
8403 ASSERT_TRUE(auth_challenge != nullptr);
8404 EXPECT_TRUE(auth_challenge->is_proxy);
8405 EXPECT_EQ("https://proxy.example.org:70",
8406 auth_challenge->challenger.Serialize());
8407 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8408 EXPECT_EQ("basic", auth_challenge->scheme);
8409 }
8410 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8411 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8412 // reused because it's not connected).
8413 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8414 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8415 }
8416}
8417
Yixin Wang385652a2018-02-16 02:37:238418TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8419 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8420 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268421 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238422 !client_headers_include_h2_stream_dependency_) {
8423 return;
8424 }
8425
8426 session_params_.origins_to_force_quic_on.insert(
8427 HostPortPair::FromString("mail.example.org:443"));
8428
Fan Yang32c5a112018-12-10 20:06:338429 const quic::QuicStreamId client_stream_0 =
8430 GetNthClientInitiatedBidirectionalStreamId(0);
8431 const quic::QuicStreamId client_stream_1 =
8432 GetNthClientInitiatedBidirectionalStreamId(1);
8433 const quic::QuicStreamId client_stream_2 =
8434 GetNthClientInitiatedBidirectionalStreamId(2);
8435 const quic::QuicStreamId push_stream_0 =
8436 GetNthServerInitiatedUnidirectionalStreamId(0);
8437 const quic::QuicStreamId push_stream_1 =
8438 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238439
8440 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528441 quic::QuicStreamOffset header_stream_offset = 0;
8442 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238443 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438444 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238445
8446 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438447 mock_quic_data.AddWrite(SYNCHRONOUS,
8448 ConstructClientRequestHeadersPacket(
8449 2, client_stream_0, true, true, HIGHEST,
8450 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8451 &header_stream_offset));
8452 mock_quic_data.AddWrite(SYNCHRONOUS,
8453 ConstructClientRequestHeadersPacket(
8454 3, client_stream_1, true, true, MEDIUM,
8455 GetRequestHeaders("GET", "https", "/1.jpg"),
8456 client_stream_0, &header_stream_offset));
8457 mock_quic_data.AddWrite(SYNCHRONOUS,
8458 ConstructClientRequestHeadersPacket(
8459 4, client_stream_2, true, true, MEDIUM,
8460 GetRequestHeaders("GET", "https", "/2.jpg"),
8461 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238462
8463 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438464 mock_quic_data.AddRead(
8465 ASYNC, ConstructServerResponseHeadersPacket(
8466 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8467 &server_header_offset));
8468 mock_quic_data.AddRead(
8469 ASYNC, ConstructServerResponseHeadersPacket(
8470 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8471 &server_header_offset));
8472 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8473 mock_quic_data.AddRead(
8474 ASYNC, ConstructServerResponseHeadersPacket(
8475 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8476 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238477
8478 // Server sends two push promises associated with |client_stream_0|; client
8479 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8480 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438481 mock_quic_data.AddRead(ASYNC,
8482 ConstructServerPushPromisePacket(
8483 4, client_stream_0, push_stream_0, false,
8484 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8485 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238486 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438487 SYNCHRONOUS,
8488 ConstructClientAckAndPriorityFramesPacket(
8489 6, false, 4, 3, 1,
8490 {{push_stream_0, client_stream_2,
8491 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8492 &header_stream_offset));
8493 mock_quic_data.AddRead(ASYNC,
8494 ConstructServerPushPromisePacket(
8495 5, client_stream_0, push_stream_1, false,
8496 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8497 &server_header_offset, &server_maker_));
8498 mock_quic_data.AddWrite(
8499 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238500 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8501 DEFAULT_PRIORITY, &header_stream_offset));
8502
8503 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438504 mock_quic_data.AddRead(
8505 ASYNC, ConstructServerResponseHeadersPacket(
8506 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8507 &server_header_offset));
8508 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8509 mock_quic_data.AddRead(
8510 ASYNC, ConstructServerResponseHeadersPacket(
8511 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8512 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238513
8514 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8515 // priority updates to match the request's priority. Client sends PRIORITY
8516 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438517 mock_quic_data.AddWrite(
8518 SYNCHRONOUS,
8519 ConstructClientAckAndPriorityFramesPacket(
8520 9, false, 7, 7, 1,
8521 {{push_stream_1, client_stream_2,
8522 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8523 {push_stream_0, client_stream_0,
8524 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8525 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238526
8527 // Server sends data for the three requests and the two push promises.
Renjief49758b2019-01-11 23:32:418528 quic::QuicString header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438529 mock_quic_data.AddRead(
8530 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418531 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438532 mock_quic_data.AddRead(
8533 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418534 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438535 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8536 mock_quic_data.AddRead(
8537 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418538 header + "hello 2!"));
8539 quic::QuicString header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438540 mock_quic_data.AddRead(
8541 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418542 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438543 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8544 mock_quic_data.AddRead(
8545 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418546 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238547
Yixin Wang385652a2018-02-16 02:37:238548 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8549 mock_quic_data.AddRead(ASYNC, 0); // EOF
8550 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8551
8552 // The non-alternate protocol job needs to hang in order to guarantee that
8553 // the alternate-protocol job will "win".
8554 AddHangingNonAlternateProtocolSocketData();
8555
8556 CreateSession();
8557
8558 request_.url = GURL("https://mail.example.org/0.jpg");
8559 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8560 TestCompletionCallback callback_0;
8561 EXPECT_EQ(ERR_IO_PENDING,
8562 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8563 base::RunLoop().RunUntilIdle();
8564
8565 request_.url = GURL("https://mail.example.org/1.jpg");
8566 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8567 TestCompletionCallback callback_1;
8568 EXPECT_EQ(ERR_IO_PENDING,
8569 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8570 base::RunLoop().RunUntilIdle();
8571
8572 request_.url = GURL("https://mail.example.org/2.jpg");
8573 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8574 TestCompletionCallback callback_2;
8575 EXPECT_EQ(ERR_IO_PENDING,
8576 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8577 base::RunLoop().RunUntilIdle();
8578
8579 // Client makes request that matches resource pushed in |pushed_stream_0|.
8580 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8581 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8582 TestCompletionCallback callback_3;
8583 EXPECT_EQ(ERR_IO_PENDING,
8584 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8585 base::RunLoop().RunUntilIdle();
8586
8587 EXPECT_TRUE(callback_0.have_result());
8588 EXPECT_EQ(OK, callback_0.WaitForResult());
8589 EXPECT_TRUE(callback_1.have_result());
8590 EXPECT_EQ(OK, callback_1.WaitForResult());
8591 EXPECT_TRUE(callback_2.have_result());
8592 EXPECT_EQ(OK, callback_2.WaitForResult());
8593
8594 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8595 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8596 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8597 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8598
8599 mock_quic_data.Resume();
8600 base::RunLoop().RunUntilIdle();
8601 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8602 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8603}
8604
[email protected]61a527782013-02-21 03:58:008605} // namespace test
8606} // namespace net