blob: 334b38a39864c2316c5701126c72860129bc5f20 [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"
mgershaf9a9232017-04-13 20:19:0322#include "net/base/mock_network_change_notifier.h"
[email protected]61a527782013-02-21 03:58:0023#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0424#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2025#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1126#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1227#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5328#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0029#include "net/http/http_auth_handler_factory.h"
30#include "net/http/http_network_session.h"
31#include "net/http/http_network_transaction.h"
32#include "net/http/http_server_properties_impl.h"
33#include "net/http/http_stream.h"
34#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1935#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1136#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0037#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5138#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4639#include "net/log/test_net_log_entry.h"
40#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4041#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0342#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4043#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0844#include "net/quic/crypto/proof_verifier_chromium.h"
45#include "net/quic/mock_crypto_client_stream_factory.h"
46#include "net/quic/mock_quic_data.h"
47#include "net/quic/quic_chromium_alarm_factory.h"
48#include "net/quic/quic_http_stream.h"
49#include "net/quic/quic_http_utils.h"
50#include "net/quic/quic_stream_factory_peer.h"
51#include "net/quic/quic_test_packet_maker.h"
52#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0053#include "net/socket/client_socket_factory.h"
54#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2155#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2856#include "net/socket/socket_performance_watcher.h"
57#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0058#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5859#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5760#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2961#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0162#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4363#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0164#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1665#include "net/third_party/quic/core/crypto/quic_decrypter.h"
66#include "net/third_party/quic/core/crypto/quic_encrypter.h"
67#include "net/third_party/quic/core/quic_framer.h"
Ryan Hamilton47cf9d12018-10-17 04:33:0968#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1669#include "net/third_party/quic/platform/api/quic_str_cat.h"
70#include "net/third_party/quic/platform/api/quic_string_piece.h"
71#include "net/third_party/quic/platform/api/quic_test.h"
72#include "net/third_party/quic/test_tools/crypto_test_utils.h"
73#include "net/third_party/quic/test_tools/mock_clock.h"
74#include "net/third_party/quic/test_tools/mock_random.h"
75#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
76#include "net/third_party/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1477#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
78#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2979#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
allada71b2efb2016-09-09 04:57:4880#include "net/url_request/url_request.h"
81#include "net/url_request/url_request_job_factory_impl.h"
82#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0183#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0084#include "testing/gtest/include/gtest/gtest.h"
85#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4686#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0087
Reilly Grant89a7e512018-01-20 01:57:1688using ::testing::ElementsAre;
89using ::testing::Key;
90
bnc508835902015-05-12 20:10:2991namespace net {
92namespace test {
[email protected]61a527782013-02-21 03:58:0093
94namespace {
95
bnc359ed2a2016-04-29 20:43:4596enum DestinationType {
97 // In pooling tests with two requests for different origins to the same
98 // destination, the destination should be
99 SAME_AS_FIRST, // the same as the first origin,
100 SAME_AS_SECOND, // the same as the second origin, or
101 DIFFERENT, // different from both.
102};
103
rchf114d982015-10-21 01:34:56104static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52105 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12106static const char kQuicAlternativeServiceWithProbabilityHeader[] =
107 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56108static const char kQuicAlternativeServiceDifferentPortHeader[] =
109 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20110
rch9ae5b3b2016-02-11 00:36:29111const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45112const char kDifferentHostname[] = "different.example.com";
113
114// Run QuicNetworkTransactionWithDestinationTest instances with all value
115// combinations of version and destination_type.
116struct PoolingTestParams {
117 friend std::ostream& operator<<(std::ostream& os,
118 const PoolingTestParams& p) {
119 os << "{ version: " << QuicVersionToString(p.version)
120 << ", destination_type: ";
121 switch (p.destination_type) {
122 case SAME_AS_FIRST:
123 os << "SAME_AS_FIRST";
124 break;
125 case SAME_AS_SECOND:
126 os << "SAME_AS_SECOND";
127 break;
128 case DIFFERENT:
129 os << "DIFFERENT";
130 break;
131 }
Yixin Wang079ad542018-01-11 04:06:05132 os << ", client_headers_include_h2_stream_dependency: "
133 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45134 os << " }";
135 return os;
136 }
137
Ryan Hamilton8d9ee76e2018-05-29 23:52:52138 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45139 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05140 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45141};
142
zhongyie537a002017-06-27 16:48:21143std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52144 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21145 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52146 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21147 if (!result.empty())
148 result.append(",");
Raul Tambre8c1981dd2019-02-08 02:22:26149 result.append(base::NumberToString(version));
zhongyie537a002017-06-27 16:48:21150 }
151 return result;
152}
153
bnc359ed2a2016-04-29 20:43:45154std::vector<PoolingTestParams> GetPoolingTestParams() {
155 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52156 quic::QuicTransportVersionVector all_supported_versions =
157 quic::AllSupportedTransportVersions();
158 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05159 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
160 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
161 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
162 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
163 params.push_back(PoolingTestParams{version, DIFFERENT, false});
164 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45165 }
166 return params;
167}
bncb07c05532015-05-14 19:07:20168
[email protected]61a527782013-02-21 03:58:00169} // namespace
170
ryansturm49a8cb12016-06-15 16:51:09171class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12172 public:
ryansturm49a8cb12016-06-15 16:51:09173 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12174
ryansturm49a8cb12016-06-15 16:51:09175 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12176
ryansturm49a8cb12016-06-15 16:51:09177 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
178 HttpRequestHeaders* request_headers) {
179 if (!proxy_info.is_http() && !proxy_info.is_https() &&
180 !proxy_info.is_quic()) {
181 return;
182 }
183 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12184 }
185
186 private:
ryansturm49a8cb12016-06-15 16:51:09187 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12188};
189
tbansal0f56a39a2016-04-07 22:03:38190class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40191 public:
tbansal180587c2017-02-16 15:13:23192 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
193 bool* rtt_notification_received)
194 : should_notify_updated_rtt_(should_notify_updated_rtt),
195 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38196 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40197
tbansal180587c2017-02-16 15:13:23198 bool ShouldNotifyUpdatedRTT() const override {
199 return *should_notify_updated_rtt_;
200 }
tbansalfdf5665b2015-09-21 22:46:40201
tbansal0f56a39a2016-04-07 22:03:38202 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
203 *rtt_notification_received_ = true;
204 }
205
206 void OnConnectionChanged() override {}
207
208 private:
tbansal180587c2017-02-16 15:13:23209 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38210 bool* rtt_notification_received_;
211
212 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
213};
214
215class TestSocketPerformanceWatcherFactory
216 : public SocketPerformanceWatcherFactory {
217 public:
218 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23219 : watcher_count_(0u),
220 should_notify_updated_rtt_(true),
221 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38222 ~TestSocketPerformanceWatcherFactory() override {}
223
224 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42225 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41226 const Protocol protocol,
227 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51228 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38229 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51230 }
231 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42232 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23233 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
234 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40235 }
236
tbansalc8a94ea2015-11-02 23:58:51237 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40238
tbansalc8a94ea2015-11-02 23:58:51239 bool rtt_notification_received() const { return rtt_notification_received_; }
240
tbansal180587c2017-02-16 15:13:23241 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
242 should_notify_updated_rtt_ = should_notify_updated_rtt;
243 }
244
tbansalc8a94ea2015-11-02 23:58:51245 private:
tbansal0f56a39a2016-04-07 22:03:38246 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23247 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51248 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38249
250 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51251};
252
Ryan Hamilton8d9ee76e2018-05-29 23:52:52253class QuicNetworkTransactionTest
254 : public PlatformTest,
255 public ::testing::WithParamInterface<
256 std::tuple<quic::QuicTransportVersion, bool>>,
257 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00258 protected:
[email protected]1c04f9522013-02-21 20:32:43259 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05260 : version_(std::get<0>(GetParam())),
261 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52262 supported_versions_(quic::test::SupportedTransportVersions(version_)),
David Schinazic8281052019-01-24 06:14:17263 random_generator_(0),
264 client_maker_(
265 version_,
266 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
267 &clock_,
268 kDefaultServerHostName,
269 quic::Perspective::IS_CLIENT,
270 client_headers_include_h2_stream_dependency_),
271 server_maker_(
272 version_,
273 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
274 &clock_,
275 kDefaultServerHostName,
276 quic::Perspective::IS_SERVER,
277 false),
rtenneti052774e2015-11-24 21:00:12278 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43279 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59280 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
[email protected]1c04f9522013-02-21 20:32:43281 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30282 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
rchf114d982015-10-21 01:34:56283 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19284 request_.method = "GET";
rchf114d982015-10-21 01:34:56285 std::string url("https://");
bncb07c05532015-05-14 19:07:20286 url.append(kDefaultServerHostName);
287 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19288 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10289 request_.traffic_annotation =
290 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52291 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56292
293 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29294 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56295 verify_details_.cert_verify_result.verified_cert = cert;
296 verify_details_.cert_verify_result.is_issued_by_known_root = true;
297 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43298 }
[email protected]61a527782013-02-21 03:58:00299
dcheng67be2b1f2014-10-27 21:47:29300 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00301 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55302 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00303 }
304
dcheng67be2b1f2014-10-27 21:47:29305 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00306 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
307 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55308 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00309 PlatformTest::TearDown();
310 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55311 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40312 session_.reset();
[email protected]61a527782013-02-21 03:58:00313 }
314
Ryan Hamilton8d9ee76e2018-05-29 23:52:52315 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23316 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03317 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52318 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30319 }
320
Ryan Hamilton8d9ee76e2018-05-29 23:52:52321 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23322 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03323 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52324 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58325 }
326
Ryan Hamilton8d9ee76e2018-05-29 23:52:52327 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23328 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52329 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20330 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58331 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20332 }
333
Ryan Hamilton8d9ee76e2018-05-29 23:52:52334 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23335 uint64_t packet_number,
336 uint64_t largest_received,
337 uint64_t smallest_received,
338 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37339 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49340 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37341 }
342
Ryan Hamilton8d9ee76e2018-05-29 23:52:52343 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23344 uint64_t packet_number,
345 uint64_t largest_received,
346 uint64_t smallest_received,
347 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52348 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23349 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49350 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23351 ack_delay_time);
352 }
353
Ryan Hamilton8d9ee76e2018-05-29 23:52:52354 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23355 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52356 quic::QuicStreamId stream_id,
357 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23358 uint64_t largest_received,
359 uint64_t smallest_received,
360 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58361 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49362 num, false, stream_id, error_code, largest_received, smallest_received,
363 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20364 }
365
Ryan Hamilton8d9ee76e2018-05-29 23:52:52366 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23367 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52368 quic::QuicStreamId stream_id,
369 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56370 size_t bytes_written) {
371 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18372 bytes_written,
373 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56374 }
375
Ryan Hamilton8d9ee76e2018-05-29 23:52:52376 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23377 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
378 uint64_t largest_received,
379 uint64_t smallest_received,
380 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58381 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49382 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20383 }
[email protected]61a527782013-02-21 03:58:00384
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58386 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23387 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52388 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23389 uint64_t largest_received,
390 uint64_t smallest_received,
391 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52392 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50393 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58394 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12395 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49396 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12397 }
398
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23400 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12401 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52402 quic::QuicStreamId stream_id,
403 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58404 return server_maker_.MakeRstPacket(num, include_version, stream_id,
405 error_code);
zhongyica364fbb2015-12-12 03:39:12406 }
407
Ryan Hamilton8d9ee76e2018-05-29 23:52:52408 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23409 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36411 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37412 }
413
Ryan Hamilton8d9ee76e2018-05-29 23:52:52414 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23415 uint64_t packet_number,
416 uint64_t largest_received,
417 uint64_t smallest_received,
418 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37419 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49420 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37421 }
422
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23424 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57425 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 quic::QuicStreamId id,
427 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57428 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57430 return client_maker_.MakePriorityPacket(
431 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23432 ConvertRequestPriorityToQuicPriority(request_priority), offset);
433 }
434
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25436 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23437 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23438 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23439 uint64_t largest_received,
440 uint64_t smallest_received,
441 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25442 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
443 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52444 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25445 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23446 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25447 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57448 }
449
zhongyi32569c62016-01-08 02:54:30450 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13451 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
452 const std::string& scheme,
453 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58454 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30455 }
456
457 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13458 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
459 const std::string& scheme,
460 const std::string& path,
461 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50462 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00463 }
464
Ryan Hamilton0239aac2018-05-19 00:03:13465 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56466 return client_maker_.ConnectRequestHeaders(host_port);
467 }
468
Ryan Hamilton0239aac2018-05-19 00:03:13469 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58470 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00471 }
472
zhongyi32569c62016-01-08 02:54:30473 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13474 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
475 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58476 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30477 }
478
Ryan Hamilton8d9ee76e2018-05-29 23:52:52479 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23480 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52481 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05482 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00483 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52484 quic::QuicStreamOffset offset,
485 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58486 return server_maker_.MakeDataPacket(
487 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00488 }
489
Ryan Hamilton8d9ee76e2018-05-29 23:52:52490 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23491 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36493 bool should_include_version,
494 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52495 quic::QuicStreamOffset offset,
496 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36497 return client_maker_.MakeDataPacket(
498 packet_number, stream_id, should_include_version, fin, offset, data);
499 }
500
Renjied172e812019-01-16 05:12:35501 std::unique_ptr<quic::QuicEncryptedPacket>
502 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23503 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35504 quic::QuicStreamId stream_id,
505 bool should_include_version,
506 bool fin,
507 quic::QuicStreamOffset offset,
508 const std::vector<std::string> data_writes) {
509 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
510 should_include_version,
511 fin, offset, data_writes);
512 }
513
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23515 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56516 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23518 uint64_t largest_received,
519 uint64_t smallest_received,
520 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56521 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 quic::QuicStreamOffset offset,
523 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56524 return client_maker_.MakeAckAndDataPacket(
525 packet_number, include_version, stream_id, largest_received,
526 smallest_received, least_unacked, fin, offset, data);
527 }
528
Renjied172e812019-01-16 05:12:35529 std::unique_ptr<quic::QuicEncryptedPacket>
530 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23531 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35532 bool include_version,
533 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23534 uint64_t largest_received,
535 uint64_t smallest_received,
536 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35537 bool fin,
538 quic::QuicStreamOffset offset,
539 const std::vector<std::string> data_writes) {
540 return client_maker_.MakeAckAndMultipleDataFramesPacket(
541 packet_number, include_version, stream_id, largest_received,
542 smallest_received, least_unacked, fin, offset, data_writes);
543 }
544
Ryan Hamilton8d9ee76e2018-05-29 23:52:52545 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23546 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36548 bool should_include_version,
549 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 quic::QuicStreamOffset* offset,
551 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36552 return client_maker_.MakeForceHolDataPacket(
553 packet_number, stream_id, should_include_version, fin, offset, data);
554 }
555
Ryan Hamilton8d9ee76e2018-05-29 23:52:52556 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23557 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52558 quic::QuicStreamId stream_id,
559 bool should_include_version,
560 bool fin,
561 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56562 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
563 should_include_version, fin,
564 std::move(headers), nullptr);
565 }
566
Ryan Hamilton8d9ee76e2018-05-29 23:52:52567 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23568 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52569 quic::QuicStreamId stream_id,
570 bool should_include_version,
571 bool fin,
572 spdy::SpdyHeaderBlock headers,
573 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48574 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
575 should_include_version, fin,
576 std::move(headers), 0, offset);
577 }
578
Ryan Hamilton8d9ee76e2018-05-29 23:52:52579 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23580 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52581 quic::QuicStreamId stream_id,
582 bool should_include_version,
583 bool fin,
584 spdy::SpdyHeaderBlock headers,
585 quic::QuicStreamId parent_stream_id,
586 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56587 return ConstructClientRequestHeadersPacket(
588 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48589 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30590 }
591
Ryan Hamilton8d9ee76e2018-05-29 23:52:52592 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23593 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52594 quic::QuicStreamId stream_id,
595 bool should_include_version,
596 bool fin,
597 RequestPriority request_priority,
598 spdy::SpdyHeaderBlock headers,
599 quic::QuicStreamId parent_stream_id,
600 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13601 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56602 ConvertRequestPriorityToQuicPriority(request_priority);
603 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
604 packet_number, stream_id, should_include_version, fin, priority,
605 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00606 }
607
Ryan Hamilton8d9ee76e2018-05-29 23:52:52608 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25609 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23610 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52611 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25612 bool should_include_version,
613 bool fin,
614 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13615 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52616 quic::QuicStreamId parent_stream_id,
617 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25618 size_t* spdy_headers_frame_length,
619 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13620 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25621 ConvertRequestPriorityToQuicPriority(request_priority);
622 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
623 packet_number, stream_id, should_include_version, fin, priority,
624 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
625 data_writes);
626 }
627
Ryan Hamilton8d9ee76e2018-05-29 23:52:52628 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23629 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52630 quic::QuicStreamId stream_id,
631 bool should_include_version,
632 bool fin,
633 const std::vector<std::string>& data,
634 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27635 return client_maker_.MakeMultipleDataFramesPacket(
636 packet_number, stream_id, should_include_version, fin, offset, data);
637 }
638
Ryan Hamilton8d9ee76e2018-05-29 23:52:52639 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23640 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52641 quic::QuicStreamId stream_id,
642 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13643 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13644 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52645 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13646 QuicTestPacketMaker* maker) {
647 return maker->MakePushPromisePacket(
648 packet_number, stream_id, promised_stream_id, should_include_version,
649 false, std::move(headers), nullptr, offset);
650 }
651
Ryan Hamilton8d9ee76e2018-05-29 23:52:52652 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23653 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52654 quic::QuicStreamId stream_id,
655 bool should_include_version,
656 bool fin,
657 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27658 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
659 should_include_version, fin,
660 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30661 }
662
Ryan Hamilton8d9ee76e2018-05-29 23:52:52663 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23664 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52665 quic::QuicStreamId stream_id,
666 bool should_include_version,
667 bool fin,
668 spdy::SpdyHeaderBlock headers,
669 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58670 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25671 packet_number, stream_id, should_include_version, fin,
672 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30673 }
674
Renjief49758b2019-01-11 23:32:41675 quic::QuicString ConstructDataHeader(size_t body_len) {
676 if (version_ != quic::QUIC_VERSION_99) {
677 return "";
678 }
679 quic::HttpEncoder encoder;
680 std::unique_ptr<char[]> buffer;
681 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
682 return quic::QuicString(buffer.get(), header_length);
683 }
684
Ryan Hamilton8d9ee76e2018-05-29 23:52:52685 void CreateSession(
686 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41687 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21688 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05689 session_params_.quic_headers_include_h2_stream_dependency =
690 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00691
mmenke6ddfbea2017-05-31 21:48:41692 session_context_.quic_clock = &clock_;
693 session_context_.quic_random = &random_generator_;
694 session_context_.client_socket_factory = &socket_factory_;
695 session_context_.quic_crypto_client_stream_factory =
696 &crypto_client_stream_factory_;
697 session_context_.host_resolver = &host_resolver_;
698 session_context_.cert_verifier = &cert_verifier_;
699 session_context_.transport_security_state = &transport_security_state_;
700 session_context_.cert_transparency_verifier =
701 cert_transparency_verifier_.get();
702 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
703 session_context_.socket_performance_watcher_factory =
704 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59705 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41706 session_context_.ssl_config_service = ssl_config_service_.get();
707 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
708 session_context_.http_server_properties = &http_server_properties_;
709 session_context_.net_log = net_log_.bound().net_log();
710
711 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12712 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56713 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
714 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00715 }
716
zhongyi86838d52017-06-30 01:19:44717 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21718
bnc691fda62016-08-12 00:43:16719 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19720 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42721 ASSERT_TRUE(response != nullptr);
722 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19723 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
724 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52725 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44726 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19727 response->connection_info);
728 }
729
bnc691fda62016-08-12 00:43:16730 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41731 const HttpResponseInfo* response = trans->GetResponseInfo();
732 ASSERT_TRUE(response != nullptr);
733 EXPECT_EQ(port, response->socket_address.port());
734 }
735
bnc691fda62016-08-12 00:43:16736 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19737 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42738 ASSERT_TRUE(response != nullptr);
739 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
741 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52742 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52743 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19744 response->connection_info);
745 }
746
Yixin Wang46a273ec302018-01-23 17:59:56747 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
748 const HttpResponseInfo* response = trans->GetResponseInfo();
749 ASSERT_TRUE(response != nullptr);
750 ASSERT_TRUE(response->headers.get() != nullptr);
751 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
752 EXPECT_TRUE(response->was_fetched_via_spdy);
753 EXPECT_TRUE(response->was_alpn_negotiated);
754 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
755 response->connection_info);
756 }
757
bnc691fda62016-08-12 00:43:16758 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19759 const std::string& expected) {
760 std::string response_data;
bnc691fda62016-08-12 00:43:16761 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19762 EXPECT_EQ(expected, response_data);
763 }
764
bnc691fda62016-08-12 00:43:16765 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19766 TestCompletionCallback callback;
767 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
769 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19770 }
771
772 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
774 RunTransaction(&trans);
775 CheckWasHttpResponse(&trans);
776 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19777 }
778
tbansalc3308d72016-08-27 10:25:04779 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
780 bool used_proxy,
781 uint16_t port) {
782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
783 HeadersHandler headers_handler;
784 trans.SetBeforeHeadersSentCallback(
785 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
786 base::Unretained(&headers_handler)));
787 RunTransaction(&trans);
788 CheckWasHttpResponse(&trans);
789 CheckResponsePort(&trans, port);
790 CheckResponseData(&trans, expected);
791 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47792 if (used_proxy) {
793 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
794 } else {
795 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
796 }
tbansalc3308d72016-08-27 10:25:04797 }
798
[email protected]aa9b14d2013-05-10 23:45:19799 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56800 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12801 }
802
bnc62a44f022015-04-02 15:59:41803 void SendRequestAndExpectQuicResponseFromProxyOnPort(
804 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46805 uint16_t port) {
bnc62a44f022015-04-02 15:59:41806 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19807 }
808
809 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27810 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19811 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46812 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21813 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12814 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21815 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44816 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19817 }
818
rchbe69cb902016-02-11 01:10:48819 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27820 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48821 const HostPortPair& alternative) {
822 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46823 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21824 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48825 alternative.port());
826 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21827 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44828 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48829 }
830
[email protected]aa9b14d2013-05-10 23:45:19831 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46832 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34833 const AlternativeServiceInfoVector alternative_service_info_vector =
834 http_server_properties_.GetAlternativeServiceInfos(server);
835 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07836 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54837 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19838 }
839
[email protected]4d590c9c2014-05-02 05:14:33840 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46841 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34842 const AlternativeServiceInfoVector alternative_service_info_vector =
843 http_server_properties_.GetAlternativeServiceInfos(server);
844 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54845 EXPECT_EQ(
846 kProtoQUIC,
847 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23848 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54849 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33850 }
851
[email protected]aa9b14d2013-05-10 23:45:19852 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42853 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30854 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30855 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30856 hanging_data->set_connect_data(hanging_connect);
857 hanging_data_.push_back(std::move(hanging_data));
858 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56859 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19860 }
861
Zhongyi Shia6b68d112018-09-24 07:49:03862 void SetUpTestForRetryConnectionOnAlternateNetwork() {
863 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
864 session_params_.quic_migrate_sessions_early_v2 = true;
865 session_params_.quic_retry_on_alternate_network_before_handshake = true;
866 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
867 MockNetworkChangeNotifier* mock_ncn =
868 scoped_mock_change_notifier_->mock_network_change_notifier();
869 mock_ncn->ForceNetworkHandlesSupported();
870 mock_ncn->SetConnectedNetworksList(
871 {kDefaultNetworkForTests, kNewNetworkForTests});
872 }
873
tbansalc3308d72016-08-27 10:25:04874 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
875 // alternative proxy. Verifies that if the alternative proxy job returns
876 // |error_code|, the request is fetched successfully by the main job.
877 void TestAlternativeProxy(int error_code) {
878 // Use a non-cryptographic scheme for the request URL since this request
879 // will be fetched via proxy with QUIC as the alternative service.
880 request_.url = GURL("http://example.org/");
881 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27882 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04883 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27884 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04885 };
886
Ryan Sleevib8d7ea02018-05-07 20:01:01887 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04888 socket_factory_.AddSocketDataProvider(&quic_data);
889
890 // Main job succeeds and the alternative job fails.
891 // Add data for two requests that will be read by the main job.
892 MockRead http_reads_1[] = {
893 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
894 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
895 MockRead(ASYNC, OK)};
896
897 MockRead http_reads_2[] = {
898 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
900 MockRead(ASYNC, OK)};
901
Ryan Sleevib8d7ea02018-05-07 20:01:01902 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
903 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04904 socket_factory_.AddSocketDataProvider(&http_data_1);
905 socket_factory_.AddSocketDataProvider(&http_data_2);
906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
907 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
908
909 TestProxyDelegate test_proxy_delegate;
910 // Proxy URL is different from the request URL.
911 test_proxy_delegate.set_alternative_proxy_server(
912 ProxyServer::FromPacString("QUIC myproxy.org:443"));
913
Lily Houghton8c2f97d2018-01-22 05:06:59914 proxy_resolution_service_ =
915 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49916 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52917 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04918
919 CreateSession();
920 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
921
922 // The first request should be fetched via the HTTPS proxy.
923 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
924
Reilly Grant89a7e512018-01-20 01:57:16925 // Since the main job succeeded only the alternative proxy server should be
926 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59927 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16928 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04929
930 // Verify that the second request completes successfully, and the
931 // alternative proxy server job is not started.
932 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
933 }
934
Fan Yang32c5a112018-12-10 20:06:33935 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
936 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36937 }
938
Fan Yang32c5a112018-12-10 20:06:33939 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
940 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36941 }
942
Bence Béky230ac612017-08-30 19:17:08943 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49944 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08945 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49946 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08947 }
948
Ryan Hamilton8d9ee76e2018-05-29 23:52:52949 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05950 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52951 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01952 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52953 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17954 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58955 QuicTestPacketMaker client_maker_;
956 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42957 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00958 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56959 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05960 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43961 MockHostResolver host_resolver_;
962 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11963 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42964 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23965 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38966 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07967 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59968 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42969 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07970 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41971 HttpNetworkSession::Params session_params_;
972 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19973 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51974 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42975 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56976 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03977 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12978
979 private:
980 void SendRequestAndExpectQuicResponseMaybeFromProxy(
981 const std::string& expected,
bnc62a44f022015-04-02 15:59:41982 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46983 uint16_t port) {
bnc691fda62016-08-12 00:43:16984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09985 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16986 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09987 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
988 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16989 RunTransaction(&trans);
990 CheckWasQuicResponse(&trans);
991 CheckResponsePort(&trans, port);
992 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09993 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47994 if (used_proxy) {
995 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
996 } else {
997 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
998 }
tbansal7cec3812015-02-05 21:25:12999 }
[email protected]61a527782013-02-21 03:58:001000};
1001
Victor Costane635086f2019-01-27 05:20:301002INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231003 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051004 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521005 ::testing::Combine(
1006 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1007 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201008
Ryan Hamiltona64a5bcf2017-11-30 07:35:281009TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481010 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281011 base::HistogramTester histograms;
1012 session_params_.origins_to_force_quic_on.insert(
1013 HostPortPair::FromString("mail.example.org:443"));
1014 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271015 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281016
1017 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521018 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281019 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431020 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281021 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1022 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1023 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1024
1025 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1026
1027 CreateSession();
1028
1029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1030 TestCompletionCallback callback;
1031 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1033 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1034
1035 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1036 -ERR_INTERNET_DISCONNECTED, 1);
1037 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1038 -ERR_INTERNET_DISCONNECTED, 1);
1039}
1040
1041TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481042 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281043 base::HistogramTester histograms;
1044 session_params_.origins_to_force_quic_on.insert(
1045 HostPortPair::FromString("mail.example.org:443"));
1046 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271047 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281048
1049 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521050 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281051 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431052 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281053 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1054 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1055 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1056
1057 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1058
1059 CreateSession();
1060
1061 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1062 TestCompletionCallback callback;
1063 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1065 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1066
1067 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1068 -ERR_INTERNET_DISCONNECTED, 1);
1069 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1070 -ERR_INTERNET_DISCONNECTED, 1);
1071}
1072
tbansal180587c2017-02-16 15:13:231073TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411074 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231075 HostPortPair::FromString("mail.example.org:443"));
1076
1077 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521078 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361079 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431080 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1081 mock_quic_data.AddWrite(
1082 SYNCHRONOUS,
1083 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331084 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431085 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431086 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331087 ASYNC, ConstructServerResponseHeadersPacket(
1088 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1089 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411090 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331091 mock_quic_data.AddRead(
1092 ASYNC, ConstructServerDataPacket(
1093 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411094 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431095 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231096 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1097
1098 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1099
1100 CreateSession();
1101 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1102
1103 EXPECT_FALSE(
1104 test_socket_performance_watcher_factory_.rtt_notification_received());
1105 SendRequestAndExpectQuicResponse("hello!");
1106 EXPECT_TRUE(
1107 test_socket_performance_watcher_factory_.rtt_notification_received());
1108}
1109
1110TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411111 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231112 HostPortPair::FromString("mail.example.org:443"));
1113
1114 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521115 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361116 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431117 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1118 mock_quic_data.AddWrite(
1119 SYNCHRONOUS,
1120 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331121 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431122 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431123 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331124 ASYNC, ConstructServerResponseHeadersPacket(
1125 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1126 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411127 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331128 mock_quic_data.AddRead(
1129 ASYNC, ConstructServerDataPacket(
1130 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411131 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431132 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231133 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1134
1135 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1136
1137 CreateSession();
1138 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1139
1140 EXPECT_FALSE(
1141 test_socket_performance_watcher_factory_.rtt_notification_received());
1142 SendRequestAndExpectQuicResponse("hello!");
1143 EXPECT_FALSE(
1144 test_socket_performance_watcher_factory_.rtt_notification_received());
1145}
1146
[email protected]1e960032013-12-20 19:00:201147TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411148 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571149 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471150
[email protected]1e960032013-12-20 19:00:201151 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521152 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361153 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431154 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1155 mock_quic_data.AddWrite(
1156 SYNCHRONOUS,
1157 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331158 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431159 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431160 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331161 ASYNC, ConstructServerResponseHeadersPacket(
1162 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1163 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411164 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331165 mock_quic_data.AddRead(
1166 ASYNC, ConstructServerDataPacket(
1167 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411168 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431169 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591170 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471171
rcha5399e02015-04-21 19:32:041172 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471173
[email protected]4dca587c2013-03-07 16:54:471174 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471175
[email protected]aa9b14d2013-05-10 23:45:191176 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471177
[email protected]98b20ce2013-05-10 05:55:261178 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461179 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191180 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261181 EXPECT_LT(0u, entries.size());
1182
1183 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291184 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001185 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1186 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261187 EXPECT_LT(0, pos);
1188
rchfd527212015-08-25 00:41:261189 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291190 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261191 entries, 0,
mikecirone8b85c432016-09-08 19:11:001192 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1193 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261194 EXPECT_LT(0, pos);
1195
Eric Romanaefc98c2018-12-18 21:38:011196 int packet_number;
1197 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1198 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261199
rchfd527212015-08-25 00:41:261200 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1201 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001202 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1203 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261204 EXPECT_LT(0, pos);
1205
[email protected]98b20ce2013-05-10 05:55:261206 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291207 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001208 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1209 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261210 EXPECT_LT(0, pos);
1211
1212 int log_stream_id;
1213 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381214 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1215 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471216}
1217
rchbd089ab2017-05-26 23:05:041218TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411219 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041220 HostPortPair::FromString("mail.example.org:443"));
1221
1222 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521223 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041224 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431225 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1226 mock_quic_data.AddWrite(
1227 SYNCHRONOUS,
1228 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331229 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431230 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131231 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041232 response_headers["key1"] = std::string(30000, 'A');
1233 response_headers["key2"] = std::string(30000, 'A');
1234 response_headers["key3"] = std::string(30000, 'A');
1235 response_headers["key4"] = std::string(30000, 'A');
1236 response_headers["key5"] = std::string(30000, 'A');
1237 response_headers["key6"] = std::string(30000, 'A');
1238 response_headers["key7"] = std::string(30000, 'A');
1239 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331240 spdy::SpdyHeadersIR headers_frame(
1241 GetNthClientInitiatedBidirectionalStreamId(0),
1242 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131243 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1244 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041245 response_framer.SerializeFrame(headers_frame);
1246
Fan Yangac867502019-01-28 21:10:231247 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041248 size_t chunk_size = 1200;
1249 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1250 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431251 mock_quic_data.AddRead(
1252 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091253 packet_number++,
1254 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521255 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041256 }
1257
Renjief49758b2019-01-11 23:32:411258 quic::QuicString header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041259 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331260 ASYNC, ConstructServerDataPacket(
1261 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411262 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041263 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431264 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1265 mock_quic_data.AddWrite(ASYNC,
1266 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041267
1268 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1269
1270 CreateSession();
1271
1272 SendRequestAndExpectQuicResponse("hello!");
1273}
1274
1275TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481276 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411277 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041278 HostPortPair::FromString("mail.example.org:443"));
1279
1280 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521281 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041282 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431283 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1284 mock_quic_data.AddWrite(
1285 SYNCHRONOUS,
1286 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331287 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431288 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131289 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041290 response_headers["key1"] = std::string(30000, 'A');
1291 response_headers["key2"] = std::string(30000, 'A');
1292 response_headers["key3"] = std::string(30000, 'A');
1293 response_headers["key4"] = std::string(30000, 'A');
1294 response_headers["key5"] = std::string(30000, 'A');
1295 response_headers["key6"] = std::string(30000, 'A');
1296 response_headers["key7"] = std::string(30000, 'A');
1297 response_headers["key8"] = std::string(30000, 'A');
1298 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331299 spdy::SpdyHeadersIR headers_frame(
1300 GetNthClientInitiatedBidirectionalStreamId(0),
1301 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131302 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1303 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041304 response_framer.SerializeFrame(headers_frame);
1305
Fan Yangac867502019-01-28 21:10:231306 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041307 size_t chunk_size = 1200;
1308 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1309 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431310 mock_quic_data.AddRead(
1311 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091312 packet_number++,
1313 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521314 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041315 }
1316
Renjief49758b2019-01-11 23:32:411317 quic::QuicString header = ConstructDataHeader(6);
1318
rchbd089ab2017-05-26 23:05:041319 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331320 ASYNC, ConstructServerDataPacket(
1321 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411322 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041323 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431324 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1325 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331326 ASYNC, ConstructClientAckAndRstPacket(
1327 4, GetNthClientInitiatedBidirectionalStreamId(0),
1328 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041329
1330 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1331
1332 CreateSession();
1333
1334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1335 TestCompletionCallback callback;
1336 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1338 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1339}
1340
rcha2bd44b2016-07-02 00:42:551341TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411342 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551343
Ryan Hamilton9835e662018-08-02 05:36:271344 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551345
1346 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521347 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361348 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431349 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1350 mock_quic_data.AddWrite(
1351 SYNCHRONOUS,
1352 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331353 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431354 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431355 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331356 ASYNC, ConstructServerResponseHeadersPacket(
1357 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1358 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411359 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331360 mock_quic_data.AddRead(
1361 ASYNC, ConstructServerDataPacket(
1362 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411363 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431364 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551365 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1366
1367 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1368
1369 CreateSession();
1370
1371 SendRequestAndExpectQuicResponse("hello!");
1372 EXPECT_TRUE(
1373 test_socket_performance_watcher_factory_.rtt_notification_received());
1374}
1375
[email protected]cf3e3cd62014-02-05 16:16:161376TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411377 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591378 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491379 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161380
[email protected]cf3e3cd62014-02-05 16:16:161381 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521382 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361383 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431384 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1385 mock_quic_data.AddWrite(
1386 SYNCHRONOUS,
1387 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331388 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431389 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431390 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331391 ASYNC, ConstructServerResponseHeadersPacket(
1392 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1393 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411394 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331395 mock_quic_data.AddRead(
1396 ASYNC, ConstructServerDataPacket(
1397 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411398 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431399 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501400 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591401 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161402
rcha5399e02015-04-21 19:32:041403 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161404
tbansal0f56a39a2016-04-07 22:03:381405 EXPECT_FALSE(
1406 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161407 // There is no need to set up an alternate protocol job, because
1408 // no attempt will be made to speak to the proxy over TCP.
1409
rch9ae5b3b2016-02-11 00:36:291410 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161411 CreateSession();
1412
bnc62a44f022015-04-02 15:59:411413 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381414 EXPECT_TRUE(
1415 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161416}
1417
bnc313ba9c2015-06-11 15:42:311418// Regression test for https://crbug.com/492458. Test that for an HTTP
1419// connection through a QUIC proxy, the certificate exhibited by the proxy is
1420// checked against the proxy hostname, not the origin hostname.
1421TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291422 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311423 const std::string proxy_host = "www.example.org";
1424
mmenke6ddfbea2017-05-31 21:48:411425 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591426 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491427 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311428
alyssar2adf3ac2016-05-03 17:12:581429 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311430 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521431 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361432 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431433 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1434 mock_quic_data.AddWrite(
1435 SYNCHRONOUS,
1436 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331437 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431438 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331440 ASYNC, ConstructServerResponseHeadersPacket(
1441 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1442 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411443 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331444 mock_quic_data.AddRead(
1445 ASYNC, ConstructServerDataPacket(
1446 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411447 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431448 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501449 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591450 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311451 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1452
1453 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291454 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311455 ASSERT_TRUE(cert.get());
1456 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241457 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1458 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311459 ProofVerifyDetailsChromium verify_details;
1460 verify_details.cert_verify_result.verified_cert = cert;
1461 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561462 ProofVerifyDetailsChromium verify_details2;
1463 verify_details2.cert_verify_result.verified_cert = cert;
1464 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311465
1466 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091467 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321468 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271469 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311470 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1471}
1472
rchbe69cb902016-02-11 01:10:481473TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341474 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481475 HostPortPair origin("www.example.org", 443);
1476 HostPortPair alternative("mail.example.org", 443);
1477
1478 base::FilePath certs_dir = GetTestCertsDirectory();
1479 scoped_refptr<X509Certificate> cert(
1480 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1481 ASSERT_TRUE(cert.get());
1482 // TODO(rch): the connection should be "to" the origin, so if the cert is
1483 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241484 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1485 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481486 ProofVerifyDetailsChromium verify_details;
1487 verify_details.cert_verify_result.verified_cert = cert;
1488 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1489
alyssar2adf3ac2016-05-03 17:12:581490 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481491 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521492 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361493 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431494 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1495 mock_quic_data.AddWrite(
1496 SYNCHRONOUS,
1497 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331498 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431499 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431500 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331501 ASYNC, ConstructServerResponseHeadersPacket(
1502 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1503 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411504 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331505 mock_quic_data.AddRead(
1506 ASYNC, ConstructServerDataPacket(
1507 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411508 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431509 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481510 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1511 mock_quic_data.AddRead(ASYNC, 0);
1512 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1513
1514 request_.url = GURL("https://" + origin.host());
1515 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271516 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091517 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321518 CreateSession();
rchbe69cb902016-02-11 01:10:481519
1520 SendRequestAndExpectQuicResponse("hello!");
1521}
1522
zhongyief3f4ce52017-07-05 23:53:281523TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521524 quic::QuicTransportVersion unsupported_version =
1525 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281526 // Add support for another QUIC version besides |version_|. Also find a
1527 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521528 for (const quic::QuicTransportVersion& version :
1529 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281530 if (version == version_)
1531 continue;
1532 if (supported_versions_.size() != 2) {
1533 supported_versions_.push_back(version);
1534 continue;
1535 }
1536 unsupported_version = version;
1537 break;
1538 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521539 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281540
1541 // Set up alternative service to use QUIC with a version that is not
1542 // supported.
1543 url::SchemeHostPort server(request_.url);
1544 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1545 443);
1546 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1547 http_server_properties_.SetQuicAlternativeService(
1548 server, alternative_service, expiration, {unsupported_version});
1549
1550 AlternativeServiceInfoVector alt_svc_info_vector =
1551 http_server_properties_.GetAlternativeServiceInfos(server);
1552 EXPECT_EQ(1u, alt_svc_info_vector.size());
1553 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1554 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1555 EXPECT_EQ(unsupported_version,
1556 alt_svc_info_vector[0].advertised_versions()[0]);
1557
1558 // First request should still be sent via TCP as the QUIC version advertised
1559 // in the stored AlternativeService is not supported by the client. However,
1560 // the response from the server will advertise new Alt-Svc with supported
1561 // versions.
1562 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521563 GenerateQuicVersionsListForAltSvcHeader(
1564 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281565 std::string altsvc_header =
1566 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1567 advertised_versions_list_str.c_str());
1568 MockRead http_reads[] = {
1569 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1570 MockRead("hello world"),
1571 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1572 MockRead(ASYNC, OK)};
1573
Ryan Sleevib8d7ea02018-05-07 20:01:011574 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281575 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081576 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281577 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1578
1579 // Second request should be sent via QUIC as a new list of verions supported
1580 // by the client has been advertised by the server.
1581 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521582 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281583 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431584 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1585 mock_quic_data.AddWrite(
1586 SYNCHRONOUS,
1587 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331588 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431589 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431590 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331591 ASYNC, ConstructServerResponseHeadersPacket(
1592 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1593 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411594 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331595 mock_quic_data.AddRead(
1596 ASYNC, ConstructServerDataPacket(
1597 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411598 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431599 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281600 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1601 mock_quic_data.AddRead(ASYNC, 0); // EOF
1602
1603 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1604
1605 AddHangingNonAlternateProtocolSocketData();
1606
1607 CreateSession(supported_versions_);
1608
1609 SendRequestAndExpectHttpResponse("hello world");
1610 SendRequestAndExpectQuicResponse("hello!");
1611
1612 // Check alternative service list is updated with new versions.
1613 alt_svc_info_vector =
1614 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1615 EXPECT_EQ(1u, alt_svc_info_vector.size());
1616 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1617 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1618 // Advertised versions will be lised in a sorted order.
1619 std::sort(supported_versions_.begin(), supported_versions_.end());
1620 EXPECT_EQ(supported_versions_[0],
1621 alt_svc_info_vector[0].advertised_versions()[0]);
1622 EXPECT_EQ(supported_versions_[1],
1623 alt_svc_info_vector[0].advertised_versions()[1]);
1624}
1625
bncaccd4962017-04-06 21:00:261626// Regression test for https://crbug.com/546991.
1627// The server might not be able to serve a request on an alternative connection,
1628// and might send a 421 Misdirected Request response status to indicate this.
1629// HttpNetworkTransaction should reset the request and retry without using
1630// alternative services.
1631TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1632 // Set up alternative service to use QUIC.
1633 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1634 // that overrides |enable_alternative_services|.
1635 url::SchemeHostPort server(request_.url);
1636 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1637 443);
1638 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211639 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441640 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261641
davidbena4449722017-05-05 23:30:531642 // First try: The alternative job uses QUIC and reports an HTTP 421
1643 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1644 // paused at Connect(), so it will never exit the socket pool. This ensures
1645 // that the alternate job always wins the race and keeps whether the
1646 // |http_data| exits the socket pool before the main job is aborted
1647 // deterministic. The first main job gets aborted without the socket pool ever
1648 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261649 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521650 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361651 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431652 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1653 mock_quic_data.AddWrite(
1654 SYNCHRONOUS,
1655 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331656 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431657 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331658 mock_quic_data.AddRead(
1659 ASYNC, ConstructServerResponseHeadersPacket(
1660 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1661 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261662 mock_quic_data.AddRead(ASYNC, OK);
1663 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1664
davidbena4449722017-05-05 23:30:531665 // Second try: The main job uses TCP, and there is no alternate job. Once the
1666 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1667 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261668 // Note that if there was an alternative QUIC Job created for the second try,
1669 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1670 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531671 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1672 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1673 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1674 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1675 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1676 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011677 reads, writes);
bncaccd4962017-04-06 21:00:261678 socket_factory_.AddSocketDataProvider(&http_data);
1679 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1680
bncaccd4962017-04-06 21:00:261681 CreateSession();
1682 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531683
1684 // Run until |mock_quic_data| has failed and |http_data| has paused.
1685 TestCompletionCallback callback;
1686 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1688 base::RunLoop().RunUntilIdle();
1689
1690 // |mock_quic_data| must have run to completion.
1691 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1692 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1693
1694 // Now that the QUIC data has been consumed, unblock |http_data|.
1695 http_data.socket()->OnConnectComplete(MockConnect());
1696
1697 // The retry logic must hide the 421 status. The transaction succeeds on
1698 // |http_data|.
1699 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261700 CheckWasHttpResponse(&trans);
1701 CheckResponsePort(&trans, 443);
1702 CheckResponseData(&trans, "hello!");
1703}
1704
[email protected]1e960032013-12-20 19:00:201705TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411706 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571707 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301708
tbansalfdf5665b2015-09-21 22:46:401709 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521710 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361711 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431712 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401713 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401714 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371715 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361716 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431717 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301718 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401719 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431720 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401721
1722 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1723 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301724
1725 CreateSession();
1726
tbansal0f56a39a2016-04-07 22:03:381727 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401728 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401730 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161731 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1733 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381734 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531735
1736 NetErrorDetails details;
1737 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521738 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401739 }
[email protected]cebe3282013-05-22 23:49:301740}
1741
tbansalc8a94ea2015-11-02 23:58:511742TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1743 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411744 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571745 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511746
1747 MockRead http_reads[] = {
1748 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1749 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1750 MockRead(ASYNC, OK)};
1751
Ryan Sleevib8d7ea02018-05-07 20:01:011752 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511753 socket_factory_.AddSocketDataProvider(&data);
1754 SSLSocketDataProvider ssl(ASYNC, OK);
1755 socket_factory_.AddSSLSocketDataProvider(&ssl);
1756
1757 CreateSession();
1758
1759 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381760 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511761}
1762
bncc958faa2015-07-31 18:14:521763TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521764 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561765 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1766 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521767 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1768 MockRead(ASYNC, OK)};
1769
Ryan Sleevib8d7ea02018-05-07 20:01:011770 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521771 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081772 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561773 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521774
1775 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521776 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361777 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431778 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1779 mock_quic_data.AddWrite(
1780 SYNCHRONOUS,
1781 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331782 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431783 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431784 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331785 ASYNC, ConstructServerResponseHeadersPacket(
1786 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1787 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411788 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331789 mock_quic_data.AddRead(
1790 ASYNC, ConstructServerDataPacket(
1791 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411792 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431793 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521794 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591795 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521796
1797 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1798
rtennetib8e80fb2016-05-16 00:12:091799 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321800 CreateSession();
bncc958faa2015-07-31 18:14:521801
1802 SendRequestAndExpectHttpResponse("hello world");
1803 SendRequestAndExpectQuicResponse("hello!");
1804}
1805
zhongyia00ca012017-07-06 23:36:391806TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1807 // Both server advertises and client supports two QUIC versions.
1808 // Only |version_| is advertised and supported.
1809 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1810 // PacketMakers are using |version_|.
1811
1812 // Add support for another QUIC version besides |version_| on the client side.
1813 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521814 quic::QuicTransportVersion advertised_version_2 =
1815 quic::QUIC_VERSION_UNSUPPORTED;
1816 for (const quic::QuicTransportVersion& version :
1817 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391818 if (version == version_)
1819 continue;
1820 if (supported_versions_.size() != 2) {
1821 supported_versions_.push_back(version);
1822 continue;
1823 }
1824 advertised_version_2 = version;
1825 break;
1826 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521827 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391828
1829 std::string QuicAltSvcWithVersionHeader =
1830 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1831 advertised_version_2, version_);
1832
1833 MockRead http_reads[] = {
1834 MockRead("HTTP/1.1 200 OK\r\n"),
1835 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1836 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1837 MockRead(ASYNC, OK)};
1838
Ryan Sleevib8d7ea02018-05-07 20:01:011839 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391840 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081841 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391842 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1843
1844 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521845 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391846 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431847 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1848 mock_quic_data.AddWrite(
1849 SYNCHRONOUS,
1850 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331851 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431852 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431853 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331854 ASYNC, ConstructServerResponseHeadersPacket(
1855 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1856 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411857 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331858 mock_quic_data.AddRead(
1859 ASYNC, ConstructServerDataPacket(
1860 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411861 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431862 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391863 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1864 mock_quic_data.AddRead(ASYNC, 0); // EOF
1865
1866 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1867
1868 AddHangingNonAlternateProtocolSocketData();
1869 CreateSession(supported_versions_);
1870
1871 SendRequestAndExpectHttpResponse("hello world");
1872 SendRequestAndExpectQuicResponse("hello!");
1873}
1874
1875TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1876 // Client and server mutually support more than one QUIC_VERSION.
1877 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1878 // which is verified as the PacketMakers are using |version_|.
1879
Ryan Hamilton8d9ee76e2018-05-29 23:52:521880 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1881 for (const quic::QuicTransportVersion& version :
1882 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391883 if (version == version_)
1884 continue;
1885 common_version_2 = version;
1886 break;
1887 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521888 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391889
1890 supported_versions_.push_back(
1891 common_version_2); // Supported but unpreferred.
1892
1893 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1894 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1895
1896 MockRead http_reads[] = {
1897 MockRead("HTTP/1.1 200 OK\r\n"),
1898 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1900 MockRead(ASYNC, OK)};
1901
Ryan Sleevib8d7ea02018-05-07 20:01:011902 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391903 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081904 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391905 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1906
1907 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521908 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391909 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431910 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1911 mock_quic_data.AddWrite(
1912 SYNCHRONOUS,
1913 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331914 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431915 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431916 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331917 ASYNC, ConstructServerResponseHeadersPacket(
1918 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1919 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411920 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331921 mock_quic_data.AddRead(
1922 ASYNC, ConstructServerDataPacket(
1923 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411924 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431925 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391926 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1927 mock_quic_data.AddRead(ASYNC, 0); // EOF
1928
1929 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1930
1931 AddHangingNonAlternateProtocolSocketData();
1932 CreateSession(supported_versions_);
1933
1934 SendRequestAndExpectHttpResponse("hello world");
1935 SendRequestAndExpectQuicResponse("hello!");
1936}
1937
rchf47265dc2016-03-21 21:33:121938TEST_P(QuicNetworkTransactionTest,
1939 UseAlternativeServiceWithProbabilityForQuic) {
1940 MockRead http_reads[] = {
1941 MockRead("HTTP/1.1 200 OK\r\n"),
1942 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1943 MockRead("hello world"),
1944 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1945 MockRead(ASYNC, OK)};
1946
Ryan Sleevib8d7ea02018-05-07 20:01:011947 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121948 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081949 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121950 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1951
1952 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521953 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361954 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431955 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1956 mock_quic_data.AddWrite(
1957 SYNCHRONOUS,
1958 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331959 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431960 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431961 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331962 ASYNC, ConstructServerResponseHeadersPacket(
1963 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1964 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411965 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331966 mock_quic_data.AddRead(
1967 ASYNC, ConstructServerDataPacket(
1968 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411969 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431970 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121971 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1972 mock_quic_data.AddRead(ASYNC, 0); // EOF
1973
1974 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1975
rtennetib8e80fb2016-05-16 00:12:091976 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121977 CreateSession();
1978
1979 SendRequestAndExpectHttpResponse("hello world");
1980 SendRequestAndExpectQuicResponse("hello!");
1981}
1982
zhongyi3d4a55e72016-04-22 20:36:461983TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1984 MockRead http_reads[] = {
1985 MockRead("HTTP/1.1 200 OK\r\n"),
1986 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1987 MockRead("hello world"),
1988 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1989 MockRead(ASYNC, OK)};
1990
Ryan Sleevib8d7ea02018-05-07 20:01:011991 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461992 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081993 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461994 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1995
1996 CreateSession();
bncb26024382016-06-29 02:39:451997 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461998 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451999 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462000 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402001 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462002 session_->http_server_properties();
2003 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2004 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2005 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462006 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342007 2u,
2008 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452009 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342010 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462011}
2012
2013TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2014 MockRead http_reads[] = {
2015 MockRead("HTTP/1.1 200 OK\r\n"),
2016 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2017 MockRead("hello world"),
2018 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2019 MockRead(ASYNC, OK)};
2020
Ryan Sleevib8d7ea02018-05-07 20:01:012021 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082022 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462023
2024 socket_factory_.AddSocketDataProvider(&http_data);
2025 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2026 socket_factory_.AddSocketDataProvider(&http_data);
2027 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2028
2029 CreateSession();
2030
2031 // Send https request and set alternative services if response header
2032 // advertises alternative service for mail.example.org.
2033 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402034 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462035 session_->http_server_properties();
2036
2037 const url::SchemeHostPort https_server(request_.url);
2038 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342039 EXPECT_EQ(
2040 2u,
2041 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462042
2043 // Send http request to the same origin but with diffrent scheme, should not
2044 // use QUIC.
2045 request_.url = GURL("http://mail.example.org:443");
2046 SendRequestAndExpectHttpResponse("hello world");
2047}
2048
zhongyie537a002017-06-27 16:48:212049TEST_P(QuicNetworkTransactionTest,
2050 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442051 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522052 for (const quic::QuicTransportVersion& version :
2053 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442054 if (version == version_)
2055 continue;
2056 supported_versions_.push_back(version);
2057 break;
2058 }
2059
zhongyie537a002017-06-27 16:48:212060 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522061 GenerateQuicVersionsListForAltSvcHeader(
2062 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212063 std::string altsvc_header =
2064 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2065 advertised_versions_list_str.c_str());
2066 MockRead http_reads[] = {
2067 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2068 MockRead("hello world"),
2069 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2070 MockRead(ASYNC, OK)};
2071
Ryan Sleevib8d7ea02018-05-07 20:01:012072 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212073 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082074 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212075 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2076
2077 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522078 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212079 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432080 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2081 mock_quic_data.AddWrite(
2082 SYNCHRONOUS,
2083 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332084 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432085 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432086 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332087 ASYNC, ConstructServerResponseHeadersPacket(
2088 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2089 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412090 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332091 mock_quic_data.AddRead(
2092 ASYNC, ConstructServerDataPacket(
2093 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412094 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432095 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212096 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2097 mock_quic_data.AddRead(ASYNC, 0); // EOF
2098
2099 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2100
2101 AddHangingNonAlternateProtocolSocketData();
2102
zhongyi86838d52017-06-30 01:19:442103 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212104
2105 SendRequestAndExpectHttpResponse("hello world");
2106 SendRequestAndExpectQuicResponse("hello!");
2107
2108 // Check alternative service is set with only mutually supported versions.
2109 const url::SchemeHostPort https_server(request_.url);
2110 const AlternativeServiceInfoVector alt_svc_info_vector =
2111 session_->http_server_properties()->GetAlternativeServiceInfos(
2112 https_server);
2113 EXPECT_EQ(1u, alt_svc_info_vector.size());
2114 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2115 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2116 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442117 std::sort(supported_versions_.begin(), supported_versions_.end());
2118 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212119 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442120 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212121 alt_svc_info_vector[0].advertised_versions()[1]);
2122}
2123
danzh3134c2562016-08-12 14:07:522124TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442125 std::string altsvc_header =
2126 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072127 MockRead http_reads[] = {
2128 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2129 MockRead("hello world"),
2130 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2131 MockRead(ASYNC, OK)};
2132
Ryan Sleevib8d7ea02018-05-07 20:01:012133 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072134 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082135 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072136 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2137
2138 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522139 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362140 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432141 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2142 mock_quic_data.AddWrite(
2143 SYNCHRONOUS,
2144 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332145 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432146 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432147 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332148 ASYNC, ConstructServerResponseHeadersPacket(
2149 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2150 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412151 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332152 mock_quic_data.AddRead(
2153 ASYNC, ConstructServerDataPacket(
2154 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412155 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432156 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072157 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592158 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072159
2160 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2161
rtennetib8e80fb2016-05-16 00:12:092162 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322163 CreateSession();
bnc8be55ebb2015-10-30 14:12:072164
2165 SendRequestAndExpectHttpResponse("hello world");
2166 SendRequestAndExpectQuicResponse("hello!");
2167}
2168
zhongyi6b5a3892016-03-12 04:46:202169TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092170 if (version_ == quic::QUIC_VERSION_99) {
2171 // Not available under version 99
2172 return;
2173 }
zhongyi6b5a3892016-03-12 04:46:202174 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522175 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362176 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432177 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2178 mock_quic_data.AddWrite(
2179 SYNCHRONOUS,
2180 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332181 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432182 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332183 mock_quic_data.AddRead(
2184 ASYNC, ConstructServerResponseHeadersPacket(
2185 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2186 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202187 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522188 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432189 mock_quic_data.AddRead(SYNCHRONOUS,
2190 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522191 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432192 "connection migration with port change only"));
2193 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:412194 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332195 mock_quic_data.AddRead(
2196 SYNCHRONOUS, ConstructServerDataPacket(
2197 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412198 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332199 mock_quic_data.AddWrite(SYNCHRONOUS,
2200 ConstructClientAckAndRstPacket(
2201 4, GetNthClientInitiatedBidirectionalStreamId(0),
2202 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202203 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2204 mock_quic_data.AddRead(ASYNC, 0); // EOF
2205
2206 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2207
2208 // The non-alternate protocol job needs to hang in order to guarantee that
2209 // the alternate-protocol job will "win".
2210 AddHangingNonAlternateProtocolSocketData();
2211
2212 // In order for a new QUIC session to be established via alternate-protocol
2213 // without racing an HTTP connection, we need the host resolution to happen
2214 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2215 // connection to the the server, in this test we require confirmation
2216 // before encrypting so the HTTP job will still start.
2217 host_resolver_.set_synchronous_mode(true);
2218 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2219 "");
2220 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2221 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102222 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582223 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2224 CompletionOnceCallback(), &request,
2225 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412226 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202227
2228 CreateSession();
2229 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272230 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202231
bnc691fda62016-08-12 00:43:162232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202233 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412234 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202236
2237 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522238 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012239 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202240
2241 // Check whether this transaction is correctly marked as received a go-away
2242 // because of migrating port.
2243 NetErrorDetails details;
2244 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162245 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202246 EXPECT_TRUE(details.quic_port_migration_detected);
2247}
2248
Zhongyi Shia6b68d112018-09-24 07:49:032249// This test verifies that a new QUIC connection will be attempted on the
2250// alternate network if the original QUIC connection fails with idle timeout
2251// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2252// alternate network as well, QUIC is marked as broken and the brokenness will
2253// not expire when default network changes.
2254TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2255 SetUpTestForRetryConnectionOnAlternateNetwork();
2256
2257 std::string request_data;
2258 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2259 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2260
2261 // The request will initially go out over QUIC.
2262 MockQuicData quic_data;
2263 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2264 int packet_num = 1;
2265 quic_data.AddWrite(SYNCHRONOUS,
2266 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2267 // Retranmit the handshake messages.
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 quic_data.AddWrite(SYNCHRONOUS,
2275 client_maker_.MakeDummyCHLOPacket(packet_num++));
2276 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2277 if (version_ <= quic::QUIC_VERSION_39) {
2278 quic_data.AddWrite(SYNCHRONOUS,
2279 client_maker_.MakeDummyCHLOPacket(packet_num++));
2280 }
2281 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2282 quic_data.AddWrite(SYNCHRONOUS,
2283 client_maker_.MakeConnectionClosePacket(
2284 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2285 "No recent network activity."));
2286 quic_data.AddSocketDataToFactory(&socket_factory_);
2287
2288 // Add successful TCP data so that TCP job will succeed.
2289 MockWrite http_writes[] = {
2290 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2291 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2292 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2293
2294 MockRead http_reads[] = {
2295 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2296 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2297 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2298 SequencedSocketData http_data(http_reads, http_writes);
2299 socket_factory_.AddSocketDataProvider(&http_data);
2300 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2301
2302 // Add data for the second QUIC connection to fail.
2303 MockQuicData quic_data2;
2304 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2305 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2306 quic_data2.AddSocketDataToFactory(&socket_factory_);
2307
2308 // Resolve the host resolution synchronously.
2309 host_resolver_.set_synchronous_mode(true);
2310 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2311 "");
2312 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2313 AddressList address;
2314 std::unique_ptr<HostResolver::Request> request;
2315 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2316 CompletionOnceCallback(), &request,
2317 net_log_.bound());
2318 EXPECT_THAT(rv, IsOk());
2319
2320 CreateSession();
2321 session_->quic_stream_factory()->set_require_confirmation(true);
2322 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2323 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2324 QuicStreamFactoryPeer::SetAlarmFactory(
2325 session_->quic_stream_factory(),
2326 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2327 &clock_));
2328 // Add alternate protocol mapping to race QUIC and TCP.
2329 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2330 // peer.
2331 AddQuicAlternateProtocolMapping(
2332 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2333
2334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2335 TestCompletionCallback callback;
2336 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2338
2339 // Pump the message loop to get the request started.
2340 // Request will be served with TCP job.
2341 base::RunLoop().RunUntilIdle();
2342 EXPECT_THAT(callback.WaitForResult(), IsOk());
2343 CheckResponseData(&trans, "TCP succeeds");
2344
2345 // Fire the retransmission alarm, from this point, connection will idle
2346 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062347 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182348 quic_fix_time_of_first_packet_sent_after_receiving)) {
2349 quic_task_runner_->RunNextTask();
2350 }
Zhongyi Shia6b68d112018-09-24 07:49:032351 // Fast forward to idle timeout the original connection. A new connection will
2352 // be kicked off on the alternate network.
2353 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2354 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2355 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2356
2357 // Run the message loop to execute posted tasks, which will report job status.
2358 base::RunLoop().RunUntilIdle();
2359
2360 // Verify that QUIC is marked as broken.
2361 ExpectBrokenAlternateProtocolMapping();
2362
2363 // Deliver a message to notify the new network becomes default, the brokenness
2364 // will not expire as QUIC is broken on both networks.
2365 scoped_mock_change_notifier_->mock_network_change_notifier()
2366 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2367 ExpectBrokenAlternateProtocolMapping();
2368
2369 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2370 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2371}
2372
2373// This test verifies that a new QUIC connection will be attempted on the
2374// alternate network if the original QUIC connection fails with idle timeout
2375// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2376// alternate network, QUIC is marked as broken. The brokenness will expire when
2377// the default network changes.
2378TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2379 SetUpTestForRetryConnectionOnAlternateNetwork();
2380
2381 std::string request_data;
2382 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2383 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2384
2385 // The request will initially go out over QUIC.
2386 MockQuicData quic_data;
2387 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2388 int packet_num = 1;
2389 quic_data.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2391 // Retranmit the handshake messages.
2392 quic_data.AddWrite(SYNCHRONOUS,
2393 client_maker_.MakeDummyCHLOPacket(packet_num++));
2394 quic_data.AddWrite(SYNCHRONOUS,
2395 client_maker_.MakeDummyCHLOPacket(packet_num++));
2396 quic_data.AddWrite(SYNCHRONOUS,
2397 client_maker_.MakeDummyCHLOPacket(packet_num++));
2398 quic_data.AddWrite(SYNCHRONOUS,
2399 client_maker_.MakeDummyCHLOPacket(packet_num++));
2400 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2401 if (version_ <= quic::QUIC_VERSION_39) {
2402 quic_data.AddWrite(SYNCHRONOUS,
2403 client_maker_.MakeDummyCHLOPacket(packet_num++));
2404 }
2405 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2406 quic_data.AddWrite(SYNCHRONOUS,
2407 client_maker_.MakeConnectionClosePacket(
2408 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2409 "No recent network activity."));
2410 quic_data.AddSocketDataToFactory(&socket_factory_);
2411
2412 // Add successful TCP data so that TCP job will succeed.
2413 MockWrite http_writes[] = {
2414 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2415 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2416 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2417
2418 MockRead http_reads[] = {
2419 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2420 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2421 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2422 SequencedSocketData http_data(http_reads, http_writes);
2423 socket_factory_.AddSocketDataProvider(&http_data);
2424 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2425
2426 // Quic connection will be retried on the alternate network after the initial
2427 // one fails on the default network.
2428 MockQuicData quic_data2;
2429 quic::QuicStreamOffset header_stream_offset = 0;
2430 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2431 quic_data2.AddWrite(SYNCHRONOUS,
2432 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2433
2434 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2435 quic_data2.AddWrite(SYNCHRONOUS,
2436 ConstructInitialSettingsPacket(2, &header_stream_offset));
2437 quic_data2.AddSocketDataToFactory(&socket_factory_);
2438
2439 // Resolve the host resolution synchronously.
2440 host_resolver_.set_synchronous_mode(true);
2441 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2442 "");
2443 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2444 AddressList address;
2445 std::unique_ptr<HostResolver::Request> request;
2446 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2447 CompletionOnceCallback(), &request,
2448 net_log_.bound());
2449 EXPECT_THAT(rv, IsOk());
2450
2451 CreateSession();
2452 session_->quic_stream_factory()->set_require_confirmation(true);
2453 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2454 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2455 QuicStreamFactoryPeer::SetAlarmFactory(
2456 session_->quic_stream_factory(),
2457 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2458 &clock_));
2459 // Add alternate protocol mapping to race QUIC and TCP.
2460 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2461 // peer.
2462 AddQuicAlternateProtocolMapping(
2463 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2464
2465 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2466 TestCompletionCallback callback;
2467 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2468 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2469
2470 // Pump the message loop to get the request started.
2471 // Request will be served with TCP job.
2472 base::RunLoop().RunUntilIdle();
2473 EXPECT_THAT(callback.WaitForResult(), IsOk());
2474 CheckResponseData(&trans, "TCP succeeds");
2475
2476 // Fire the retransmission alarm, after which connection will idle
2477 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062478 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182479 quic_fix_time_of_first_packet_sent_after_receiving)) {
2480 quic_task_runner_->RunNextTask();
2481 }
Zhongyi Shia6b68d112018-09-24 07:49:032482 // Fast forward to idle timeout the original connection. A new connection will
2483 // be kicked off on the alternate network.
2484 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2485 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2486 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2487
2488 // The second connection hasn't finish handshake, verify that QUIC is not
2489 // marked as broken.
2490 ExpectQuicAlternateProtocolMapping();
2491 // Explicitly confirm the handshake on the second connection.
2492 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2493 quic::QuicSession::HANDSHAKE_CONFIRMED);
2494 // Run message loop to execute posted tasks, which will notify JoController
2495 // about the orphaned job status.
2496 base::RunLoop().RunUntilIdle();
2497
2498 // Verify that QUIC is marked as broken.
2499 ExpectBrokenAlternateProtocolMapping();
2500
2501 // Deliver a message to notify the new network becomes default, the previous
2502 // brokenness will be clear as the brokenness is bond with old default
2503 // network.
2504 scoped_mock_change_notifier_->mock_network_change_notifier()
2505 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2506 ExpectQuicAlternateProtocolMapping();
2507
2508 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2509 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2510}
2511
2512// This test verifies that a new QUIC connection will be attempted on the
2513// alternate network if the original QUIC connection fails with idle timeout
2514// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2515// alternative network succeeds, QUIC is not marked as broken.
2516TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2517 SetUpTestForRetryConnectionOnAlternateNetwork();
2518
2519 std::string request_data;
2520 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2521 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2522
2523 // The request will initially go out over QUIC.
2524 MockQuicData quic_data;
2525 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2526 int packet_num = 1;
2527 quic_data.AddWrite(SYNCHRONOUS,
2528 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2529 // Retranmit the handshake messages.
2530 quic_data.AddWrite(SYNCHRONOUS,
2531 client_maker_.MakeDummyCHLOPacket(packet_num++));
2532 quic_data.AddWrite(SYNCHRONOUS,
2533 client_maker_.MakeDummyCHLOPacket(packet_num++));
2534 quic_data.AddWrite(SYNCHRONOUS,
2535 client_maker_.MakeDummyCHLOPacket(packet_num++));
2536 quic_data.AddWrite(SYNCHRONOUS,
2537 client_maker_.MakeDummyCHLOPacket(packet_num++));
2538 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2539 // quic_fix_has_pending_crypto_data is introduced and enabled.
2540 if (version_ <= quic::QUIC_VERSION_39) {
2541 quic_data.AddWrite(SYNCHRONOUS,
2542 client_maker_.MakeDummyCHLOPacket(packet_num++));
2543 }
2544 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2545 quic_data.AddWrite(SYNCHRONOUS,
2546 client_maker_.MakeConnectionClosePacket(
2547 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2548 "No recent network activity."));
2549 quic_data.AddSocketDataToFactory(&socket_factory_);
2550
2551 // Add hanging TCP data so that TCP job will never succeeded.
2552 AddHangingNonAlternateProtocolSocketData();
2553
2554 // Quic connection will then be retried on the alternate network.
2555 MockQuicData quic_data2;
2556 quic::QuicStreamOffset header_stream_offset = 0;
2557 quic_data2.AddWrite(SYNCHRONOUS,
2558 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2559
Renjief49758b2019-01-11 23:32:412560 const quic::QuicString body = "hello!";
2561 quic::QuicString header = ConstructDataHeader(body.length());
2562
Zhongyi Shia6b68d112018-09-24 07:49:032563 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2564 quic_data2.AddWrite(SYNCHRONOUS,
2565 ConstructInitialSettingsPacket(2, &header_stream_offset));
2566 quic_data2.AddWrite(
2567 SYNCHRONOUS,
2568 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332569 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032570 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032571 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332572 ASYNC, ConstructServerResponseHeadersPacket(
2573 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2574 GetResponseHeaders("200 OK")));
2575 quic_data2.AddRead(
2576 ASYNC, ConstructServerDataPacket(
2577 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412578 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032579 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2580 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2581 quic_data2.AddSocketDataToFactory(&socket_factory_);
2582
2583 // Resolve the host resolution synchronously.
2584 host_resolver_.set_synchronous_mode(true);
2585 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2586 "");
2587 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2588 AddressList address;
2589 std::unique_ptr<HostResolver::Request> request;
2590 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2591 CompletionOnceCallback(), &request,
2592 net_log_.bound());
2593 EXPECT_THAT(rv, IsOk());
2594
2595 CreateSession();
2596 session_->quic_stream_factory()->set_require_confirmation(true);
2597 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2598 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2599 QuicStreamFactoryPeer::SetAlarmFactory(
2600 session_->quic_stream_factory(),
2601 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2602 &clock_));
2603 // Add alternate protocol mapping to race QUIC and TCP.
2604 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2605 // peer.
2606 AddQuicAlternateProtocolMapping(
2607 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2608
2609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2610 TestCompletionCallback callback;
2611 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2613
2614 // Pump the message loop to get the request started.
2615 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062616 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182617 quic_fix_time_of_first_packet_sent_after_receiving)) {
2618 quic_task_runner_->RunNextTask();
2619 }
Zhongyi Shia6b68d112018-09-24 07:49:032620
2621 // Fast forward to idle timeout the original connection. A new connection will
2622 // be kicked off on the alternate network.
2623 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2624 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2625 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2626
2627 // Verify that QUIC is not marked as broken.
2628 ExpectQuicAlternateProtocolMapping();
2629 // Explicitly confirm the handshake on the second connection.
2630 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2631 quic::QuicSession::HANDSHAKE_CONFIRMED);
2632
2633 // Read the response.
2634 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412635 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032636 // Verify that QUIC is not marked as broken.
2637 ExpectQuicAlternateProtocolMapping();
2638
2639 // Deliver a message to notify the new network becomes default.
2640 scoped_mock_change_notifier_->mock_network_change_notifier()
2641 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2642 ExpectQuicAlternateProtocolMapping();
2643 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2644 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2645}
2646
rch9ecde09b2017-04-08 00:18:232647// Verify that if a QUIC connection times out, the QuicHttpStream will
2648// return QUIC_PROTOCOL_ERROR.
2649TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482650 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412651 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232652
2653 // The request will initially go out over QUIC.
2654 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522655 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132656 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232657 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2658
2659 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522660 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2661 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432662 quic_data.AddWrite(SYNCHRONOUS,
2663 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332664 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2665 true, priority, GetRequestHeaders("GET", "https", "/"),
2666 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232667
2668 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522669 quic::QuicStreamOffset settings_offset = header_stream_offset;
2670 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432671 quic_data.AddWrite(SYNCHRONOUS,
2672 client_maker_.MakeInitialSettingsPacketAndSaveData(
2673 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232674 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092675 quic_data.AddWrite(SYNCHRONOUS,
2676 client_maker_.MakeDataPacket(
2677 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2678 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232679 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092680 quic_data.AddWrite(SYNCHRONOUS,
2681 client_maker_.MakeDataPacket(
2682 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2683 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232684 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092685 quic_data.AddWrite(SYNCHRONOUS,
2686 client_maker_.MakeDataPacket(
2687 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2688 false, 0, request_data));
2689 quic_data.AddWrite(SYNCHRONOUS,
2690 client_maker_.MakeDataPacket(
2691 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2692 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232693 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092694 quic_data.AddWrite(SYNCHRONOUS,
2695 client_maker_.MakeDataPacket(
2696 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2697 false, 0, request_data));
2698 quic_data.AddWrite(SYNCHRONOUS,
2699 client_maker_.MakeDataPacket(
2700 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2701 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232702 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092703 quic_data.AddWrite(SYNCHRONOUS,
2704 client_maker_.MakeDataPacket(
2705 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2706 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522707 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092708 SYNCHRONOUS, client_maker_.MakeDataPacket(
2709 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2710 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232711
Zhongyi Shi32f2fd02018-04-16 18:23:432712 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522713 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432714 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222715
rch9ecde09b2017-04-08 00:18:232716 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2717 quic_data.AddRead(ASYNC, OK);
2718 quic_data.AddSocketDataToFactory(&socket_factory_);
2719
2720 // In order for a new QUIC session to be established via alternate-protocol
2721 // without racing an HTTP connection, we need the host resolution to happen
2722 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2723 // connection to the the server, in this test we require confirmation
2724 // before encrypting so the HTTP job will still start.
2725 host_resolver_.set_synchronous_mode(true);
2726 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2727 "");
2728 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2729 AddressList address;
2730 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582731 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2732 CompletionOnceCallback(), &request,
2733 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412734 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232735
2736 CreateSession();
2737 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552738 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232739 QuicStreamFactoryPeer::SetAlarmFactory(
2740 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192741 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552742 &clock_));
rch9ecde09b2017-04-08 00:18:232743
Ryan Hamilton9835e662018-08-02 05:36:272744 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232745
2746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2747 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412748 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232749 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2750
2751 // Pump the message loop to get the request started.
2752 base::RunLoop().RunUntilIdle();
2753 // Explicitly confirm the handshake.
2754 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522755 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232756
2757 // Run the QUIC session to completion.
2758 quic_task_runner_->RunUntilIdle();
2759
2760 ExpectQuicAlternateProtocolMapping();
2761 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2762 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2763}
2764
2765// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2766// return QUIC_PROTOCOL_ERROR.
2767TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482768 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522769 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232770
2771 // The request will initially go out over QUIC.
2772 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522773 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132774 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232775 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2776
2777 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522778 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2779 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432780 quic_data.AddWrite(SYNCHRONOUS,
2781 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332782 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2783 true, priority, GetRequestHeaders("GET", "https", "/"),
2784 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232785
2786 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522787 quic::QuicStreamOffset settings_offset = header_stream_offset;
2788 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432789 quic_data.AddWrite(SYNCHRONOUS,
2790 client_maker_.MakeInitialSettingsPacketAndSaveData(
2791 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232792 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092793 quic_data.AddWrite(SYNCHRONOUS,
2794 client_maker_.MakeDataPacket(
2795 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2796 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232797 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092798 quic_data.AddWrite(SYNCHRONOUS,
2799 client_maker_.MakeDataPacket(
2800 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2801 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232802 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092803 quic_data.AddWrite(SYNCHRONOUS,
2804 client_maker_.MakeDataPacket(
2805 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2806 false, 0, request_data));
2807 quic_data.AddWrite(SYNCHRONOUS,
2808 client_maker_.MakeDataPacket(
2809 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2810 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232811 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092812 quic_data.AddWrite(SYNCHRONOUS,
2813 client_maker_.MakeDataPacket(
2814 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2815 false, 0, request_data));
2816 quic_data.AddWrite(SYNCHRONOUS,
2817 client_maker_.MakeDataPacket(
2818 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2819 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232820 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092821 quic_data.AddWrite(SYNCHRONOUS,
2822 client_maker_.MakeDataPacket(
2823 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2824 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522825 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092826 SYNCHRONOUS, client_maker_.MakeDataPacket(
2827 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2828 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232829 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522830 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092831 SYNCHRONOUS, client_maker_.MakeDataPacket(
2832 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2833 false, 0, request_data));
2834 quic_data.AddWrite(
2835 SYNCHRONOUS, client_maker_.MakeDataPacket(
2836 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2837 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232838 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432839 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522840 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432841 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232842
2843 quic_data.AddRead(ASYNC, OK);
2844 quic_data.AddSocketDataToFactory(&socket_factory_);
2845
2846 // In order for a new QUIC session to be established via alternate-protocol
2847 // without racing an HTTP connection, we need the host resolution to happen
2848 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2849 // connection to the the server, in this test we require confirmation
2850 // before encrypting so the HTTP job will still start.
2851 host_resolver_.set_synchronous_mode(true);
2852 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2853 "");
2854 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2855 AddressList address;
2856 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582857 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2858 CompletionOnceCallback(), &request,
2859 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412860 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232861
2862 CreateSession();
2863 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552864 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232865 QuicStreamFactoryPeer::SetAlarmFactory(
2866 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192867 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552868 &clock_));
rch9ecde09b2017-04-08 00:18:232869
Ryan Hamilton9835e662018-08-02 05:36:272870 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232871
2872 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2873 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412874 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2876
2877 // Pump the message loop to get the request started.
2878 base::RunLoop().RunUntilIdle();
2879 // Explicitly confirm the handshake.
2880 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522881 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232882
2883 // Run the QUIC session to completion.
2884 quic_task_runner_->RunUntilIdle();
2885
2886 ExpectQuicAlternateProtocolMapping();
2887 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2888 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2889}
2890
2891// Verify that if a QUIC connection RTOs, while there are no active streams
2892// QUIC will not be marked as broken.
2893TEST_P(QuicNetworkTransactionTest,
2894 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522895 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232896
2897 // The request will initially go out over QUIC.
2898 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522899 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132900 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232901 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2902
2903 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522904 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2905 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432906 quic_data.AddWrite(SYNCHRONOUS,
2907 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332908 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2909 true, priority, GetRequestHeaders("GET", "https", "/"),
2910 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232911
2912 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522913 quic::QuicStreamOffset settings_offset = header_stream_offset;
2914 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432915 quic_data.AddWrite(SYNCHRONOUS,
2916 client_maker_.MakeInitialSettingsPacketAndSaveData(
2917 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232918
Fan Yang32c5a112018-12-10 20:06:332919 quic_data.AddWrite(SYNCHRONOUS,
2920 client_maker_.MakeRstPacket(
2921 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2922 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232923 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092924 quic_data.AddWrite(SYNCHRONOUS,
2925 client_maker_.MakeDataPacket(
2926 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2927 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232928 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092929 quic_data.AddWrite(SYNCHRONOUS,
2930 client_maker_.MakeDataPacket(
2931 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2932 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232933 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332934 quic_data.AddWrite(SYNCHRONOUS,
2935 client_maker_.MakeRstPacket(
2936 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2937 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092938 quic_data.AddWrite(SYNCHRONOUS,
2939 client_maker_.MakeDataPacket(
2940 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2941 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232942 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092943 quic_data.AddWrite(SYNCHRONOUS,
2944 client_maker_.MakeDataPacket(
2945 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2946 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332947 quic_data.AddWrite(SYNCHRONOUS,
2948 client_maker_.MakeRstPacket(
2949 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2950 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232951 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522952 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092953 SYNCHRONOUS, client_maker_.MakeDataPacket(
2954 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2955 false, 0, request_data));
2956 quic_data.AddWrite(
2957 SYNCHRONOUS, client_maker_.MakeDataPacket(
2958 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2959 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232960 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432961 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332962 SYNCHRONOUS, client_maker_.MakeRstPacket(
2963 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2964 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522965 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092966 SYNCHRONOUS, client_maker_.MakeDataPacket(
2967 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2968 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232969 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432970 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522971 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432972 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232973
2974 quic_data.AddRead(ASYNC, OK);
2975 quic_data.AddSocketDataToFactory(&socket_factory_);
2976
2977 // In order for a new QUIC session to be established via alternate-protocol
2978 // without racing an HTTP connection, we need the host resolution to happen
2979 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2980 // connection to the the server, in this test we require confirmation
2981 // before encrypting so the HTTP job will still start.
2982 host_resolver_.set_synchronous_mode(true);
2983 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2984 "");
2985 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2986 AddressList address;
2987 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582988 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2989 CompletionOnceCallback(), &request,
2990 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412991 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232992
2993 CreateSession();
2994 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552995 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232996 QuicStreamFactoryPeer::SetAlarmFactory(
2997 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192998 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552999 &clock_));
rch9ecde09b2017-04-08 00:18:233000
Ryan Hamilton9835e662018-08-02 05:36:273001 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233002
Jeremy Roman0579ed62017-08-29 15:56:193003 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233004 session_.get());
3005 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413006 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3008
3009 // Pump the message loop to get the request started.
3010 base::RunLoop().RunUntilIdle();
3011 // Explicitly confirm the handshake.
3012 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523013 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233014
3015 // Now cancel the request.
3016 trans.reset();
3017
3018 // Run the QUIC session to completion.
3019 quic_task_runner_->RunUntilIdle();
3020
3021 ExpectQuicAlternateProtocolMapping();
3022
3023 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3024}
3025
rch2f2991c2017-04-13 19:28:173026// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3027// the request fails with QUIC_PROTOCOL_ERROR.
3028TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:483029 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173030 // The request will initially go out over QUIC.
3031 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523032 quic::QuicStreamOffset header_stream_offset = 0;
3033 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3034 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433035 quic_data.AddWrite(
3036 SYNCHRONOUS,
3037 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333038 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433039 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523040 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433041 quic_data.AddWrite(SYNCHRONOUS,
3042 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173043 // Peer sending data from an non-existing stream causes this end to raise
3044 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333045 quic_data.AddRead(
3046 ASYNC, ConstructServerRstPacket(
3047 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3048 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173049 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433050 quic_data.AddWrite(SYNCHRONOUS,
3051 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523052 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3053 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173054 quic_data.AddSocketDataToFactory(&socket_factory_);
3055
3056 // In order for a new QUIC session to be established via alternate-protocol
3057 // without racing an HTTP connection, we need the host resolution to happen
3058 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3059 // connection to the the server, in this test we require confirmation
3060 // before encrypting so the HTTP job will still start.
3061 host_resolver_.set_synchronous_mode(true);
3062 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3063 "");
3064 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3065 AddressList address;
3066 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583067 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3068 CompletionOnceCallback(), &request,
3069 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413070 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173071
3072 CreateSession();
3073
Ryan Hamilton9835e662018-08-02 05:36:273074 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173075
3076 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3077 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413078 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3080
3081 // Pump the message loop to get the request started.
3082 base::RunLoop().RunUntilIdle();
3083 // Explicitly confirm the handshake.
3084 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523085 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173086
3087 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3088
3089 // Run the QUIC session to completion.
3090 base::RunLoop().RunUntilIdle();
3091 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3092 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3093
3094 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3095 ExpectQuicAlternateProtocolMapping();
3096 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3097}
3098
rch9ecde09b2017-04-08 00:18:233099// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3100// connection times out, then QUIC will be marked as broken and the request
3101// retried over TCP.
3102TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413103 session_params_.mark_quic_broken_when_network_blackholes = true;
3104 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233105
3106 // The request will initially go out over QUIC.
3107 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523108 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133109 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233110 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3111
3112 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523113 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3114 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433115 quic_data.AddWrite(SYNCHRONOUS,
3116 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333117 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3118 true, priority, GetRequestHeaders("GET", "https", "/"),
3119 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233120
3121 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523122 quic::QuicStreamOffset settings_offset = header_stream_offset;
3123 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433124 quic_data.AddWrite(SYNCHRONOUS,
3125 client_maker_.MakeInitialSettingsPacketAndSaveData(
3126 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233127 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093128 quic_data.AddWrite(SYNCHRONOUS,
3129 client_maker_.MakeDataPacket(
3130 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3131 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233132 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093133 quic_data.AddWrite(SYNCHRONOUS,
3134 client_maker_.MakeDataPacket(
3135 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3136 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233137 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093138 quic_data.AddWrite(SYNCHRONOUS,
3139 client_maker_.MakeDataPacket(
3140 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3141 false, 0, request_data));
3142 quic_data.AddWrite(SYNCHRONOUS,
3143 client_maker_.MakeDataPacket(
3144 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3145 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233146 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093147 quic_data.AddWrite(SYNCHRONOUS,
3148 client_maker_.MakeDataPacket(
3149 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3150 false, 0, request_data));
3151 quic_data.AddWrite(SYNCHRONOUS,
3152 client_maker_.MakeDataPacket(
3153 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3154 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233155 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093156 quic_data.AddWrite(SYNCHRONOUS,
3157 client_maker_.MakeDataPacket(
3158 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3159 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523160 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093161 SYNCHRONOUS, client_maker_.MakeDataPacket(
3162 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3163 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233164
Zhongyi Shi32f2fd02018-04-16 18:23:433165 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523166 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433167 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223168
rch9ecde09b2017-04-08 00:18:233169 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3170 quic_data.AddRead(ASYNC, OK);
3171 quic_data.AddSocketDataToFactory(&socket_factory_);
3172
3173 // After that fails, it will be resent via TCP.
3174 MockWrite http_writes[] = {
3175 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3176 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3177 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3178
3179 MockRead http_reads[] = {
3180 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3181 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3182 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013183 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233184 socket_factory_.AddSocketDataProvider(&http_data);
3185 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3186
3187 // In order for a new QUIC session to be established via alternate-protocol
3188 // without racing an HTTP connection, we need the host resolution to happen
3189 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3190 // connection to the the server, in this test we require confirmation
3191 // before encrypting so the HTTP job will still start.
3192 host_resolver_.set_synchronous_mode(true);
3193 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3194 "");
3195 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3196 AddressList address;
3197 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583198 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3199 CompletionOnceCallback(), &request,
3200 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413201 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233202
3203 CreateSession();
3204 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553205 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233206 QuicStreamFactoryPeer::SetAlarmFactory(
3207 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193208 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553209 &clock_));
rch9ecde09b2017-04-08 00:18:233210
Ryan Hamilton9835e662018-08-02 05:36:273211 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233212
3213 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3214 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413215 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233216 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3217
3218 // Pump the message loop to get the request started.
3219 base::RunLoop().RunUntilIdle();
3220 // Explicitly confirm the handshake.
3221 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523222 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233223
3224 // Run the QUIC session to completion.
3225 quic_task_runner_->RunUntilIdle();
3226 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3227
3228 // Let the transaction proceed which will result in QUIC being marked
3229 // as broken and the request falling back to TCP.
3230 EXPECT_THAT(callback.WaitForResult(), IsOk());
3231
3232 ExpectBrokenAlternateProtocolMapping();
3233 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3234 ASSERT_FALSE(http_data.AllReadDataConsumed());
3235
3236 // Read the response body over TCP.
3237 CheckResponseData(&trans, "hello world");
3238 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3239 ASSERT_TRUE(http_data.AllReadDataConsumed());
3240}
3241
rch2f2991c2017-04-13 19:28:173242// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3243// connection times out, then QUIC will be marked as broken and the request
3244// retried over TCP.
3245TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413246 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173247
3248 // The request will initially go out over QUIC.
3249 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523250 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133251 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173252 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3253
3254 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523255 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3256 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433257 quic_data.AddWrite(SYNCHRONOUS,
3258 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333259 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3260 true, priority, GetRequestHeaders("GET", "https", "/"),
3261 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173262
3263 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523264 quic::QuicStreamOffset settings_offset = header_stream_offset;
3265 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433266 quic_data.AddWrite(SYNCHRONOUS,
3267 client_maker_.MakeInitialSettingsPacketAndSaveData(
3268 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173269 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093270 quic_data.AddWrite(SYNCHRONOUS,
3271 client_maker_.MakeDataPacket(
3272 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3273 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173274 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093275 quic_data.AddWrite(SYNCHRONOUS,
3276 client_maker_.MakeDataPacket(
3277 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3278 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173279 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093280 quic_data.AddWrite(SYNCHRONOUS,
3281 client_maker_.MakeDataPacket(
3282 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3283 false, 0, request_data));
3284 quic_data.AddWrite(SYNCHRONOUS,
3285 client_maker_.MakeDataPacket(
3286 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3287 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173288 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093289 quic_data.AddWrite(SYNCHRONOUS,
3290 client_maker_.MakeDataPacket(
3291 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3292 false, 0, request_data));
3293 quic_data.AddWrite(SYNCHRONOUS,
3294 client_maker_.MakeDataPacket(
3295 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3296 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173297 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093298 quic_data.AddWrite(SYNCHRONOUS,
3299 client_maker_.MakeDataPacket(
3300 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3301 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523302 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093303 SYNCHRONOUS, client_maker_.MakeDataPacket(
3304 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3305 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173306
Zhongyi Shi32f2fd02018-04-16 18:23:433307 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523308 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433309 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223310
rch2f2991c2017-04-13 19:28:173311 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3312 quic_data.AddRead(ASYNC, OK);
3313 quic_data.AddSocketDataToFactory(&socket_factory_);
3314
3315 // After that fails, it will be resent via TCP.
3316 MockWrite http_writes[] = {
3317 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3318 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3319 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3320
3321 MockRead http_reads[] = {
3322 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3323 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3324 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013325 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173326 socket_factory_.AddSocketDataProvider(&http_data);
3327 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3328
3329 // In order for a new QUIC session to be established via alternate-protocol
3330 // without racing an HTTP connection, we need the host resolution to happen
3331 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3332 // connection to the the server, in this test we require confirmation
3333 // before encrypting so the HTTP job will still start.
3334 host_resolver_.set_synchronous_mode(true);
3335 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3336 "");
3337 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3338 AddressList address;
3339 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583340 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3341 CompletionOnceCallback(), &request,
3342 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413343 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173344
3345 CreateSession();
3346 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553347 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173348 QuicStreamFactoryPeer::SetAlarmFactory(
3349 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193350 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553351 &clock_));
rch2f2991c2017-04-13 19:28:173352
Ryan Hamilton9835e662018-08-02 05:36:273353 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173354
3355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3356 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413357 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3359
3360 // Pump the message loop to get the request started.
3361 base::RunLoop().RunUntilIdle();
3362 // Explicitly confirm the handshake.
3363 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523364 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173365
3366 // Run the QUIC session to completion.
3367 quic_task_runner_->RunUntilIdle();
3368 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3369
3370 ExpectQuicAlternateProtocolMapping();
3371
3372 // Let the transaction proceed which will result in QUIC being marked
3373 // as broken and the request falling back to TCP.
3374 EXPECT_THAT(callback.WaitForResult(), IsOk());
3375
3376 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3377 ASSERT_FALSE(http_data.AllReadDataConsumed());
3378
3379 // Read the response body over TCP.
3380 CheckResponseData(&trans, "hello world");
3381 ExpectBrokenAlternateProtocolMapping();
3382 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3383 ASSERT_TRUE(http_data.AllReadDataConsumed());
3384}
3385
rch9ecde09b2017-04-08 00:18:233386// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3387// connection times out, then QUIC will be marked as broken but the request
3388// will not be retried over TCP.
3389TEST_P(QuicNetworkTransactionTest,
3390 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413391 session_params_.mark_quic_broken_when_network_blackholes = true;
3392 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233393
3394 // The request will initially go out over QUIC.
3395 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523396 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133397 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233398 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3399
3400 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523401 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3402 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433403 quic_data.AddWrite(SYNCHRONOUS,
3404 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333405 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3406 true, priority, GetRequestHeaders("GET", "https", "/"),
3407 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233408
3409 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523410 quic::QuicStreamOffset settings_offset = header_stream_offset;
3411 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433412 quic_data.AddWrite(SYNCHRONOUS,
3413 client_maker_.MakeInitialSettingsPacketAndSaveData(
3414 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233415
Zhongyi Shi32f2fd02018-04-16 18:23:433416 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333417 1, GetNthClientInitiatedBidirectionalStreamId(0),
3418 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433419 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523420 quic_data.AddWrite(
3421 SYNCHRONOUS,
3422 ConstructClientAckPacket(3, 1, 1, 1,
3423 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233424
3425 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523426 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093427 SYNCHRONOUS, client_maker_.MakeDataPacket(
3428 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3429 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233430 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093431 quic_data.AddWrite(
3432 SYNCHRONOUS, client_maker_.MakeDataPacket(
3433 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3434 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233435 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523436 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093437 SYNCHRONOUS, client_maker_.MakeDataPacket(
3438 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3439 false, 0, request_data));
3440 quic_data.AddWrite(
3441 SYNCHRONOUS, client_maker_.MakeDataPacket(
3442 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3443 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233444 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523445 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093446 SYNCHRONOUS, client_maker_.MakeDataPacket(
3447 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3448 false, 0, request_data));
3449 quic_data.AddWrite(
3450 SYNCHRONOUS, client_maker_.MakeDataPacket(
3451 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3452 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233453 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523454 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093455 SYNCHRONOUS, client_maker_.MakeDataPacket(
3456 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3457 false, 0, request_data));
3458 quic_data.AddWrite(
3459 SYNCHRONOUS, client_maker_.MakeDataPacket(
3460 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3461 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233462
Michael Warres112212822018-12-26 17:51:063463 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183464 quic_fix_time_of_first_packet_sent_after_receiving)) {
3465 quic_data.AddWrite(
3466 SYNCHRONOUS,
3467 client_maker_.MakeAckAndConnectionClosePacket(
3468 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3469 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3470
3471 } else {
3472 quic_data.AddWrite(
3473 SYNCHRONOUS,
3474 client_maker_.MakeAckAndConnectionClosePacket(
3475 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3476 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3477 }
Fan Yang928f1632017-12-14 18:55:223478
rch9ecde09b2017-04-08 00:18:233479 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3480 quic_data.AddRead(ASYNC, OK);
3481 quic_data.AddSocketDataToFactory(&socket_factory_);
3482
3483 // In order for a new QUIC session to be established via alternate-protocol
3484 // without racing an HTTP connection, we need the host resolution to happen
3485 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3486 // connection to the the server, in this test we require confirmation
3487 // before encrypting so the HTTP job will still start.
3488 host_resolver_.set_synchronous_mode(true);
3489 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3490 "");
3491 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3492 AddressList address;
3493 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583494 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3495 CompletionOnceCallback(), &request,
3496 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413497 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233498
3499 CreateSession();
3500 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553501 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233502 QuicStreamFactoryPeer::SetAlarmFactory(
3503 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193504 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553505 &clock_));
rch9ecde09b2017-04-08 00:18:233506
Ryan Hamilton9835e662018-08-02 05:36:273507 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233508
3509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3510 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413511 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3513
3514 // Pump the message loop to get the request started.
3515 base::RunLoop().RunUntilIdle();
3516 // Explicitly confirm the handshake.
3517 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523518 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233519
3520 // Pump the message loop to get the request started.
3521 base::RunLoop().RunUntilIdle();
3522
3523 // Run the QUIC session to completion.
3524 quic_task_runner_->RunUntilIdle();
3525 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3526
3527 // Let the transaction proceed which will result in QUIC being marked
3528 // as broken and the request falling back to TCP.
3529 EXPECT_THAT(callback.WaitForResult(), IsOk());
3530
3531 ExpectBrokenAlternateProtocolMapping();
3532 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3533
3534 std::string response_data;
3535 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3536 IsError(ERR_QUIC_PROTOCOL_ERROR));
3537}
3538
3539// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3540// connection RTOs, then QUIC will be marked as broken and the request retried
3541// over TCP.
3542TEST_P(QuicNetworkTransactionTest,
3543 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413544 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523545 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233546
3547 // The request will initially go out over QUIC.
3548 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523549 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133550 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233551 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3552
3553 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523554 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3555 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433556 quic_data.AddWrite(SYNCHRONOUS,
3557 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333558 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3559 true, priority, GetRequestHeaders("GET", "https", "/"),
3560 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233561
3562 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523563 quic::QuicStreamOffset settings_offset = header_stream_offset;
3564 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433565 quic_data.AddWrite(SYNCHRONOUS,
3566 client_maker_.MakeInitialSettingsPacketAndSaveData(
3567 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233568 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093569 quic_data.AddWrite(SYNCHRONOUS,
3570 client_maker_.MakeDataPacket(
3571 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3572 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233573 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093574 quic_data.AddWrite(SYNCHRONOUS,
3575 client_maker_.MakeDataPacket(
3576 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3577 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233578 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093579 quic_data.AddWrite(SYNCHRONOUS,
3580 client_maker_.MakeDataPacket(
3581 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3582 false, 0, request_data));
3583 quic_data.AddWrite(SYNCHRONOUS,
3584 client_maker_.MakeDataPacket(
3585 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3586 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233587 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093588 quic_data.AddWrite(SYNCHRONOUS,
3589 client_maker_.MakeDataPacket(
3590 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3591 false, 0, request_data));
3592 quic_data.AddWrite(SYNCHRONOUS,
3593 client_maker_.MakeDataPacket(
3594 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3595 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233596 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093597 quic_data.AddWrite(SYNCHRONOUS,
3598 client_maker_.MakeDataPacket(
3599 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3600 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523601 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093602 SYNCHRONOUS, client_maker_.MakeDataPacket(
3603 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3604 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233605 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523606 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093607 SYNCHRONOUS, client_maker_.MakeDataPacket(
3608 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3609 false, 0, request_data));
3610 quic_data.AddWrite(
3611 SYNCHRONOUS, client_maker_.MakeDataPacket(
3612 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3613 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233614
Zhongyi Shi32f2fd02018-04-16 18:23:433615 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523616 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433617 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233618
3619 quic_data.AddRead(ASYNC, OK);
3620 quic_data.AddSocketDataToFactory(&socket_factory_);
3621
3622 // After that fails, it will be resent via TCP.
3623 MockWrite http_writes[] = {
3624 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3625 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3626 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3627
3628 MockRead http_reads[] = {
3629 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3630 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3631 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013632 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233633 socket_factory_.AddSocketDataProvider(&http_data);
3634 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3635
3636 // In order for a new QUIC session to be established via alternate-protocol
3637 // without racing an HTTP connection, we need the host resolution to happen
3638 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3639 // connection to the the server, in this test we require confirmation
3640 // before encrypting so the HTTP job will still start.
3641 host_resolver_.set_synchronous_mode(true);
3642 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3643 "");
3644 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3645 AddressList address;
3646 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583647 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3648 CompletionOnceCallback(), &request,
3649 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413650 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233651
3652 CreateSession();
3653 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553654 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233655 QuicStreamFactoryPeer::SetAlarmFactory(
3656 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193657 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553658 &clock_));
rch9ecde09b2017-04-08 00:18:233659
Ryan Hamilton9835e662018-08-02 05:36:273660 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233661
3662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3663 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413664 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3666
3667 // Pump the message loop to get the request started.
3668 base::RunLoop().RunUntilIdle();
3669 // Explicitly confirm the handshake.
3670 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523671 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233672
3673 // Run the QUIC session to completion.
3674 quic_task_runner_->RunUntilIdle();
3675 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3676
3677 // Let the transaction proceed which will result in QUIC being marked
3678 // as broken and the request falling back to TCP.
3679 EXPECT_THAT(callback.WaitForResult(), IsOk());
3680
3681 ExpectBrokenAlternateProtocolMapping();
3682 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3683 ASSERT_FALSE(http_data.AllReadDataConsumed());
3684
3685 // Read the response body over TCP.
3686 CheckResponseData(&trans, "hello world");
3687 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3688 ASSERT_TRUE(http_data.AllReadDataConsumed());
3689}
3690
3691// Verify that if a QUIC connection RTOs, while there are no active streams
3692// QUIC will be marked as broken.
3693TEST_P(QuicNetworkTransactionTest,
3694 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413695 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523696 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233697
3698 // The request will initially go out over QUIC.
3699 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523700 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133701 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233702 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3703
3704 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523705 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3706 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433707 quic_data.AddWrite(SYNCHRONOUS,
3708 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333709 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3710 true, priority, GetRequestHeaders("GET", "https", "/"),
3711 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233712
3713 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523714 quic::QuicStreamOffset settings_offset = header_stream_offset;
3715 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433716 quic_data.AddWrite(SYNCHRONOUS,
3717 client_maker_.MakeInitialSettingsPacketAndSaveData(
3718 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233719
Fan Yang32c5a112018-12-10 20:06:333720 quic_data.AddWrite(SYNCHRONOUS,
3721 client_maker_.MakeRstPacket(
3722 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3723 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233724 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093725 quic_data.AddWrite(SYNCHRONOUS,
3726 client_maker_.MakeDataPacket(
3727 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3728 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233729 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093730 quic_data.AddWrite(SYNCHRONOUS,
3731 client_maker_.MakeDataPacket(
3732 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3733 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233734 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333735 quic_data.AddWrite(SYNCHRONOUS,
3736 client_maker_.MakeRstPacket(
3737 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3738 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093739 quic_data.AddWrite(SYNCHRONOUS,
3740 client_maker_.MakeDataPacket(
3741 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3742 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233743 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093744 quic_data.AddWrite(SYNCHRONOUS,
3745 client_maker_.MakeDataPacket(
3746 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3747 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333748 quic_data.AddWrite(SYNCHRONOUS,
3749 client_maker_.MakeRstPacket(
3750 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3751 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233752 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523753 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093754 SYNCHRONOUS, client_maker_.MakeDataPacket(
3755 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3756 false, 0, request_data));
3757 quic_data.AddWrite(
3758 SYNCHRONOUS, client_maker_.MakeDataPacket(
3759 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3760 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233761 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433762 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333763 SYNCHRONOUS, client_maker_.MakeRstPacket(
3764 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3765 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523766 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093767 SYNCHRONOUS, client_maker_.MakeDataPacket(
3768 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3769 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233770 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433771 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523772 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433773 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233774
3775 quic_data.AddRead(ASYNC, OK);
3776 quic_data.AddSocketDataToFactory(&socket_factory_);
3777
3778 // In order for a new QUIC session to be established via alternate-protocol
3779 // without racing an HTTP connection, we need the host resolution to happen
3780 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3781 // connection to the the server, in this test we require confirmation
3782 // before encrypting so the HTTP job will still start.
3783 host_resolver_.set_synchronous_mode(true);
3784 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3785 "");
3786 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3787 AddressList address;
3788 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583789 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3790 CompletionOnceCallback(), &request,
3791 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413792 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233793
3794 CreateSession();
3795 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553796 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233797 QuicStreamFactoryPeer::SetAlarmFactory(
3798 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193799 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553800 &clock_));
rch9ecde09b2017-04-08 00:18:233801
Ryan Hamilton9835e662018-08-02 05:36:273802 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233803
Jeremy Roman0579ed62017-08-29 15:56:193804 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233805 session_.get());
3806 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413807 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233808 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3809
3810 // Pump the message loop to get the request started.
3811 base::RunLoop().RunUntilIdle();
3812 // Explicitly confirm the handshake.
3813 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523814 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233815
3816 // Now cancel the request.
3817 trans.reset();
3818
3819 // Run the QUIC session to completion.
3820 quic_task_runner_->RunUntilIdle();
3821
3822 ExpectBrokenAlternateProtocolMapping();
3823
3824 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3825}
3826
rch2f2991c2017-04-13 19:28:173827// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3828// protocol error occurs after the handshake is confirmed, the request
3829// retried over TCP and the QUIC will be marked as broken.
3830TEST_P(QuicNetworkTransactionTest,
3831 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413832 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173833
3834 // The request will initially go out over QUIC.
3835 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523836 quic::QuicStreamOffset header_stream_offset = 0;
3837 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3838 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433839 quic_data.AddWrite(
3840 SYNCHRONOUS,
3841 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333842 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433843 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523844 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433845 quic_data.AddWrite(SYNCHRONOUS,
3846 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173847 // Peer sending data from an non-existing stream causes this end to raise
3848 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333849 quic_data.AddRead(
3850 ASYNC, ConstructServerRstPacket(
3851 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3852 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173853 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433854 quic_data.AddWrite(SYNCHRONOUS,
3855 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523856 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3857 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173858 quic_data.AddSocketDataToFactory(&socket_factory_);
3859
3860 // After that fails, it will be resent via TCP.
3861 MockWrite http_writes[] = {
3862 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3863 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3864 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3865
3866 MockRead http_reads[] = {
3867 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3868 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3869 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013870 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173871 socket_factory_.AddSocketDataProvider(&http_data);
3872 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3873
3874 // In order for a new QUIC session to be established via alternate-protocol
3875 // without racing an HTTP connection, we need the host resolution to happen
3876 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3877 // connection to the the server, in this test we require confirmation
3878 // before encrypting so the HTTP job will still start.
3879 host_resolver_.set_synchronous_mode(true);
3880 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3881 "");
3882 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3883 AddressList address;
3884 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583885 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3886 CompletionOnceCallback(), &request,
3887 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413888 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173889
3890 CreateSession();
3891
Ryan Hamilton9835e662018-08-02 05:36:273892 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173893
3894 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3895 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413896 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173897 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3898
3899 // Pump the message loop to get the request started.
3900 base::RunLoop().RunUntilIdle();
3901 // Explicitly confirm the handshake.
3902 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523903 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173904
3905 // Run the QUIC session to completion.
3906 base::RunLoop().RunUntilIdle();
3907 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3908
3909 ExpectQuicAlternateProtocolMapping();
3910
3911 // Let the transaction proceed which will result in QUIC being marked
3912 // as broken and the request falling back to TCP.
3913 EXPECT_THAT(callback.WaitForResult(), IsOk());
3914
3915 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3916 ASSERT_FALSE(http_data.AllReadDataConsumed());
3917
3918 // Read the response body over TCP.
3919 CheckResponseData(&trans, "hello world");
3920 ExpectBrokenAlternateProtocolMapping();
3921 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3922 ASSERT_TRUE(http_data.AllReadDataConsumed());
3923}
3924
rch30943ee2017-06-12 21:28:443925// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3926// request is reset from, then QUIC will be marked as broken and the request
3927// retried over TCP.
3928TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443929 // The request will initially go out over QUIC.
3930 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523931 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133932 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443933 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3934
3935 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523936 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3937 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433938 quic_data.AddWrite(SYNCHRONOUS,
3939 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333940 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3941 true, priority, GetRequestHeaders("GET", "https", "/"),
3942 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443943
3944 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523945 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3946 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433947 quic_data.AddWrite(SYNCHRONOUS,
3948 client_maker_.MakeInitialSettingsPacketAndSaveData(
3949 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443950
Fan Yang32c5a112018-12-10 20:06:333951 quic_data.AddRead(ASYNC,
3952 ConstructServerRstPacket(
3953 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3954 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443955
3956 quic_data.AddRead(ASYNC, OK);
3957 quic_data.AddSocketDataToFactory(&socket_factory_);
3958
3959 // After that fails, it will be resent via TCP.
3960 MockWrite http_writes[] = {
3961 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3962 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3963 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3964
3965 MockRead http_reads[] = {
3966 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3967 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3968 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013969 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443970 socket_factory_.AddSocketDataProvider(&http_data);
3971 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3972
3973 // In order for a new QUIC session to be established via alternate-protocol
3974 // without racing an HTTP connection, we need the host resolution to happen
3975 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3976 // connection to the the server, in this test we require confirmation
3977 // before encrypting so the HTTP job will still start.
3978 host_resolver_.set_synchronous_mode(true);
3979 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3980 "");
3981 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3982 AddressList address;
3983 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583984 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3985 CompletionOnceCallback(), &request,
3986 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413987 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443988
3989 CreateSession();
3990
Ryan Hamilton9835e662018-08-02 05:36:273991 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443992
3993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3994 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413995 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3997
3998 // Pump the message loop to get the request started.
3999 base::RunLoop().RunUntilIdle();
4000 // Explicitly confirm the handshake.
4001 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524002 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:444003
4004 // Run the QUIC session to completion.
4005 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4006
4007 ExpectQuicAlternateProtocolMapping();
4008
4009 // Let the transaction proceed which will result in QUIC being marked
4010 // as broken and the request falling back to TCP.
4011 EXPECT_THAT(callback.WaitForResult(), IsOk());
4012
4013 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4014 ASSERT_FALSE(http_data.AllReadDataConsumed());
4015
4016 // Read the response body over TCP.
4017 CheckResponseData(&trans, "hello world");
4018 ExpectBrokenAlternateProtocolMapping();
4019 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4020 ASSERT_TRUE(http_data.AllReadDataConsumed());
4021}
4022
Ryan Hamilton6c2a2a82017-12-15 02:06:284023// Verify that when an origin has two alt-svc advertisements, one local and one
4024// remote, that when the local is broken the request will go over QUIC via
4025// the remote Alt-Svc.
4026// This is a regression test for crbug/825646.
4027TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
4028 session_params_.quic_allow_remote_alt_svc = true;
4029
4030 GURL origin1 = request_.url; // mail.example.org
4031 GURL origin2("https://www.example.org/");
4032 ASSERT_NE(origin1.host(), origin2.host());
4033
4034 scoped_refptr<X509Certificate> cert(
4035 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244036 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4037 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284038
4039 ProofVerifyDetailsChromium verify_details;
4040 verify_details.cert_verify_result.verified_cert = cert;
4041 verify_details.cert_verify_result.is_issued_by_known_root = true;
4042 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4043
4044 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524045 quic::QuicStreamOffset request_header_offset(0);
4046 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:284047 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434048 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4049 mock_quic_data.AddWrite(
4050 SYNCHRONOUS,
4051 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334052 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434053 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4054 mock_quic_data.AddRead(
4055 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334056 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434057 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414058 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434059 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334060 ASYNC, ConstructServerDataPacket(
4061 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414062 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434063 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284064 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4065 mock_quic_data.AddRead(ASYNC, 0); // EOF
4066
4067 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4068 MockQuicData mock_quic_data2;
4069 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4070 AddHangingNonAlternateProtocolSocketData();
4071
4072 CreateSession();
4073
4074 // Set up alternative service for |origin1|.
4075 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4076 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4077 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4078 AlternativeServiceInfoVector alternative_services;
4079 alternative_services.push_back(
4080 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4081 local_alternative, expiration,
4082 session_->params().quic_supported_versions));
4083 alternative_services.push_back(
4084 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4085 remote_alternative, expiration,
4086 session_->params().quic_supported_versions));
4087 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4088 alternative_services);
4089
4090 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4091
4092 SendRequestAndExpectQuicResponse("hello!");
4093}
4094
rch30943ee2017-06-12 21:28:444095// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4096// request is reset from, then QUIC will be marked as broken and the request
4097// retried over TCP. Then, subsequent requests will go over a new QUIC
4098// connection instead of going back to the broken QUIC connection.
4099// This is a regression tests for crbug/731303.
4100TEST_P(QuicNetworkTransactionTest,
4101 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344102 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444103
4104 GURL origin1 = request_.url;
4105 GURL origin2("https://www.example.org/");
4106 ASSERT_NE(origin1.host(), origin2.host());
4107
4108 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524109 quic::QuicStreamOffset request_header_offset(0);
4110 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444111
4112 scoped_refptr<X509Certificate> cert(
4113 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244114 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4115 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444116
4117 ProofVerifyDetailsChromium verify_details;
4118 verify_details.cert_verify_result.verified_cert = cert;
4119 verify_details.cert_verify_result.is_issued_by_known_root = true;
4120 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4121
4122 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434123 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444124 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434125 mock_quic_data.AddWrite(
4126 SYNCHRONOUS,
4127 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334128 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434129 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4130 mock_quic_data.AddRead(
4131 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334132 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434133 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414134 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434135 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334136 ASYNC, ConstructServerDataPacket(
4137 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414138 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434139 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444140
4141 // Second request will go over the pooled QUIC connection, but will be
4142 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054143 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174144 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4145 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054146 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174147 QuicTestPacketMaker server_maker2(
4148 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4149 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434150 mock_quic_data.AddWrite(
4151 SYNCHRONOUS,
4152 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334153 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434154 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334155 GetNthClientInitiatedBidirectionalStreamId(0),
4156 &request_header_offset));
4157 mock_quic_data.AddRead(
4158 ASYNC, ConstructServerRstPacket(
4159 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4160 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444161 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4162 mock_quic_data.AddRead(ASYNC, 0); // EOF
4163
4164 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4165
4166 // After that fails, it will be resent via TCP.
4167 MockWrite http_writes[] = {
4168 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4169 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4170 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4171
4172 MockRead http_reads[] = {
4173 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4174 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4175 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014176 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444177 socket_factory_.AddSocketDataProvider(&http_data);
4178 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4179
Ryan Hamilton6c2a2a82017-12-15 02:06:284180 // Then the next request to the second origin will be sent over TCP.
4181 socket_factory_.AddSocketDataProvider(&http_data);
4182 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444183
4184 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564185 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4186 QuicStreamFactoryPeer::SetAlarmFactory(
4187 session_->quic_stream_factory(),
4188 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4189 &clock_));
rch30943ee2017-06-12 21:28:444190
4191 // Set up alternative service for |origin1|.
4192 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244193 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214194 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244195 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444196 supported_versions_);
rch30943ee2017-06-12 21:28:444197
4198 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244199 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214200 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244201 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444202 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344203
rch30943ee2017-06-12 21:28:444204 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524205 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444206 SendRequestAndExpectQuicResponse("hello!");
4207
4208 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524209 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444210 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4211 request_.url = origin2;
4212 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284213 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244214 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284215 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244216 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444217
4218 // The third request should use a new QUIC connection, not the broken
4219 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284220 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444221}
4222
bnc8be55ebb2015-10-30 14:12:074223TEST_P(QuicNetworkTransactionTest,
4224 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4225 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444226 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074227 MockRead http_reads[] = {
4228 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4229 MockRead("hello world"),
4230 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4231 MockRead(ASYNC, OK)};
4232
Ryan Sleevib8d7ea02018-05-07 20:01:014233 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074234 socket_factory_.AddSocketDataProvider(&http_data);
4235 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4236 socket_factory_.AddSocketDataProvider(&http_data);
4237 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4238
rch3f4b8452016-02-23 16:59:324239 CreateSession();
bnc8be55ebb2015-10-30 14:12:074240
4241 SendRequestAndExpectHttpResponse("hello world");
4242 SendRequestAndExpectHttpResponse("hello world");
4243}
4244
Xida Chen9bfe0b62018-04-24 19:52:214245// When multiple alternative services are advertised, HttpStreamFactory should
4246// select the alternative service which uses existing QUIC session if available.
4247// If no existing QUIC session can be used, use the first alternative service
4248// from the list.
zhongyi32569c62016-01-08 02:54:304249TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344250 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524251 MockRead http_reads[] = {
4252 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294253 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524254 MockRead("hello world"),
4255 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4256 MockRead(ASYNC, OK)};
4257
Ryan Sleevib8d7ea02018-05-07 20:01:014258 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524259 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084260 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564261 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524262
Ryan Hamilton8d9ee76e2018-05-29 23:52:524263 quic::QuicStreamOffset request_header_offset = 0;
4264 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304265 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294266 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304267 // alternative service list.
bncc958faa2015-07-31 18:14:524268 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364269 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434270 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4271 mock_quic_data.AddWrite(
4272 SYNCHRONOUS,
4273 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334274 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434275 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304276
4277 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294278 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4279 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434280 mock_quic_data.AddRead(
4281 ASYNC,
4282 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334283 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434284 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414285 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434286 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334287 ASYNC, ConstructServerDataPacket(
4288 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414289 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434290 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304291
4292 // Second QUIC request data.
4293 // Connection pooling, using existing session, no need to include version
4294 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584295 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334296 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4297 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4298 true, GetRequestHeaders("GET", "https", "/"),
4299 GetNthClientInitiatedBidirectionalStreamId(0),
4300 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434301 mock_quic_data.AddRead(
4302 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334303 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434304 GetResponseHeaders("200 OK"), &response_header_offset));
4305 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334306 ASYNC, ConstructServerDataPacket(
4307 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414308 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434309 mock_quic_data.AddWrite(
4310 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524311 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594312 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524313
4314 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4315
rtennetib8e80fb2016-05-16 00:12:094316 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324317 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564318 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4319 QuicStreamFactoryPeer::SetAlarmFactory(
4320 session_->quic_stream_factory(),
4321 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4322 &clock_));
bncc958faa2015-07-31 18:14:524323
4324 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304325
bnc359ed2a2016-04-29 20:43:454326 SendRequestAndExpectQuicResponse("hello!");
4327 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304328}
4329
tbansal6490783c2016-09-20 17:55:274330// Check that an existing QUIC connection to an alternative proxy server is
4331// used.
4332TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4333 base::HistogramTester histogram_tester;
4334
Ryan Hamilton8d9ee76e2018-05-29 23:52:524335 quic::QuicStreamOffset request_header_offset = 0;
4336 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274337 // First QUIC request data.
4338 // Open a session to foo.example.org:443 using the first entry of the
4339 // alternative service list.
4340 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364341 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434342 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4343 mock_quic_data.AddWrite(
4344 SYNCHRONOUS,
4345 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334346 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434347 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274348
4349 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434350 mock_quic_data.AddRead(
4351 ASYNC,
4352 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334353 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434354 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414355 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434356 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334357 ASYNC, ConstructServerDataPacket(
4358 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414359 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434360 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274361
4362 // Second QUIC request data.
4363 // Connection pooling, using existing session, no need to include version
4364 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274365 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334366 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4367 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4368 true, GetRequestHeaders("GET", "http", "/"),
4369 GetNthClientInitiatedBidirectionalStreamId(0),
4370 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434371 mock_quic_data.AddRead(
4372 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334373 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434374 GetResponseHeaders("200 OK"), &response_header_offset));
4375 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334376 ASYNC, ConstructServerDataPacket(
4377 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414378 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434379 mock_quic_data.AddWrite(
4380 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274381 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4382 mock_quic_data.AddRead(ASYNC, 0); // EOF
4383
4384 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4385
4386 AddHangingNonAlternateProtocolSocketData();
4387
4388 TestProxyDelegate test_proxy_delegate;
4389
Lily Houghton8c2f97d2018-01-22 05:06:594390 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494391 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274392
4393 test_proxy_delegate.set_alternative_proxy_server(
4394 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524395 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274396
4397 request_.url = GURL("http://mail.example.org/");
4398
4399 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564400 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4401 QuicStreamFactoryPeer::SetAlarmFactory(
4402 session_->quic_stream_factory(),
4403 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4404 &clock_));
tbansal6490783c2016-09-20 17:55:274405
4406 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4407 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4408 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4409 1);
4410
4411 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4412 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4413 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4414 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4415 1);
4416}
4417
Ryan Hamilton8d9ee76e2018-05-29 23:52:524418// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454419// even if alternative service destination is different.
4420TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344421 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304422 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524423 quic::QuicStreamOffset request_header_offset(0);
4424 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454425
rch5cb522462017-04-25 20:18:364426 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434427 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454428 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434429 mock_quic_data.AddWrite(
4430 SYNCHRONOUS,
4431 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334432 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434433 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4434 mock_quic_data.AddRead(
4435 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334436 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434437 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414438 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334440 ASYNC, ConstructServerDataPacket(
4441 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414442 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434443 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304444
bnc359ed2a2016-04-29 20:43:454445 // Second request.
alyssar2adf3ac2016-05-03 17:12:584446 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334447 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4448 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4449 true, GetRequestHeaders("GET", "https", "/"),
4450 GetNthClientInitiatedBidirectionalStreamId(0),
4451 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434452 mock_quic_data.AddRead(
4453 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334454 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434455 GetResponseHeaders("200 OK"), &response_header_offset));
4456 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334457 ASYNC, ConstructServerDataPacket(
4458 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414459 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434460 mock_quic_data.AddWrite(
4461 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304462 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4463 mock_quic_data.AddRead(ASYNC, 0); // EOF
4464
4465 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454466
4467 AddHangingNonAlternateProtocolSocketData();
4468 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304469
rch3f4b8452016-02-23 16:59:324470 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564471 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4472 QuicStreamFactoryPeer::SetAlarmFactory(
4473 session_->quic_stream_factory(),
4474 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4475 &clock_));
zhongyi32569c62016-01-08 02:54:304476
bnc359ed2a2016-04-29 20:43:454477 const char destination1[] = "first.example.com";
4478 const char destination2[] = "second.example.com";
4479
4480 // Set up alternative service entry to destination1.
4481 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214482 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454483 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214484 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444485 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454486 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524487 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454488 SendRequestAndExpectQuicResponse("hello!");
4489
4490 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214491 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214492 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444493 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524494 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454495 // even though alternative service destination is different.
4496 SendRequestAndExpectQuicResponse("hello!");
4497}
4498
4499// Pool to existing session with matching destination and matching certificate
4500// even if origin is different, and even if the alternative service with
4501// matching destination is not the first one on the list.
4502TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344503 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454504 GURL origin1 = request_.url;
4505 GURL origin2("https://www.example.org/");
4506 ASSERT_NE(origin1.host(), origin2.host());
4507
4508 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524509 quic::QuicStreamOffset request_header_offset(0);
4510 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454511
rch5cb522462017-04-25 20:18:364512 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434513 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454514 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434515 mock_quic_data.AddWrite(
4516 SYNCHRONOUS,
4517 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334518 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434519 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4520 mock_quic_data.AddRead(
4521 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334522 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434523 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414524 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434525 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334526 ASYNC, ConstructServerDataPacket(
4527 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414528 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434529 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454530
4531 // Second request.
Yixin Wang079ad542018-01-11 04:06:054532 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174533 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4534 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054535 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174536 QuicTestPacketMaker server_maker2(
4537 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4538 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584539 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434540 SYNCHRONOUS,
4541 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334542 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434543 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334544 GetNthClientInitiatedBidirectionalStreamId(0),
4545 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434546 mock_quic_data.AddRead(
4547 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334548 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434549 GetResponseHeaders("200 OK"), &response_header_offset));
4550 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334551 ASYNC, ConstructServerDataPacket(
4552 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414553 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434554 mock_quic_data.AddWrite(
4555 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454556 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4557 mock_quic_data.AddRead(ASYNC, 0); // EOF
4558
4559 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4560
4561 AddHangingNonAlternateProtocolSocketData();
4562 AddHangingNonAlternateProtocolSocketData();
4563
4564 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564565 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4566 QuicStreamFactoryPeer::SetAlarmFactory(
4567 session_->quic_stream_factory(),
4568 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4569 &clock_));
bnc359ed2a2016-04-29 20:43:454570
4571 const char destination1[] = "first.example.com";
4572 const char destination2[] = "second.example.com";
4573
4574 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214575 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454576 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214577 http_server_properties_.SetQuicAlternativeService(
4578 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444579 supported_versions_);
bnc359ed2a2016-04-29 20:43:454580
4581 // Set up multiple alternative service entries for |origin2|,
4582 // the first one with a different destination as for |origin1|,
4583 // the second one with the same. The second one should be used,
4584 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214585 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454586 AlternativeServiceInfoVector alternative_services;
4587 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214588 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4589 alternative_service2, expiration,
4590 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454591 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214592 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4593 alternative_service1, expiration,
4594 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454595 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4596 alternative_services);
bnc359ed2a2016-04-29 20:43:454597 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524598 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454599 SendRequestAndExpectQuicResponse("hello!");
4600
4601 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524602 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454603 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584604
bnc359ed2a2016-04-29 20:43:454605 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304606}
4607
4608// Multiple origins have listed the same alternative services. When there's a
4609// existing QUIC session opened by a request to other origin,
4610// if the cert is valid, should select this QUIC session to make the request
4611// if this is also the first existing QUIC session.
4612TEST_P(QuicNetworkTransactionTest,
4613 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344614 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294615 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304616
rch9ae5b3b2016-02-11 00:36:294617 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304618 MockRead http_reads[] = {
4619 MockRead("HTTP/1.1 200 OK\r\n"),
4620 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294621 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304622 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4623 MockRead(ASYNC, OK)};
4624
Ryan Sleevib8d7ea02018-05-07 20:01:014625 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304626 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084627 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304628 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4629
4630 // HTTP data for request to mail.example.org.
4631 MockRead http_reads2[] = {
4632 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294633 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304634 MockRead("hello world from mail.example.org"),
4635 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4636 MockRead(ASYNC, OK)};
4637
Ryan Sleevib8d7ea02018-05-07 20:01:014638 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304639 socket_factory_.AddSocketDataProvider(&http_data2);
4640 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4641
Ryan Hamilton8d9ee76e2018-05-29 23:52:524642 quic::QuicStreamOffset request_header_offset = 0;
4643 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304644
Yixin Wang079ad542018-01-11 04:06:054645 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174646 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4647 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054648 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584649 server_maker_.set_hostname("www.example.org");
4650 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304651 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364652 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434653 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304654 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584655 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434656 SYNCHRONOUS,
4657 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334658 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434659 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4660
4661 mock_quic_data.AddRead(
4662 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334663 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434664 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414665 quic::QuicString header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334666 mock_quic_data.AddRead(
4667 ASYNC, ConstructServerDataPacket(
4668 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414669 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434670 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4671 // Second QUIC request data.
4672 mock_quic_data.AddWrite(
4673 SYNCHRONOUS,
4674 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334675 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434676 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334677 GetNthClientInitiatedBidirectionalStreamId(0),
4678 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434679 mock_quic_data.AddRead(
4680 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334681 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434682 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334683 mock_quic_data.AddRead(
4684 ASYNC, ConstructServerDataPacket(
4685 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414686 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434687 mock_quic_data.AddWrite(
4688 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304689 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4690 mock_quic_data.AddRead(ASYNC, 0); // EOF
4691
4692 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304693
rtennetib8e80fb2016-05-16 00:12:094694 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324695 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564696 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4697 QuicStreamFactoryPeer::SetAlarmFactory(
4698 session_->quic_stream_factory(),
4699 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4700 &clock_));
zhongyi32569c62016-01-08 02:54:304701
4702 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294703 request_.url = GURL("https://www.example.org/");
4704 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304705 request_.url = GURL("https://mail.example.org/");
4706 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4707
rch9ae5b3b2016-02-11 00:36:294708 // Open a QUIC session to mail.example.org:443 when making request
4709 // to mail.example.org.
4710 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454711 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304712
rch9ae5b3b2016-02-11 00:36:294713 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304714 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454715 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524716}
4717
4718TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524719 MockRead http_reads[] = {
4720 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564721 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524722 MockRead("hello world"),
4723 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4724 MockRead(ASYNC, OK)};
4725
Ryan Sleevib8d7ea02018-05-07 20:01:014726 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524727 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084728 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564729 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524730
rtennetib8e80fb2016-05-16 00:12:094731 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324732 CreateSession();
bncc958faa2015-07-31 18:14:524733
4734 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454735
4736 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344737 AlternativeServiceInfoVector alternative_service_info_vector =
4738 http_server_properties_.GetAlternativeServiceInfos(http_server);
4739 ASSERT_EQ(1u, alternative_service_info_vector.size());
4740 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544741 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344742 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4743 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4744 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524745}
4746
4747TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524748 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564749 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4750 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524751 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4752 MockRead(ASYNC, OK)};
4753
Ryan Sleevib8d7ea02018-05-07 20:01:014754 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524755 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084756 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564757 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524758
4759 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524760 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364761 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434762 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4763 mock_quic_data.AddWrite(
4764 SYNCHRONOUS,
4765 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334766 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434767 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434768 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334769 ASYNC, ConstructServerResponseHeadersPacket(
4770 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4771 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414772 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334773 mock_quic_data.AddRead(
4774 ASYNC, ConstructServerDataPacket(
4775 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414776 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434777 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524778 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4779 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524780
4781 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4782
rtennetib8e80fb2016-05-16 00:12:094783 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324784 CreateSession();
bncc958faa2015-07-31 18:14:524785
bnc3472afd2016-11-17 15:27:214786 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524787 HostPortPair::FromURL(request_.url));
4788 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4789 alternative_service);
4790 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4791 alternative_service));
4792
4793 SendRequestAndExpectHttpResponse("hello world");
4794 SendRequestAndExpectQuicResponse("hello!");
4795
mmenkee24011922015-12-17 22:12:594796 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524797
4798 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4799 alternative_service));
rchac7f35e2017-03-15 20:42:304800 EXPECT_NE(nullptr,
4801 http_server_properties_.GetServerNetworkStats(
4802 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524803}
4804
bncc958faa2015-07-31 18:14:524805TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524806 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564807 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4808 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524809 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4810 MockRead(ASYNC, OK)};
4811
Ryan Sleevib8d7ea02018-05-07 20:01:014812 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524813 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564814 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524815
4816 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524817 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364818 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434819 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4820 mock_quic_data.AddWrite(
4821 SYNCHRONOUS,
4822 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334823 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434824 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434825 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334826 ASYNC, ConstructServerResponseHeadersPacket(
4827 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4828 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414829 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334830 mock_quic_data.AddRead(
4831 ASYNC, ConstructServerDataPacket(
4832 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414833 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434834 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524835 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4836
4837 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4838
4839 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324840 CreateSession();
bncc958faa2015-07-31 18:14:524841
4842 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4843 SendRequestAndExpectHttpResponse("hello world");
4844}
4845
tbansalc3308d72016-08-27 10:25:044846// Tests that the connection to an HTTPS proxy is raced with an available
4847// alternative proxy server.
4848TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274849 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594850 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494851 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044852
4853 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524854 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364855 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434856 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4857 mock_quic_data.AddWrite(
4858 SYNCHRONOUS,
4859 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334860 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434861 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434862 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334863 ASYNC, ConstructServerResponseHeadersPacket(
4864 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4865 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414866 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334867 mock_quic_data.AddRead(
4868 ASYNC, ConstructServerDataPacket(
4869 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414870 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434871 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044872 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4873 mock_quic_data.AddRead(ASYNC, 0); // EOF
4874
4875 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4876
4877 // There is no need to set up main job, because no attempt will be made to
4878 // speak to the proxy over TCP.
4879 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044880 TestProxyDelegate test_proxy_delegate;
4881 const HostPortPair host_port_pair("mail.example.org", 443);
4882
4883 test_proxy_delegate.set_alternative_proxy_server(
4884 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524885 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044886 CreateSession();
4887 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4888
4889 // The main job needs to hang in order to guarantee that the alternative
4890 // proxy server job will "win".
4891 AddHangingNonAlternateProtocolSocketData();
4892
4893 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4894
4895 // Verify that the alternative proxy server is not marked as broken.
4896 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4897
4898 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594899 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274900
4901 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4902 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4903 1);
tbansalc3308d72016-08-27 10:25:044904}
4905
bnc1c196c6e2016-05-28 13:51:484906TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304907 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274908 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304909
4910 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564911 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294912 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564913 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304914
4915 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564916 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484917 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564918 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304919
Ryan Sleevib8d7ea02018-05-07 20:01:014920 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504921 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084922 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504923 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304924
4925 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454926 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304927 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454928 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304929 };
Ryan Sleevib8d7ea02018-05-07 20:01:014930 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504931 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304932
4933 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014934 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504935 socket_factory_.AddSocketDataProvider(&http_data2);
4936 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304937
bnc912a04b2016-04-20 14:19:504938 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304939
4940 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304941 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174942 ASSERT_TRUE(http_data.AllReadDataConsumed());
4943 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304944
4945 // Now run the second request in which the QUIC socket hangs,
4946 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304947 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454948 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304949
rch37de576c2015-05-17 20:28:174950 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4951 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454952 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304953}
4954
[email protected]1e960032013-12-20 19:00:204955TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204956 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524957 quic::QuicStreamOffset header_stream_offset = 0;
4958 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4959 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434960 mock_quic_data.AddWrite(
4961 SYNCHRONOUS,
4962 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334963 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434964 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434965 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334966 ASYNC, ConstructServerResponseHeadersPacket(
4967 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4968 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414969 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334970 mock_quic_data.AddRead(
4971 ASYNC, ConstructServerDataPacket(
4972 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414973 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434974 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504975 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594976 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484977
rcha5399e02015-04-21 19:32:044978 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484979
rtennetib8e80fb2016-05-16 00:12:094980 // The non-alternate protocol job needs to hang in order to guarantee that
4981 // the alternate-protocol job will "win".
4982 AddHangingNonAlternateProtocolSocketData();
4983
rch3f4b8452016-02-23 16:59:324984 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274985 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194986 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304987
4988 EXPECT_EQ(nullptr,
4989 http_server_properties_.GetServerNetworkStats(
4990 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484991}
4992
[email protected]1e960032013-12-20 19:00:204993TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204994 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524995 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4996 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334997 mock_quic_data.AddWrite(
4998 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4999 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5000 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435001 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335002 ASYNC, ConstructServerResponseHeadersPacket(
5003 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5004 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415005 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335006 mock_quic_data.AddRead(
5007 ASYNC, ConstructServerDataPacket(
5008 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415009 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435010 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:505011 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595012 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045013 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275014
5015 // In order for a new QUIC session to be established via alternate-protocol
5016 // without racing an HTTP connection, we need the host resolution to happen
5017 // synchronously.
5018 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295019 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565020 "");
rch9ae5b3b2016-02-11 00:36:295021 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:275022 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105023 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585024 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5025 CompletionOnceCallback(), &request,
5026 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415027 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:275028
rtennetib8e80fb2016-05-16 00:12:095029 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325030 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275031 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275032 SendRequestAndExpectQuicResponse("hello!");
5033}
5034
[email protected]0fc924b2014-03-31 04:34:155035TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495036 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5037 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155038
5039 // Since we are using a proxy, the QUIC job will not succeed.
5040 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295041 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5042 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565043 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155044
5045 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565046 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485047 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565048 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155049
Ryan Sleevib8d7ea02018-05-07 20:01:015050 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155051 socket_factory_.AddSocketDataProvider(&http_data);
5052
5053 // In order for a new QUIC session to be established via alternate-protocol
5054 // without racing an HTTP connection, we need the host resolution to happen
5055 // synchronously.
5056 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295057 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565058 "");
rch9ae5b3b2016-02-11 00:36:295059 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:155060 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105061 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585062 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5063 CompletionOnceCallback(), &request,
5064 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415065 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:155066
rch9ae5b3b2016-02-11 00:36:295067 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325068 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275069 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155070 SendRequestAndExpectHttpResponse("hello world");
5071}
5072
[email protected]1e960032013-12-20 19:00:205073TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:205074 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525075 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365076 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435077 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5078 mock_quic_data.AddWrite(
5079 SYNCHRONOUS,
5080 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335081 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435082 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435083 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335084 ASYNC, ConstructServerResponseHeadersPacket(
5085 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5086 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415087 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335088 mock_quic_data.AddRead(
5089 ASYNC, ConstructServerDataPacket(
5090 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415091 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435092 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595093 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045094 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125095
rtennetib8e80fb2016-05-16 00:12:095096 // The non-alternate protocol job needs to hang in order to guarantee that
5097 // the alternate-protocol job will "win".
5098 AddHangingNonAlternateProtocolSocketData();
5099
[email protected]11c05872013-08-20 02:04:125100 // In order for a new QUIC session to be established via alternate-protocol
5101 // without racing an HTTP connection, we need the host resolution to happen
5102 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5103 // connection to the the server, in this test we require confirmation
5104 // before encrypting so the HTTP job will still start.
5105 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295106 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565107 "");
rch9ae5b3b2016-02-11 00:36:295108 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:125109 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105110 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585111 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5112 CompletionOnceCallback(), &request,
5113 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415114 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:125115
rch3f4b8452016-02-23 16:59:325116 CreateSession();
[email protected]11c05872013-08-20 02:04:125117 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275118 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125119
bnc691fda62016-08-12 00:43:165120 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125121 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415122 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015123 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125124
5125 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525126 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015127 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505128
bnc691fda62016-08-12 00:43:165129 CheckWasQuicResponse(&trans);
5130 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125131}
5132
Steven Valdez58097ec32018-07-16 18:29:045133TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5134 MockQuicData mock_quic_data;
5135 quic::QuicStreamOffset client_header_stream_offset = 0;
5136 quic::QuicStreamOffset server_header_stream_offset = 0;
5137 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5138 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045139 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335140 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5141 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5142 true, GetRequestHeaders("GET", "https", "/"),
5143 &client_header_stream_offset));
5144 mock_quic_data.AddRead(
5145 ASYNC,
5146 ConstructServerResponseHeadersPacket(
5147 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5148 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5149 mock_quic_data.AddWrite(SYNCHRONOUS,
5150 ConstructClientAckAndRstPacket(
5151 2, GetNthClientInitiatedBidirectionalStreamId(0),
5152 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045153
5154 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5155
5156 spdy::SpdySettingsIR settings_frame;
5157 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5158 quic::kDefaultMaxUncompressedHeaderSize);
5159 spdy::SpdySerializedFrame spdy_frame(
5160 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5161 mock_quic_data.AddWrite(
5162 SYNCHRONOUS,
5163 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385164 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5165 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045166 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5167 client_header_stream_offset += spdy_frame.size();
5168
5169 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335170 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5171 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5172 true, GetRequestHeaders("GET", "https", "/"),
5173 GetNthClientInitiatedBidirectionalStreamId(0),
5174 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045175 mock_quic_data.AddRead(
5176 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335177 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045178 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:415179 quic::QuicString header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045180 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335181 ASYNC, ConstructServerDataPacket(
5182 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415183 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045184 mock_quic_data.AddWrite(
5185 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5186 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5187 mock_quic_data.AddRead(ASYNC, 0); // EOF
5188
5189 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5190
5191 // In order for a new QUIC session to be established via alternate-protocol
5192 // without racing an HTTP connection, we need the host resolution to happen
5193 // synchronously.
5194 host_resolver_.set_synchronous_mode(true);
5195 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5196 "");
5197 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5198 AddressList address;
5199 std::unique_ptr<HostResolver::Request> request;
5200 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5201 CompletionOnceCallback(), &request, net_log_.bound());
5202
5203 AddHangingNonAlternateProtocolSocketData();
5204 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275205 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565206 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5207 QuicStreamFactoryPeer::SetAlarmFactory(
5208 session_->quic_stream_factory(),
5209 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5210 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045211
5212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5213 TestCompletionCallback callback;
5214 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5216
5217 // Confirm the handshake after the 425 Too Early.
5218 base::RunLoop().RunUntilIdle();
5219
5220 // The handshake hasn't been confirmed yet, so the retry should not have
5221 // succeeded.
5222 EXPECT_FALSE(callback.have_result());
5223
5224 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5225 quic::QuicSession::HANDSHAKE_CONFIRMED);
5226
5227 EXPECT_THAT(callback.WaitForResult(), IsOk());
5228 CheckWasQuicResponse(&trans);
5229 CheckResponseData(&trans, "hello!");
5230}
5231
5232TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5233 MockQuicData mock_quic_data;
5234 quic::QuicStreamOffset client_header_stream_offset = 0;
5235 quic::QuicStreamOffset server_header_stream_offset = 0;
5236 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5237 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045238 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335239 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5240 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5241 true, GetRequestHeaders("GET", "https", "/"),
5242 &client_header_stream_offset));
5243 mock_quic_data.AddRead(
5244 ASYNC,
5245 ConstructServerResponseHeadersPacket(
5246 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5247 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5248 mock_quic_data.AddWrite(SYNCHRONOUS,
5249 ConstructClientAckAndRstPacket(
5250 2, GetNthClientInitiatedBidirectionalStreamId(0),
5251 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045252
5253 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5254
5255 spdy::SpdySettingsIR settings_frame;
5256 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5257 quic::kDefaultMaxUncompressedHeaderSize);
5258 spdy::SpdySerializedFrame spdy_frame(
5259 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5260 mock_quic_data.AddWrite(
5261 SYNCHRONOUS,
5262 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385263 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5264 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045265 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5266 client_header_stream_offset += spdy_frame.size();
5267
5268 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335269 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5270 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5271 true, GetRequestHeaders("GET", "https", "/"),
5272 GetNthClientInitiatedBidirectionalStreamId(0),
5273 &client_header_stream_offset));
5274 mock_quic_data.AddRead(
5275 ASYNC,
5276 ConstructServerResponseHeadersPacket(
5277 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5278 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5279 mock_quic_data.AddWrite(SYNCHRONOUS,
5280 ConstructClientAckAndRstPacket(
5281 5, GetNthClientInitiatedBidirectionalStreamId(1),
5282 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045283 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5284 mock_quic_data.AddRead(ASYNC, 0); // EOF
5285
5286 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5287
5288 // In order for a new QUIC session to be established via alternate-protocol
5289 // without racing an HTTP connection, we need the host resolution to happen
5290 // synchronously.
5291 host_resolver_.set_synchronous_mode(true);
5292 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5293 "");
5294 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5295 AddressList address;
5296 std::unique_ptr<HostResolver::Request> request;
5297 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5298 CompletionOnceCallback(), &request, net_log_.bound());
5299
5300 AddHangingNonAlternateProtocolSocketData();
5301 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275302 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565303 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5304 QuicStreamFactoryPeer::SetAlarmFactory(
5305 session_->quic_stream_factory(),
5306 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5307 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045308
5309 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5310 TestCompletionCallback callback;
5311 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5312 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5313
5314 // Confirm the handshake after the 425 Too Early.
5315 base::RunLoop().RunUntilIdle();
5316
5317 // The handshake hasn't been confirmed yet, so the retry should not have
5318 // succeeded.
5319 EXPECT_FALSE(callback.have_result());
5320
5321 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5322 quic::QuicSession::HANDSHAKE_CONFIRMED);
5323
5324 EXPECT_THAT(callback.WaitForResult(), IsOk());
5325 const HttpResponseInfo* response = trans.GetResponseInfo();
5326 ASSERT_TRUE(response != nullptr);
5327 ASSERT_TRUE(response->headers.get() != nullptr);
5328 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5329 EXPECT_TRUE(response->was_fetched_via_spdy);
5330 EXPECT_TRUE(response->was_alpn_negotiated);
5331 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5332 response->connection_info);
5333}
5334
zhongyica364fbb2015-12-12 03:39:125335TEST_P(QuicNetworkTransactionTest,
5336 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485337 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125338 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525339 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365340 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435341 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5342 mock_quic_data.AddWrite(
5343 SYNCHRONOUS,
5344 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335345 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435346 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125347 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525348 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435349 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125350 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5351
5352 // The non-alternate protocol job needs to hang in order to guarantee that
5353 // the alternate-protocol job will "win".
5354 AddHangingNonAlternateProtocolSocketData();
5355
5356 // In order for a new QUIC session to be established via alternate-protocol
5357 // without racing an HTTP connection, we need the host resolution to happen
5358 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5359 // connection to the the server, in this test we require confirmation
5360 // before encrypting so the HTTP job will still start.
5361 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295362 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125363 "");
rch9ae5b3b2016-02-11 00:36:295364 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125365 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105366 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585367 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5368 CompletionOnceCallback(), &request,
5369 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415370 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125371
rch3f4b8452016-02-23 16:59:325372 CreateSession();
zhongyica364fbb2015-12-12 03:39:125373 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275374 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125375
bnc691fda62016-08-12 00:43:165376 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125377 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415378 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015379 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125380
5381 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525382 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015383 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125384
5385 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525386 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125387
bnc691fda62016-08-12 00:43:165388 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125389 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525390 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5391 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125392}
5393
5394TEST_P(QuicNetworkTransactionTest,
5395 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485396 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125397 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525398 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365399 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435400 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5401 mock_quic_data.AddWrite(
5402 SYNCHRONOUS,
5403 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335404 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435405 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215406 // Peer sending data from an non-existing stream causes this end to raise
5407 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335408 mock_quic_data.AddRead(
5409 ASYNC, ConstructServerRstPacket(
5410 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5411 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215412 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525413 mock_quic_data.AddWrite(
5414 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5415 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5416 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125417 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5418
5419 // The non-alternate protocol job needs to hang in order to guarantee that
5420 // the alternate-protocol job will "win".
5421 AddHangingNonAlternateProtocolSocketData();
5422
5423 // In order for a new QUIC session to be established via alternate-protocol
5424 // without racing an HTTP connection, we need the host resolution to happen
5425 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5426 // connection to the the server, in this test we require confirmation
5427 // before encrypting so the HTTP job will still start.
5428 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295429 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125430 "");
rch9ae5b3b2016-02-11 00:36:295431 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125432 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105433 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585434 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5435 CompletionOnceCallback(), &request,
5436 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415437 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125438
rch3f4b8452016-02-23 16:59:325439 CreateSession();
zhongyica364fbb2015-12-12 03:39:125440 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275441 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125442
bnc691fda62016-08-12 00:43:165443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125444 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415445 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125447
5448 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525449 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015450 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125451 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525452 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125453
bnc691fda62016-08-12 00:43:165454 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525455 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125456}
5457
rchcd5f1c62016-06-23 02:43:485458TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5459 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525460 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365461 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435462 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5463 mock_quic_data.AddWrite(
5464 SYNCHRONOUS,
5465 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335466 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435467 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485468 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335469 mock_quic_data.AddRead(
5470 ASYNC, ConstructServerResponseHeadersPacket(
5471 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5472 GetResponseHeaders("200 OK")));
5473 mock_quic_data.AddRead(
5474 ASYNC, ConstructServerRstPacket(
5475 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5476 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435477 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485478 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5479 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5480
5481 // The non-alternate protocol job needs to hang in order to guarantee that
5482 // the alternate-protocol job will "win".
5483 AddHangingNonAlternateProtocolSocketData();
5484
5485 // In order for a new QUIC session to be established via alternate-protocol
5486 // without racing an HTTP connection, we need the host resolution to happen
5487 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5488 // connection to the the server, in this test we require confirmation
5489 // before encrypting so the HTTP job will still start.
5490 host_resolver_.set_synchronous_mode(true);
5491 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5492 "");
5493 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5494 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105495 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585496 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5497 CompletionOnceCallback(), &request,
5498 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415499 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485500
5501 CreateSession();
5502 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275503 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485504
bnc691fda62016-08-12 00:43:165505 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485506 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415507 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015508 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485509
5510 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525511 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485512 // Read the headers.
robpercival214763f2016-07-01 23:27:015513 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485514
bnc691fda62016-08-12 00:43:165515 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485516 ASSERT_TRUE(response != nullptr);
5517 ASSERT_TRUE(response->headers.get() != nullptr);
5518 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5519 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525520 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445521 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5522 response->connection_info);
rchcd5f1c62016-06-23 02:43:485523
5524 std::string response_data;
bnc691fda62016-08-12 00:43:165525 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485526}
5527
5528TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485529 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485530 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525531 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365532 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435533 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5534 mock_quic_data.AddWrite(
5535 SYNCHRONOUS,
5536 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335537 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435538 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335539 mock_quic_data.AddRead(
5540 ASYNC, ConstructServerRstPacket(
5541 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5542 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485543 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5544 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5545
5546 // The non-alternate protocol job needs to hang in order to guarantee that
5547 // the alternate-protocol job will "win".
5548 AddHangingNonAlternateProtocolSocketData();
5549
5550 // In order for a new QUIC session to be established via alternate-protocol
5551 // without racing an HTTP connection, we need the host resolution to happen
5552 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5553 // connection to the the server, in this test we require confirmation
5554 // before encrypting so the HTTP job will still start.
5555 host_resolver_.set_synchronous_mode(true);
5556 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5557 "");
5558 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5559 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105560 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585561 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5562 CompletionOnceCallback(), &request,
5563 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415564 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485565
5566 CreateSession();
5567 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275568 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485569
bnc691fda62016-08-12 00:43:165570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485571 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415572 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485574
5575 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525576 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485577 // Read the headers.
robpercival214763f2016-07-01 23:27:015578 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485579}
5580
[email protected]1e960032013-12-20 19:00:205581TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305582 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525583 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585584 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305585 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505586 MockRead(ASYNC, close->data(), close->length()),
5587 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5588 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305589 };
Ryan Sleevib8d7ea02018-05-07 20:01:015590 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305591 socket_factory_.AddSocketDataProvider(&quic_data);
5592
5593 // Main job which will succeed even though the alternate job fails.
5594 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025595 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5596 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5597 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305598
Ryan Sleevib8d7ea02018-05-07 20:01:015599 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305600 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565601 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305602
rch3f4b8452016-02-23 16:59:325603 CreateSession();
David Schinazic8281052019-01-24 06:14:175604 AddQuicAlternateProtocolMapping(
5605 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195606 SendRequestAndExpectHttpResponse("hello from http");
5607 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305608}
5609
[email protected]1e960032013-12-20 19:00:205610TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595611 // Alternate-protocol job
5612 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025613 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595614 };
Ryan Sleevib8d7ea02018-05-07 20:01:015615 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595616 socket_factory_.AddSocketDataProvider(&quic_data);
5617
5618 // Main job which will succeed even though the alternate job fails.
5619 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025620 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5621 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5622 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595623
Ryan Sleevib8d7ea02018-05-07 20:01:015624 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595625 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565626 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595627
rch3f4b8452016-02-23 16:59:325628 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595629
Ryan Hamilton9835e662018-08-02 05:36:275630 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195631 SendRequestAndExpectHttpResponse("hello from http");
5632 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595633}
5634
[email protected]00c159f2014-05-21 22:38:165635TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535636 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165637 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025638 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165639 };
Ryan Sleevib8d7ea02018-05-07 20:01:015640 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165641 socket_factory_.AddSocketDataProvider(&quic_data);
5642
[email protected]eb71ab62014-05-23 07:57:535643 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165644 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025645 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165646 };
5647
Ryan Sleevib8d7ea02018-05-07 20:01:015648 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165649 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5650 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565651 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165652
rtennetib8e80fb2016-05-16 00:12:095653 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325654 CreateSession();
[email protected]00c159f2014-05-21 22:38:165655
Ryan Hamilton9835e662018-08-02 05:36:275656 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165658 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165659 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5661 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165662 ExpectQuicAlternateProtocolMapping();
5663}
5664
Zhongyi Shia0cef1082017-08-25 01:49:505665TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5666 // Tests that TCP job is delayed and QUIC job does not require confirmation
5667 // if QUIC was recently supported on the same IP on start.
5668
5669 // Set QUIC support on the last IP address, which is same with the local IP
5670 // address. Require confirmation mode will be turned off immediately when
5671 // local IP address is sorted out after we configure the UDP socket.
5672 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5673
5674 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525675 quic::QuicStreamOffset header_stream_offset = 0;
5676 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5677 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435678 mock_quic_data.AddWrite(
5679 SYNCHRONOUS,
5680 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335681 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435682 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435683 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335684 ASYNC, ConstructServerResponseHeadersPacket(
5685 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5686 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415687 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335688 mock_quic_data.AddRead(
5689 ASYNC, ConstructServerDataPacket(
5690 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415691 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435692 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505693 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5694 mock_quic_data.AddRead(ASYNC, 0); // EOF
5695
5696 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5697 // No HTTP data is mocked as TCP job never starts in this case.
5698
5699 CreateSession();
5700 // QuicStreamFactory by default requires confirmation on construction.
5701 session_->quic_stream_factory()->set_require_confirmation(true);
5702
Ryan Hamilton9835e662018-08-02 05:36:275703 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505704
5705 // Stall host resolution so that QUIC job will not succeed synchronously.
5706 // Socket will not be configured immediately and QUIC support is not sorted
5707 // out, TCP job will still be delayed as server properties indicates QUIC
5708 // support on last IP address.
5709 host_resolver_.set_synchronous_mode(false);
5710
5711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5712 TestCompletionCallback callback;
5713 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5714 IsError(ERR_IO_PENDING));
5715 // Complete host resolution in next message loop so that QUIC job could
5716 // proceed.
5717 base::RunLoop().RunUntilIdle();
5718 EXPECT_THAT(callback.WaitForResult(), IsOk());
5719
5720 CheckWasQuicResponse(&trans);
5721 CheckResponseData(&trans, "hello!");
5722}
5723
5724TEST_P(QuicNetworkTransactionTest,
5725 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5726 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5727 // was recently supported on a different IP address on start.
5728
5729 // Set QUIC support on the last IP address, which is different with the local
5730 // IP address. Require confirmation mode will remain when local IP address is
5731 // sorted out after we configure the UDP socket.
5732 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5733
5734 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525735 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505736 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435737 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5738 mock_quic_data.AddWrite(
5739 SYNCHRONOUS,
5740 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335741 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435742 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435743 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335744 ASYNC, ConstructServerResponseHeadersPacket(
5745 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5746 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415747 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335748 mock_quic_data.AddRead(
5749 ASYNC, ConstructServerDataPacket(
5750 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415751 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435752 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505753 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5754 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5755 // No HTTP data is mocked as TCP job will be delayed and never starts.
5756
5757 CreateSession();
5758 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275759 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505760
5761 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5762 // Socket will not be configured immediately and QUIC support is not sorted
5763 // out, TCP job will still be delayed as server properties indicates QUIC
5764 // support on last IP address.
5765 host_resolver_.set_synchronous_mode(false);
5766
5767 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5768 TestCompletionCallback callback;
5769 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5770 IsError(ERR_IO_PENDING));
5771
5772 // Complete host resolution in next message loop so that QUIC job could
5773 // proceed.
5774 base::RunLoop().RunUntilIdle();
5775 // Explicitly confirm the handshake so that QUIC job could succeed.
5776 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525777 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505778 EXPECT_THAT(callback.WaitForResult(), IsOk());
5779
5780 CheckWasQuicResponse(&trans);
5781 CheckResponseData(&trans, "hello!");
5782}
5783
Ryan Hamilton75f197262017-08-17 14:00:075784TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5785 // Test that NetErrorDetails is correctly populated, even if the
5786 // handshake has not yet been confirmed and no stream has been created.
5787
5788 // QUIC job will pause. When resumed, it will fail.
5789 MockQuicData mock_quic_data;
5790 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5791 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5792 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5793
5794 // Main job will also fail.
5795 MockRead http_reads[] = {
5796 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5797 };
5798
Ryan Sleevib8d7ea02018-05-07 20:01:015799 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075800 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5801 socket_factory_.AddSocketDataProvider(&http_data);
5802 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5803
5804 AddHangingNonAlternateProtocolSocketData();
5805 CreateSession();
5806 // Require handshake confirmation to ensure that no QUIC streams are
5807 // created, and to ensure that the TCP job does not wait for the QUIC
5808 // job to fail before it starts.
5809 session_->quic_stream_factory()->set_require_confirmation(true);
5810
Ryan Hamilton9835e662018-08-02 05:36:275811 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075812 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5813 TestCompletionCallback callback;
5814 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5816 // Allow the TCP job to fail.
5817 base::RunLoop().RunUntilIdle();
5818 // Now let the QUIC job fail.
5819 mock_quic_data.Resume();
5820 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5821 ExpectQuicAlternateProtocolMapping();
5822 NetErrorDetails details;
5823 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525824 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075825}
5826
[email protected]1e960032013-12-20 19:00:205827TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455828 // Alternate-protocol job
5829 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025830 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455831 };
Ryan Sleevib8d7ea02018-05-07 20:01:015832 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455833 socket_factory_.AddSocketDataProvider(&quic_data);
5834
[email protected]c92c1b52014-05-31 04:16:065835 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015836 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065837 socket_factory_.AddSocketDataProvider(&quic_data2);
5838
[email protected]4d283b32013-10-17 12:57:275839 // Final job that will proceed when the QUIC job fails.
5840 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025841 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5842 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5843 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275844
Ryan Sleevib8d7ea02018-05-07 20:01:015845 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275846 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565847 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275848
rtennetiafccbc062016-05-16 18:21:145849 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325850 CreateSession();
[email protected]77c6c162013-08-17 02:57:455851
Ryan Hamilton9835e662018-08-02 05:36:275852 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455853
[email protected]4d283b32013-10-17 12:57:275854 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455855
5856 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275857
rch37de576c2015-05-17 20:28:175858 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5859 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455860}
5861
[email protected]93b31772014-06-19 08:03:355862TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035863 // Alternate-protocol job
5864 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595865 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035866 };
Ryan Sleevib8d7ea02018-05-07 20:01:015867 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035868 socket_factory_.AddSocketDataProvider(&quic_data);
5869
5870 // Main job that will proceed when the QUIC job fails.
5871 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025872 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5873 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5874 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035875
Ryan Sleevib8d7ea02018-05-07 20:01:015876 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035877 socket_factory_.AddSocketDataProvider(&http_data);
5878
rtennetib8e80fb2016-05-16 00:12:095879 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325880 CreateSession();
[email protected]65768442014-06-06 23:37:035881
Ryan Hamilton9835e662018-08-02 05:36:275882 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035883
5884 SendRequestAndExpectHttpResponse("hello from http");
5885}
5886
[email protected]eb71ab62014-05-23 07:57:535887TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335888 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015889 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495890 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335891 socket_factory_.AddSocketDataProvider(&quic_data);
5892
5893 // Main job which will succeed even though the alternate job fails.
5894 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025895 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5896 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5897 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335898
Ryan Sleevib8d7ea02018-05-07 20:01:015899 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335900 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565901 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335902
rch3f4b8452016-02-23 16:59:325903 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275904 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335905 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535906
5907 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335908}
5909
[email protected]4fee9672014-01-08 14:47:155910TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155911 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175912 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5913 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045914 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155915
5916 // When the QUIC connection fails, we will try the request again over HTTP.
5917 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485918 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565919 MockRead("hello world"),
5920 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5921 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155922
Ryan Sleevib8d7ea02018-05-07 20:01:015923 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155924 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565925 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155926
5927 // In order for a new QUIC session to be established via alternate-protocol
5928 // without racing an HTTP connection, we need the host resolution to happen
5929 // synchronously.
5930 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295931 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565932 "");
rch9ae5b3b2016-02-11 00:36:295933 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155934 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105935 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585936 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5937 CompletionOnceCallback(), &request,
5938 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415939 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155940
rch3f4b8452016-02-23 16:59:325941 CreateSession();
David Schinazic8281052019-01-24 06:14:175942 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5943 AddQuicAlternateProtocolMapping(
5944 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155945 SendRequestAndExpectHttpResponse("hello world");
5946}
5947
tbansalc3308d72016-08-27 10:25:045948// For an alternative proxy that supports QUIC, test that the request is
5949// successfully fetched by the main job when the alternate proxy job encounters
5950// an error.
5951TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5952 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5953}
5954TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5955 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5956}
5957TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5958 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5959}
5960TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5961 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5962}
5963TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5964 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5965}
5966TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5967 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5968}
5969TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5970 TestAlternativeProxy(ERR_IO_PENDING);
5971}
5972TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5973 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5974}
5975
5976TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5977 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175978 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5979 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335980 mock_quic_data.AddWrite(
5981 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5982 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5983 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435984 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045985 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5986
5987 // When the QUIC connection fails, we will try the request again over HTTP.
5988 MockRead http_reads[] = {
5989 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5990 MockRead("hello world"),
5991 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5992 MockRead(ASYNC, OK)};
5993
Ryan Sleevib8d7ea02018-05-07 20:01:015994 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045995 socket_factory_.AddSocketDataProvider(&http_data);
5996 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5997
5998 TestProxyDelegate test_proxy_delegate;
5999 const HostPortPair host_port_pair("myproxy.org", 443);
6000 test_proxy_delegate.set_alternative_proxy_server(
6001 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6002 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6003
Ramin Halavatica8d5252018-03-12 05:33:496004 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6005 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526006 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046007 request_.url = GURL("http://mail.example.org/");
6008
6009 // In order for a new QUIC session to be established via alternate-protocol
6010 // without racing an HTTP connection, we need the host resolution to happen
6011 // synchronously.
6012 host_resolver_.set_synchronous_mode(true);
6013 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
6014 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
6015 AddressList address;
6016 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:586017 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
6018 CompletionOnceCallback(), &request,
6019 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:416020 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:046021
6022 CreateSession();
David Schinazic8281052019-01-24 06:14:176023 crypto_client_stream_factory_.set_handshake_mode(
6024 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046025 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596026 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166027 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046028}
6029
bnc508835902015-05-12 20:10:296030TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586031 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386032 EXPECT_FALSE(
6033 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296034 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526035 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366036 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436037 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6038 mock_quic_data.AddWrite(
6039 SYNCHRONOUS,
6040 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336041 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436042 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436043 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336044 ASYNC, ConstructServerResponseHeadersPacket(
6045 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6046 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416047 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336048 mock_quic_data.AddRead(
6049 ASYNC, ConstructServerDataPacket(
6050 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416051 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436052 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:506053 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296054 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6055
bncb07c05532015-05-14 19:07:206056 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096057 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326058 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276059 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296060 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386061 EXPECT_TRUE(
6062 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296063}
6064
zhongyi363c91c2017-03-23 23:16:086065// TODO(zhongyi): disabled this broken test as it was not testing the correct
6066// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6067TEST_P(QuicNetworkTransactionTest,
6068 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276069 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596070 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496071 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046072
6073 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046074
6075 test_proxy_delegate.set_alternative_proxy_server(
6076 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526077 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046078
6079 request_.url = GURL("http://mail.example.org/");
6080
6081 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6082 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016083 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046084 socket_factory_.AddSocketDataProvider(&socket_data);
6085
6086 // The non-alternate protocol job needs to hang in order to guarantee that
6087 // the alternate-protocol job will "win".
6088 AddHangingNonAlternateProtocolSocketData();
6089
6090 CreateSession();
6091 request_.method = "POST";
6092 ChunkedUploadDataStream upload_data(0);
6093 upload_data.AppendData("1", 1, true);
6094
6095 request_.upload_data_stream = &upload_data;
6096
6097 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6098 TestCompletionCallback callback;
6099 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6100 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6101 EXPECT_NE(OK, callback.WaitForResult());
6102
6103 // Verify that the alternative proxy server is not marked as broken.
6104 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6105
6106 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596107 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276108
6109 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6110 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6111 1);
tbansalc3308d72016-08-27 10:25:046112}
6113
rtenneti56977812016-01-15 19:26:566114TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:416115 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576116 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566117
6118 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6119 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016120 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:566121 socket_factory_.AddSocketDataProvider(&socket_data);
6122
rtennetib8e80fb2016-05-16 00:12:096123 // The non-alternate protocol job needs to hang in order to guarantee that
6124 // the alternate-protocol job will "win".
6125 AddHangingNonAlternateProtocolSocketData();
6126
rtenneti56977812016-01-15 19:26:566127 CreateSession();
6128 request_.method = "POST";
6129 ChunkedUploadDataStream upload_data(0);
6130 upload_data.AppendData("1", 1, true);
6131
6132 request_.upload_data_stream = &upload_data;
6133
bnc691fda62016-08-12 00:43:166134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566135 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166136 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016137 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566138 EXPECT_NE(OK, callback.WaitForResult());
6139}
6140
rche11300ef2016-09-02 01:44:286141TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486142 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286143 ScopedMockNetworkChangeNotifier network_change_notifier;
6144 MockNetworkChangeNotifier* mock_ncn =
6145 network_change_notifier.mock_network_change_notifier();
6146 mock_ncn->ForceNetworkHandlesSupported();
6147 mock_ncn->SetConnectedNetworksList(
6148 {kDefaultNetworkForTests, kNewNetworkForTests});
6149
mmenke6ddfbea2017-05-31 21:48:416150 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286151 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316152 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286153
6154 MockQuicData socket_data;
6155 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526156 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436157 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336158 socket_data.AddWrite(
6159 SYNCHRONOUS,
6160 ConstructClientRequestHeadersPacket(
6161 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6162 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286163 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6164 socket_data.AddSocketDataToFactory(&socket_factory_);
6165
6166 MockQuicData socket_data2;
6167 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6168 socket_data2.AddSocketDataToFactory(&socket_factory_);
6169
6170 // The non-alternate protocol job needs to hang in order to guarantee that
6171 // the alternate-protocol job will "win".
6172 AddHangingNonAlternateProtocolSocketData();
6173
6174 CreateSession();
6175 request_.method = "POST";
6176 ChunkedUploadDataStream upload_data(0);
6177
6178 request_.upload_data_stream = &upload_data;
6179
rdsmith1d343be52016-10-21 20:37:506180 std::unique_ptr<HttpNetworkTransaction> trans(
6181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286182 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506183 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286184 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6185
6186 base::RunLoop().RunUntilIdle();
6187 upload_data.AppendData("1", 1, true);
6188 base::RunLoop().RunUntilIdle();
6189
6190 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506191 trans.reset();
rche11300ef2016-09-02 01:44:286192 session_.reset();
6193}
6194
Ryan Hamilton4b3574532017-10-30 20:17:256195TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6196 session_params_.origins_to_force_quic_on.insert(
6197 HostPortPair::FromString("mail.example.org:443"));
6198
6199 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526200 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436201 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256202 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336203 socket_data.AddWrite(
6204 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6205 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6206 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436207 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336208 ASYNC, ConstructServerResponseHeadersPacket(
6209 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6210 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416211 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336212 socket_data.AddRead(
6213 ASYNC, ConstructServerDataPacket(
6214 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416215 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436216 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256217 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166218 socket_data.AddWrite(
6219 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6220 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6221 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256222
6223 socket_data.AddSocketDataToFactory(&socket_factory_);
6224
6225 CreateSession();
6226
6227 SendRequestAndExpectQuicResponse("hello!");
6228 session_.reset();
6229}
6230
6231TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6232 session_params_.origins_to_force_quic_on.insert(
6233 HostPortPair::FromString("mail.example.org:443"));
6234
6235 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526236 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436237 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256238 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336239 socket_data.AddWrite(
6240 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6241 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6242 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436243 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336244 ASYNC, ConstructServerResponseHeadersPacket(
6245 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6246 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416247 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336248 socket_data.AddRead(
6249 ASYNC, ConstructServerDataPacket(
6250 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416251 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436252 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256253 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166254 socket_data.AddWrite(
6255 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6256 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6257 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256258
6259 socket_data.AddSocketDataToFactory(&socket_factory_);
6260
6261 CreateSession();
6262
6263 SendRequestAndExpectQuicResponse("hello!");
6264 session_.reset();
6265}
6266
Ryan Hamilton9edcf1a2017-11-22 05:55:176267TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486268 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256269 session_params_.origins_to_force_quic_on.insert(
6270 HostPortPair::FromString("mail.example.org:443"));
6271
6272 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526273 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256274 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436275 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176276 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256277 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6278 }
6279 socket_data.AddSocketDataToFactory(&socket_factory_);
6280
6281 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176282 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6283 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6284 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6285 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256286
Ryan Hamilton8d9ee76e2018-05-29 23:52:526287 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256288 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6289 TestCompletionCallback callback;
6290 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6291 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176292 while (!callback.have_result()) {
6293 base::RunLoop().RunUntilIdle();
6294 quic_task_runner_->RunUntilIdle();
6295 }
6296 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256297 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176298 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6299 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6300 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526301 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6302 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256303}
6304
Ryan Hamilton9edcf1a2017-11-22 05:55:176305TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486306 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256307 session_params_.origins_to_force_quic_on.insert(
6308 HostPortPair::FromString("mail.example.org:443"));
6309
6310 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526311 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256312 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436313 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176314 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256315 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6316 }
6317 socket_data.AddSocketDataToFactory(&socket_factory_);
6318
6319 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176320 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6321 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6322 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6323 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256324
Ryan Hamilton8d9ee76e2018-05-29 23:52:526325 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6327 TestCompletionCallback callback;
6328 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176330 while (!callback.have_result()) {
6331 base::RunLoop().RunUntilIdle();
6332 quic_task_runner_->RunUntilIdle();
6333 }
6334 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256335 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176336 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6337 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6338 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526339 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6340 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256341}
6342
Cherie Shi7596de632018-02-22 07:28:186343TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486344 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186345 session_params_.origins_to_force_quic_on.insert(
6346 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526347 const quic::QuicString error_details =
6348 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6349 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186350
6351 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526352 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186353 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436354 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186355 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6356 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526357 socket_data.AddWrite(
6358 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6359 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186360 socket_data.AddSocketDataToFactory(&socket_factory_);
6361
6362 CreateSession();
6363
6364 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6365 TestCompletionCallback callback;
6366 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6367 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6368 base::RunLoop().RunUntilIdle();
6369 ASSERT_TRUE(callback.have_result());
6370 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6371 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6372 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6373}
6374
ckrasic769733c2016-06-30 00:42:136375// Adds coverage to catch regression such as https://crbug.com/622043
6376TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416377 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136378 HostPortPair::FromString("mail.example.org:443"));
6379
6380 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526381 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236382 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436383 mock_quic_data.AddWrite(
6384 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6385 &header_stream_offset));
6386 mock_quic_data.AddWrite(
6387 SYNCHRONOUS,
6388 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336389 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6390 true, true, GetRequestHeaders("GET", "https", "/"),
6391 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526392 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436393 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336394 ASYNC, ConstructServerPushPromisePacket(
6395 1, GetNthClientInitiatedBidirectionalStreamId(0),
6396 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6397 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6398 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576399 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266400 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336401 mock_quic_data.AddWrite(SYNCHRONOUS,
6402 ConstructClientPriorityPacket(
6403 client_packet_number++, false,
6404 GetNthServerInitiatedUnidirectionalStreamId(0),
6405 GetNthClientInitiatedBidirectionalStreamId(0),
6406 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576407 }
Zhongyi Shi32f2fd02018-04-16 18:23:436408 mock_quic_data.AddRead(
6409 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336410 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436411 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576412 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436413 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6414 mock_quic_data.AddRead(
6415 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336416 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6417 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416418 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436419 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336420 ASYNC, ConstructServerDataPacket(
6421 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416422 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576423 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436424 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416425 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436426 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336427 ASYNC, ConstructServerDataPacket(
6428 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416429 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336430 mock_quic_data.AddWrite(SYNCHRONOUS,
6431 ConstructClientAckAndRstPacket(
6432 client_packet_number++,
6433 GetNthServerInitiatedUnidirectionalStreamId(0),
6434 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136435 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6436 mock_quic_data.AddRead(ASYNC, 0); // EOF
6437 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6438
6439 // The non-alternate protocol job needs to hang in order to guarantee that
6440 // the alternate-protocol job will "win".
6441 AddHangingNonAlternateProtocolSocketData();
6442
6443 CreateSession();
6444
6445 // PUSH_PROMISE handling in the http layer gets exercised here.
6446 SendRequestAndExpectQuicResponse("hello!");
6447
6448 request_.url = GURL("https://mail.example.org/pushed.jpg");
6449 SendRequestAndExpectQuicResponse("and hello!");
6450
6451 // Check that the NetLog was filled reasonably.
6452 TestNetLogEntry::List entries;
6453 net_log_.GetEntries(&entries);
6454 EXPECT_LT(0u, entries.size());
6455
6456 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6457 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006458 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6459 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136460 EXPECT_LT(0, pos);
6461}
6462
rch56ec40a2017-06-23 14:48:446463// Regression test for http://crbug.com/719461 in which a promised stream
6464// is closed before the pushed headers arrive, but after the connection
6465// is closed and before the callbacks are executed.
6466TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486467 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446468 session_params_.origins_to_force_quic_on.insert(
6469 HostPortPair::FromString("mail.example.org:443"));
6470
6471 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526472 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236473 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446474 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436475 mock_quic_data.AddWrite(
6476 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6477 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446478 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436479 mock_quic_data.AddWrite(
6480 SYNCHRONOUS,
6481 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336482 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6483 true, true, GetRequestHeaders("GET", "https", "/"),
6484 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526485 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446486 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436487 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336488 ASYNC, ConstructServerPushPromisePacket(
6489 1, GetNthClientInitiatedBidirectionalStreamId(0),
6490 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6491 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6492 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576493 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266494 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336495 mock_quic_data.AddWrite(SYNCHRONOUS,
6496 ConstructClientPriorityPacket(
6497 client_packet_number++, false,
6498 GetNthServerInitiatedUnidirectionalStreamId(0),
6499 GetNthClientInitiatedBidirectionalStreamId(0),
6500 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576501 }
rch56ec40a2017-06-23 14:48:446502 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436503 mock_quic_data.AddRead(
6504 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336505 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436506 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446507 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576508 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436509 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446510 // Response body for first request.
Renjief49758b2019-01-11 23:32:416511 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436512 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336513 ASYNC, ConstructServerDataPacket(
6514 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416515 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446516 // Write error for the third request.
6517 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6518 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6519 mock_quic_data.AddRead(ASYNC, 0); // EOF
6520 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6521
6522 CreateSession();
6523
6524 // Send a request which triggers a push promise from the server.
6525 SendRequestAndExpectQuicResponse("hello!");
6526
6527 // Start a push transaction that will be cancelled after the connection
6528 // is closed, but before the callback is executed.
6529 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196530 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446531 session_.get());
6532 TestCompletionCallback callback2;
6533 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6534 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6535 base::RunLoop().RunUntilIdle();
6536
6537 // Cause the connection to close on a write error.
6538 HttpRequestInfo request3;
6539 request3.method = "GET";
6540 request3.url = GURL("https://mail.example.org/");
6541 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106542 request3.traffic_annotation =
6543 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446544 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6545 TestCompletionCallback callback3;
6546 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6547 IsError(ERR_IO_PENDING));
6548
6549 base::RunLoop().RunUntilIdle();
6550
6551 // When |trans2| is destroyed, the underlying stream will be closed.
6552 EXPECT_FALSE(callback2.have_result());
6553 trans2 = nullptr;
6554
6555 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6556}
6557
ckrasicda193a82016-07-09 00:39:366558TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416559 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366560 HostPortPair::FromString("mail.example.org:443"));
6561
6562 MockQuicData mock_quic_data;
6563
Ryan Hamilton8d9ee76e2018-05-29 23:52:526564 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416565 int write_packet_index = 1;
6566 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6567 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366568
Renjief49758b2019-01-11 23:32:416569 quic::QuicString header = ConstructDataHeader(1);
6570 if (version_ != quic::QUIC_VERSION_99) {
6571 mock_quic_data.AddWrite(
6572 SYNCHRONOUS,
6573 ConstructClientRequestHeadersAndDataFramesPacket(
6574 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6575 true, true, DEFAULT_PRIORITY,
6576 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6577 {"1"}));
6578 } else {
6579 mock_quic_data.AddWrite(
6580 SYNCHRONOUS,
6581 ConstructClientRequestHeadersAndDataFramesPacket(
6582 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6583 true, true, DEFAULT_PRIORITY,
6584 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6585 {header, "1"}));
6586 }
ckrasicda193a82016-07-09 00:39:366587
Zhongyi Shi32f2fd02018-04-16 18:23:436588 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336589 ASYNC, ConstructServerResponseHeadersPacket(
6590 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6591 GetResponseHeaders("200 OK")));
6592
Renjief49758b2019-01-11 23:32:416593 quic::QuicString header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336594 mock_quic_data.AddRead(
6595 ASYNC, ConstructServerDataPacket(
6596 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416597 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366598
Renjief49758b2019-01-11 23:32:416599 mock_quic_data.AddWrite(
6600 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366601
6602 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6603 mock_quic_data.AddRead(ASYNC, 0); // EOF
6604 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6605
6606 // The non-alternate protocol job needs to hang in order to guarantee that
6607 // the alternate-protocol job will "win".
6608 AddHangingNonAlternateProtocolSocketData();
6609
6610 CreateSession();
6611 request_.method = "POST";
6612 ChunkedUploadDataStream upload_data(0);
6613 upload_data.AppendData("1", 1, true);
6614
6615 request_.upload_data_stream = &upload_data;
6616
6617 SendRequestAndExpectQuicResponse("hello!");
6618}
6619
allada71b2efb2016-09-09 04:57:486620class QuicURLRequestContext : public URLRequestContext {
6621 public:
6622 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6623 MockClientSocketFactory* socket_factory)
6624 : storage_(this) {
6625 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076626 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046627 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486628 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046629 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596630 storage_.set_proxy_resolution_service(
6631 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076632 storage_.set_ssl_config_service(
6633 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486634 storage_.set_http_auth_handler_factory(
6635 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6636 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076637 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046638 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486639 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046640 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6641 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6642 false));
allada71b2efb2016-09-09 04:57:486643 }
6644
6645 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6646
6647 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6648
6649 private:
6650 MockClientSocketFactory* socket_factory_;
6651 URLRequestContextStorage storage_;
6652};
6653
6654TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416655 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486656 HostPortPair::FromString("mail.example.org:443"));
6657
6658 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526659 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366660 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436661 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136662 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486663 headers["user-agent"] = "";
6664 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336665 mock_quic_data.AddWrite(
6666 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6667 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6668 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486669
Ryan Hamilton8d9ee76e2018-05-29 23:52:526670 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336671 mock_quic_data.AddRead(
6672 ASYNC,
6673 ConstructServerResponseHeadersPacket(
6674 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6675 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486676
Renjief49758b2019-01-11 23:32:416677 quic::QuicString header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366678 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336679 ASYNC, ConstructServerDataPacket(
6680 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6681 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436682 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486683
6684 mock_quic_data.AddRead(ASYNC, 0); // EOF
6685
6686 CreateSession();
6687
6688 TestDelegate delegate;
6689 QuicURLRequestContext quic_url_request_context(std::move(session_),
6690 &socket_factory_);
6691
6692 mock_quic_data.AddSocketDataToFactory(
6693 &quic_url_request_context.socket_factory());
6694 TestNetworkDelegate network_delegate;
6695 quic_url_request_context.set_network_delegate(&network_delegate);
6696
6697 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296698 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6699 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486700 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6701 &ssl_data_);
6702
6703 request->Start();
Wez2a31b222018-06-07 22:07:156704 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486705
6706 EXPECT_LT(0, request->GetTotalSentBytes());
6707 EXPECT_LT(0, request->GetTotalReceivedBytes());
6708 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6709 request->GetTotalSentBytes());
6710 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6711 request->GetTotalReceivedBytes());
6712 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6713 request->raw_header_size());
Wez0e717112018-06-18 23:09:226714
6715 // Pump the message loop to allow all data to be consumed.
6716 base::RunLoop().RunUntilIdle();
6717
allada71b2efb2016-09-09 04:57:486718 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6719 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6720}
6721
6722TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416723 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486724 HostPortPair::FromString("mail.example.org:443"));
6725
6726 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526727 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236728 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436729 mock_quic_data.AddWrite(
6730 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6731 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136732 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486733 headers["user-agent"] = "";
6734 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436735 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336736 SYNCHRONOUS,
6737 ConstructClientRequestHeadersPacket(
6738 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6739 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486740
Ryan Hamilton8d9ee76e2018-05-29 23:52:526741 quic::QuicStreamOffset server_header_offset = 0;
6742 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486743
Zhongyi Shi32f2fd02018-04-16 18:23:436744 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336745 ASYNC, ConstructServerPushPromisePacket(
6746 1, GetNthClientInitiatedBidirectionalStreamId(0),
6747 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6748 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6749 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486750
Yixin Wangb470bc882018-02-15 18:43:576751 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266752 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336753 mock_quic_data.AddWrite(SYNCHRONOUS,
6754 ConstructClientPriorityPacket(
6755 client_packet_number++, false,
6756 GetNthServerInitiatedUnidirectionalStreamId(0),
6757 GetNthClientInitiatedBidirectionalStreamId(0),
6758 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576759 }
6760
allada71b2efb2016-09-09 04:57:486761 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436762 mock_quic_data.AddRead(
6763 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336764 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436765 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486766 expected_raw_header_response_size =
6767 server_header_offset - expected_raw_header_response_size;
6768
Yixin Wangb470bc882018-02-15 18:43:576769 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436770 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486771
ckrasicbf2f59c2017-05-04 23:54:366772 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436773 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336774 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6775 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416776 quic::QuicString header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436777 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336778 ASYNC, ConstructServerDataPacket(
6779 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416780 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486781
Yixin Wangb470bc882018-02-15 18:43:576782 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436783 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416784 quic::QuicString header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366785 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336786 ASYNC, ConstructServerDataPacket(
6787 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416788 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486789
Zhongyi Shi32f2fd02018-04-16 18:23:436790 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486791
6792 CreateSession();
6793
6794 TestDelegate delegate;
6795 QuicURLRequestContext quic_url_request_context(std::move(session_),
6796 &socket_factory_);
6797
6798 mock_quic_data.AddSocketDataToFactory(
6799 &quic_url_request_context.socket_factory());
6800 TestNetworkDelegate network_delegate;
6801 quic_url_request_context.set_network_delegate(&network_delegate);
6802
6803 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296804 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6805 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486806 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6807 &ssl_data_);
6808
6809 request->Start();
Wez2a31b222018-06-07 22:07:156810 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486811
6812 EXPECT_LT(0, request->GetTotalSentBytes());
6813 EXPECT_LT(0, request->GetTotalReceivedBytes());
6814 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6815 request->GetTotalSentBytes());
6816 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6817 request->GetTotalReceivedBytes());
6818 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6819 request->raw_header_size());
Wez0e717112018-06-18 23:09:226820
6821 // Pump the message loop to allow all data to be consumed.
6822 base::RunLoop().RunUntilIdle();
6823
allada71b2efb2016-09-09 04:57:486824 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6825 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6826}
6827
Yixin Wang10f477ed2017-11-21 04:20:206828TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6829 session_params_.quic_host_whitelist.insert("mail.example.org");
6830
6831 MockRead http_reads[] = {
6832 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6833 MockRead("hello world"),
6834 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6835 MockRead(ASYNC, OK)};
6836
Ryan Sleevib8d7ea02018-05-07 20:01:016837 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206838 socket_factory_.AddSocketDataProvider(&http_data);
6839 AddCertificate(&ssl_data_);
6840 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6841
6842 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526843 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206844 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436845 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6846 mock_quic_data.AddWrite(
6847 SYNCHRONOUS,
6848 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336849 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436850 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436851 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336852 ASYNC, ConstructServerResponseHeadersPacket(
6853 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6854 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416855 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336856 mock_quic_data.AddRead(
6857 ASYNC, ConstructServerDataPacket(
6858 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416859 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436860 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206861 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6862 mock_quic_data.AddRead(ASYNC, 0); // EOF
6863
6864 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6865
6866 AddHangingNonAlternateProtocolSocketData();
6867 CreateSession();
6868
6869 SendRequestAndExpectHttpResponse("hello world");
6870 SendRequestAndExpectQuicResponse("hello!");
6871}
6872
6873TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6874 session_params_.quic_host_whitelist.insert("mail.example.com");
6875
6876 MockRead http_reads[] = {
6877 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6878 MockRead("hello world"),
6879 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6880 MockRead(ASYNC, OK)};
6881
Ryan Sleevib8d7ea02018-05-07 20:01:016882 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206883 socket_factory_.AddSocketDataProvider(&http_data);
6884 AddCertificate(&ssl_data_);
6885 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6886 socket_factory_.AddSocketDataProvider(&http_data);
6887 AddCertificate(&ssl_data_);
6888 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6889
6890 AddHangingNonAlternateProtocolSocketData();
6891 CreateSession();
6892
6893 SendRequestAndExpectHttpResponse("hello world");
6894 SendRequestAndExpectHttpResponse("hello world");
6895}
6896
bnc359ed2a2016-04-29 20:43:456897class QuicNetworkTransactionWithDestinationTest
6898 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016899 public ::testing::WithParamInterface<PoolingTestParams>,
6900 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456901 protected:
6902 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556903 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056904 client_headers_include_h2_stream_dependency_(
6905 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526906 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456907 destination_type_(GetParam().destination_type),
6908 cert_transparency_verifier_(new MultiLogCTVerifier()),
6909 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596910 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456911 auth_handler_factory_(
6912 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6913 random_generator_(0),
6914 ssl_data_(ASYNC, OK) {}
6915
6916 void SetUp() override {
6917 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556918 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456919
mmenke6ddfbea2017-05-31 21:48:416920 HttpNetworkSession::Params session_params;
6921 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346922 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446923 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056924 session_params.quic_headers_include_h2_stream_dependency =
6925 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416926
6927 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456928
Ryan Hamilton8d9ee76e2018-05-29 23:52:526929 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416930 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456931
6932 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276933 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416934 session_context.quic_crypto_client_stream_factory =
6935 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456936
mmenke6ddfbea2017-05-31 21:48:416937 session_context.quic_random = &random_generator_;
6938 session_context.client_socket_factory = &socket_factory_;
6939 session_context.host_resolver = &host_resolver_;
6940 session_context.cert_verifier = &cert_verifier_;
6941 session_context.transport_security_state = &transport_security_state_;
6942 session_context.cert_transparency_verifier =
6943 cert_transparency_verifier_.get();
6944 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6945 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456946 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416947 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596948 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416949 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6950 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456951
mmenke6ddfbea2017-05-31 21:48:416952 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456953 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456954 }
6955
6956 void TearDown() override {
6957 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6958 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556959 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456960 PlatformTest::TearDown();
6961 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556962 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406963 session_.reset();
bnc359ed2a2016-04-29 20:43:456964 }
6965
zhongyie537a002017-06-27 16:48:216966 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456967 HostPortPair destination;
6968 switch (destination_type_) {
6969 case SAME_AS_FIRST:
6970 destination = HostPortPair(origin1_, 443);
6971 break;
6972 case SAME_AS_SECOND:
6973 destination = HostPortPair(origin2_, 443);
6974 break;
6975 case DIFFERENT:
6976 destination = HostPortPair(kDifferentHostname, 443);
6977 break;
6978 }
bnc3472afd2016-11-17 15:27:216979 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456980 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216981 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456982 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446983 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456984 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526985 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236986 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526987 quic::QuicStreamId stream_id,
6988 bool should_include_version,
6989 quic::QuicStreamOffset* offset,
6990 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486991 return ConstructClientRequestHeadersPacket(
6992 packet_number, stream_id, should_include_version, 0, offset, maker);
6993 }
bnc359ed2a2016-04-29 20:43:456994
Ryan Hamilton8d9ee76e2018-05-29 23:52:526995 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236996 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526997 quic::QuicStreamId stream_id,
6998 bool should_include_version,
6999 quic::QuicStreamId parent_stream_id,
7000 quic::QuicStreamOffset* offset,
7001 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137002 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457003 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137004 spdy::SpdyHeaderBlock headers(
7005 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:457006 return maker->MakeRequestHeadersPacketWithOffsetTracking(
7007 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:487008 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:457009 }
7010
Ryan Hamilton8d9ee76e2018-05-29 23:52:527011 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237012 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527013 quic::QuicStreamId stream_id,
7014 bool should_include_version,
7015 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587016 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457017 packet_number, stream_id, should_include_version, nullptr, maker);
7018 }
7019
Ryan Hamilton8d9ee76e2018-05-29 23:52:527020 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237021 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527022 quic::QuicStreamId stream_id,
7023 quic::QuicStreamOffset* offset,
7024 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137025 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:457026 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:267027 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:457028 }
7029
Ryan Hamilton8d9ee76e2018-05-29 23:52:527030 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237031 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527032 quic::QuicStreamId stream_id,
7033 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587034 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
7035 nullptr, maker);
bnc359ed2a2016-04-29 20:43:457036 }
7037
Ryan Hamilton8d9ee76e2018-05-29 23:52:527038 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237039 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527040 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457041 QuicTestPacketMaker* maker) {
Renjief49758b2019-01-11 23:32:417042 quic::QuicString header = "";
7043 if (version_ == quic::QUIC_VERSION_99) {
7044 quic::HttpEncoder encoder;
7045 std::unique_ptr<char[]> buffer;
7046 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
7047 header = quic::QuicString(buffer.get(), header_length);
7048 }
bnc359ed2a2016-04-29 20:43:457049 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:417050 header + "hello");
bnc359ed2a2016-04-29 20:43:457051 }
7052
Ryan Hamilton8d9ee76e2018-05-29 23:52:527053 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237054 uint64_t packet_number,
7055 uint64_t largest_received,
7056 uint64_t smallest_received,
7057 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457058 QuicTestPacketMaker* maker) {
7059 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497060 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457061 }
7062
Ryan Hamilton8d9ee76e2018-05-29 23:52:527063 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237064 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527065 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:377066 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:367067 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:377068 }
7069
bnc359ed2a2016-04-29 20:43:457070 void AddRefusedSocketData() {
7071 std::unique_ptr<StaticSocketDataProvider> refused_data(
7072 new StaticSocketDataProvider());
7073 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7074 refused_data->set_connect_data(refused_connect);
7075 socket_factory_.AddSocketDataProvider(refused_data.get());
7076 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7077 }
7078
7079 void AddHangingSocketData() {
7080 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7081 new StaticSocketDataProvider());
7082 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7083 hanging_data->set_connect_data(hanging_connect);
7084 socket_factory_.AddSocketDataProvider(hanging_data.get());
7085 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7086 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7087 }
7088
7089 bool AllDataConsumed() {
7090 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7091 if (!socket_data_ptr->AllReadDataConsumed() ||
7092 !socket_data_ptr->AllWriteDataConsumed()) {
7093 return false;
7094 }
7095 }
7096 return true;
7097 }
7098
7099 void SendRequestAndExpectQuicResponse(const std::string& host) {
7100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7101 HttpRequestInfo request;
7102 std::string url("https://");
7103 url.append(host);
7104 request.url = GURL(url);
7105 request.load_flags = 0;
7106 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107107 request.traffic_annotation =
7108 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457109 TestCompletionCallback callback;
7110 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017111 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457112
7113 std::string response_data;
robpercival214763f2016-07-01 23:27:017114 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457115 EXPECT_EQ("hello", response_data);
7116
7117 const HttpResponseInfo* response = trans.GetResponseInfo();
7118 ASSERT_TRUE(response != nullptr);
7119 ASSERT_TRUE(response->headers.get() != nullptr);
7120 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7121 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527122 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:447123 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457124 response->connection_info);
7125 EXPECT_EQ(443, response->socket_address.port());
7126 }
7127
Fan Yang32c5a112018-12-10 20:06:337128 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
7129 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:367130 }
7131
Ryan Hamilton8d9ee76e2018-05-29 23:52:527132 quic::MockClock clock_;
7133 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:057134 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527135 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457136 DestinationType destination_type_;
7137 std::string origin1_;
7138 std::string origin2_;
7139 std::unique_ptr<HttpNetworkSession> session_;
7140 MockClientSocketFactory socket_factory_;
7141 MockHostResolver host_resolver_;
7142 MockCertVerifier cert_verifier_;
7143 TransportSecurityState transport_security_state_;
7144 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237145 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457146 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077147 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597148 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457149 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527150 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457151 HttpServerPropertiesImpl http_server_properties_;
7152 BoundTestNetLog net_log_;
7153 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7154 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7155 static_socket_data_provider_vector_;
7156 SSLSocketDataProvider ssl_data_;
7157};
7158
Victor Costane635086f2019-01-27 05:20:307159INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7160 QuicNetworkTransactionWithDestinationTest,
7161 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457162
7163// A single QUIC request fails because the certificate does not match the origin
7164// hostname, regardless of whether it matches the alternative service hostname.
7165TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7166 if (destination_type_ == DIFFERENT)
7167 return;
7168
7169 GURL url("https://mail.example.com/");
7170 origin1_ = url.host();
7171
7172 // Not used for requests, but this provides a test case where the certificate
7173 // is valid for the hostname of the alternative service.
7174 origin2_ = "mail.example.org";
7175
zhongyie537a002017-06-27 16:48:217176 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457177
7178 scoped_refptr<X509Certificate> cert(
7179 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247180 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7181 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457182
7183 ProofVerifyDetailsChromium verify_details;
7184 verify_details.cert_verify_result.verified_cert = cert;
7185 verify_details.cert_verify_result.is_issued_by_known_root = true;
7186 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7187
7188 MockQuicData mock_quic_data;
7189 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7190 mock_quic_data.AddRead(ASYNC, 0);
7191
7192 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7193
7194 AddRefusedSocketData();
7195
7196 HttpRequestInfo request;
7197 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107198 request.traffic_annotation =
7199 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457200
7201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7202 TestCompletionCallback callback;
7203 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017204 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457205
7206 EXPECT_TRUE(AllDataConsumed());
7207}
7208
7209// First request opens QUIC session to alternative service. Second request
7210// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527211// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457212TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7213 origin1_ = "mail.example.org";
7214 origin2_ = "news.example.org";
7215
zhongyie537a002017-06-27 16:48:217216 SetQuicAlternativeService(origin1_);
7217 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457218
7219 scoped_refptr<X509Certificate> cert(
7220 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247221 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7222 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7223 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457224
7225 ProofVerifyDetailsChromium verify_details;
7226 verify_details.cert_verify_result.verified_cert = cert;
7227 verify_details.cert_verify_result.is_issued_by_known_root = true;
7228 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7229
Yixin Wang079ad542018-01-11 04:06:057230 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177231 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7232 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057233 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177234 QuicTestPacketMaker server_maker(
7235 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7236 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457237
Ryan Hamilton8d9ee76e2018-05-29 23:52:527238 quic::QuicStreamOffset request_header_offset(0);
7239 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457240
7241 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057242 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437243 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057244 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337245 mock_quic_data.AddWrite(
7246 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7247 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7248 &request_header_offset, &client_maker));
7249 mock_quic_data.AddRead(ASYNC,
7250 ConstructServerResponseHeadersPacket(
7251 1, GetNthClientInitiatedBidirectionalStreamId(0),
7252 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437253 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337254 ASYNC,
7255 ConstructServerDataPacket(
7256 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437257 mock_quic_data.AddWrite(SYNCHRONOUS,
7258 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457259
Yixin Wang079ad542018-01-11 04:06:057260 client_maker.set_hostname(origin2_);
7261 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457262
Zhongyi Shi32f2fd02018-04-16 18:23:437263 mock_quic_data.AddWrite(
7264 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337265 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7266 GetNthClientInitiatedBidirectionalStreamId(0),
7267 &request_header_offset, &client_maker));
7268 mock_quic_data.AddRead(ASYNC,
7269 ConstructServerResponseHeadersPacket(
7270 3, GetNthClientInitiatedBidirectionalStreamId(1),
7271 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437272 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337273 ASYNC,
7274 ConstructServerDataPacket(
7275 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437276 mock_quic_data.AddWrite(SYNCHRONOUS,
7277 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457278 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7279 mock_quic_data.AddRead(ASYNC, 0); // EOF
7280
7281 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7282
7283 AddHangingSocketData();
7284 AddHangingSocketData();
7285
Fan Yangc9e00dc2018-10-09 14:17:567286 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7287 QuicStreamFactoryPeer::SetAlarmFactory(
7288 session_->quic_stream_factory(),
7289 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7290 &clock_));
7291
bnc359ed2a2016-04-29 20:43:457292 SendRequestAndExpectQuicResponse(origin1_);
7293 SendRequestAndExpectQuicResponse(origin2_);
7294
7295 EXPECT_TRUE(AllDataConsumed());
7296}
7297
7298// First request opens QUIC session to alternative service. Second request does
7299// not pool to it, even though destination matches, because certificate is not
7300// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527301// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457302TEST_P(QuicNetworkTransactionWithDestinationTest,
7303 DoNotPoolIfCertificateInvalid) {
7304 origin1_ = "news.example.org";
7305 origin2_ = "mail.example.com";
7306
zhongyie537a002017-06-27 16:48:217307 SetQuicAlternativeService(origin1_);
7308 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457309
7310 scoped_refptr<X509Certificate> cert1(
7311 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247312 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7313 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7314 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457315
7316 scoped_refptr<X509Certificate> cert2(
7317 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247318 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7319 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457320
7321 ProofVerifyDetailsChromium verify_details1;
7322 verify_details1.cert_verify_result.verified_cert = cert1;
7323 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7324 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7325
7326 ProofVerifyDetailsChromium verify_details2;
7327 verify_details2.cert_verify_result.verified_cert = cert2;
7328 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7329 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7330
Yixin Wang079ad542018-01-11 04:06:057331 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177332 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7333 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057334 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177335 QuicTestPacketMaker server_maker1(
7336 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7337 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457338
7339 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527340 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457341 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437342 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7343 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337344 mock_quic_data1.AddWrite(
7345 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7346 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7347 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437348 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337349 ASYNC,
7350 ConstructServerResponseHeadersPacket(
7351 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437352 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337353 ASYNC,
7354 ConstructServerDataPacket(
7355 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437356 mock_quic_data1.AddWrite(
7357 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457358 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7359 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7360
7361 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7362
Yixin Wang079ad542018-01-11 04:06:057363 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177364 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7365 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057366 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177367 QuicTestPacketMaker server_maker2(
7368 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7369 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457370
7371 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527372 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457373 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437374 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7375 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337376 mock_quic_data2.AddWrite(
7377 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7378 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7379 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437380 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337381 ASYNC,
7382 ConstructServerResponseHeadersPacket(
7383 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437384 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337385 ASYNC,
7386 ConstructServerDataPacket(
7387 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437388 mock_quic_data2.AddWrite(
7389 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457390 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7391 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7392
7393 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7394
bnc359ed2a2016-04-29 20:43:457395 SendRequestAndExpectQuicResponse(origin1_);
7396 SendRequestAndExpectQuicResponse(origin2_);
7397
7398 EXPECT_TRUE(AllDataConsumed());
7399}
7400
ckrasicdee37572017-04-06 22:42:277401// crbug.com/705109 - this confirms that matching request with a body
7402// triggers a crash (pre-fix).
7403TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417404 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277405 HostPortPair::FromString("mail.example.org:443"));
7406
7407 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527408 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237409 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437410 mock_quic_data.AddWrite(
7411 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7412 &header_stream_offset));
7413 mock_quic_data.AddWrite(
7414 SYNCHRONOUS,
7415 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337416 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7417 true, true, GetRequestHeaders("GET", "https", "/"),
7418 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527419 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437420 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337421 ASYNC, ConstructServerPushPromisePacket(
7422 1, GetNthClientInitiatedBidirectionalStreamId(0),
7423 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7424 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7425 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577426 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267427 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337428 mock_quic_data.AddWrite(SYNCHRONOUS,
7429 ConstructClientPriorityPacket(
7430 client_packet_number++, false,
7431 GetNthServerInitiatedUnidirectionalStreamId(0),
7432 GetNthClientInitiatedBidirectionalStreamId(0),
7433 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577434 }
Zhongyi Shi32f2fd02018-04-16 18:23:437435 mock_quic_data.AddRead(
7436 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337437 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437438 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577439 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437440 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7441 mock_quic_data.AddRead(
7442 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337443 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7444 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417445 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437446 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337447 ASYNC, ConstructServerDataPacket(
7448 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417449 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577450 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437451 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417452
7453 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437454 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337455 ASYNC, ConstructServerDataPacket(
7456 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417457 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277458
7459 // Because the matching request has a body, we will see the push
7460 // stream get cancelled, and the matching request go out on the
7461 // wire.
Fan Yang32c5a112018-12-10 20:06:337462 mock_quic_data.AddWrite(SYNCHRONOUS,
7463 ConstructClientAckAndRstPacket(
7464 client_packet_number++,
7465 GetNthServerInitiatedUnidirectionalStreamId(0),
7466 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277467 const char kBody[] = "1";
Renjief49758b2019-01-11 23:32:417468 quic::QuicString header3 = ConstructDataHeader(1);
7469 if (version_ != quic::QUIC_VERSION_99) {
7470 mock_quic_data.AddWrite(
7471 SYNCHRONOUS,
7472 ConstructClientRequestHeadersAndDataFramesPacket(
7473 client_packet_number++,
7474 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7475 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7476 GetNthServerInitiatedUnidirectionalStreamId(0),
7477 &header_stream_offset, nullptr, {kBody}));
7478 } else {
7479 mock_quic_data.AddWrite(
7480 SYNCHRONOUS,
7481 ConstructClientRequestHeadersAndDataFramesPacket(
7482 client_packet_number++,
7483 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7484 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7485 GetNthServerInitiatedUnidirectionalStreamId(0),
7486 &header_stream_offset, nullptr, {header3, kBody}));
7487 }
ckrasicdee37572017-04-06 22:42:277488
7489 // We see the same response as for the earlier pushed and cancelled
7490 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437491 mock_quic_data.AddRead(
7492 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337493 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437494 GetResponseHeaders("200 OK"), &server_header_offset));
7495 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337496 ASYNC, ConstructServerDataPacket(
7497 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417498 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277499
Yixin Wangb470bc882018-02-15 18:43:577500 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437501 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277502 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7503 mock_quic_data.AddRead(ASYNC, 0); // EOF
7504 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7505
7506 // The non-alternate protocol job needs to hang in order to guarantee that
7507 // the alternate-protocol job will "win".
7508 AddHangingNonAlternateProtocolSocketData();
7509
7510 CreateSession();
7511
7512 // PUSH_PROMISE handling in the http layer gets exercised here.
7513 SendRequestAndExpectQuicResponse("hello!");
7514
7515 request_.url = GURL("https://mail.example.org/pushed.jpg");
7516 ChunkedUploadDataStream upload_data(0);
7517 upload_data.AppendData("1", 1, true);
7518 request_.upload_data_stream = &upload_data;
7519 SendRequestAndExpectQuicResponse("and hello!");
7520}
7521
Bence Béky7538a952018-02-01 16:59:527522// Regression test for https://crbug.com/797825: If pushed headers describe a
7523// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7524// not be called (otherwise a DCHECK fails).
7525TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137526 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527527 pushed_request_headers[":authority"] = "";
7528 pushed_request_headers[":method"] = "GET";
7529 pushed_request_headers[":path"] = "/";
7530 pushed_request_headers[":scheme"] = "nosuchscheme";
7531
7532 session_params_.origins_to_force_quic_on.insert(
7533 HostPortPair::FromString("mail.example.org:443"));
7534
7535 MockQuicData mock_quic_data;
7536
Ryan Hamilton8d9ee76e2018-05-29 23:52:527537 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527538 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437539 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7540 mock_quic_data.AddWrite(
7541 SYNCHRONOUS,
7542 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337543 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437544 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527545
Ryan Hamilton8d9ee76e2018-05-29 23:52:527546 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337547 mock_quic_data.AddRead(
7548 ASYNC, ConstructServerPushPromisePacket(
7549 1, GetNthClientInitiatedBidirectionalStreamId(0),
7550 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7551 std::move(pushed_request_headers), &server_header_offset,
7552 &server_maker_));
7553 mock_quic_data.AddWrite(SYNCHRONOUS,
7554 ConstructClientRstPacket(
7555 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7556 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527557
Zhongyi Shi32f2fd02018-04-16 18:23:437558 mock_quic_data.AddRead(
7559 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337560 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437561 GetResponseHeaders("200 OK"), &server_header_offset));
7562 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527563
Zhongyi Shi32f2fd02018-04-16 18:23:437564 mock_quic_data.AddRead(
7565 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337566 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7567 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417568 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437569 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337570 ASYNC, ConstructServerDataPacket(
7571 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417572 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437573 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527574
7575 mock_quic_data.AddRead(ASYNC, 0);
7576 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7577
7578 // The non-alternate protocol job needs to hang in order to guarantee that
7579 // the alternate-protocol job will "win".
7580 AddHangingNonAlternateProtocolSocketData();
7581
7582 CreateSession();
7583
7584 // PUSH_PROMISE handling in the http layer gets exercised here.
7585 SendRequestAndExpectQuicResponse("hello!");
7586
7587 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7588 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7589}
7590
Yixin Wang46a273ec302018-01-23 17:59:567591// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147592TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567593 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147594 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567595 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497596 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567597
7598 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527599 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567600 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357601 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337602 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357603 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7604 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7605 false, ConnectRequestHeaders("mail.example.org:443"),
7606 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337607 mock_quic_data.AddRead(
7608 ASYNC, ConstructServerResponseHeadersPacket(
7609 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7610 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567611
7612 const char get_request[] =
7613 "GET / HTTP/1.1\r\n"
7614 "Host: mail.example.org\r\n"
7615 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417616 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7617 if (version_ != quic::QUIC_VERSION_99) {
7618 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357619 SYNCHRONOUS,
7620 ConstructClientAckAndDataPacket(
7621 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7622 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417623 } else {
7624 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417625 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357626 ConstructClientAckAndMultipleDataFramesPacket(
7627 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7628 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417629 }
7630
Yixin Wang46a273ec302018-01-23 17:59:567631 const char get_response[] =
7632 "HTTP/1.1 200 OK\r\n"
7633 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417634 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437635 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337636 ASYNC, ConstructServerDataPacket(
7637 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417638 0, header2 + quic::QuicString(get_response)));
7639 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337640 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417641 SYNCHRONOUS, ConstructServerDataPacket(
7642 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7643 false, strlen(get_response) + header2.length(),
7644 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357645 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567646 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7647
7648 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417649 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357650 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7651 quic::QUIC_STREAM_CANCELLED,
7652 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567653
7654 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7655
7656 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7657
7658 CreateSession();
7659
7660 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097661 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7663 HeadersHandler headers_handler;
7664 trans.SetBeforeHeadersSentCallback(
7665 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7666 base::Unretained(&headers_handler)));
7667 RunTransaction(&trans);
7668 CheckWasHttpResponse(&trans);
7669 CheckResponsePort(&trans, 70);
7670 CheckResponseData(&trans, "0123456789");
7671 EXPECT_TRUE(headers_handler.was_proxied());
7672 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7673
7674 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7675 // proxy socket to disconnect.
7676 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7677
7678 base::RunLoop().RunUntilIdle();
7679 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7680 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7681}
7682
7683// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147684TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567685 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147686 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567687 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497688 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567689
7690 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527691 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567692 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357693 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337694 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357695 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7696 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7697 false, ConnectRequestHeaders("mail.example.org:443"),
7698 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337699 mock_quic_data.AddRead(
7700 ASYNC, ConstructServerResponseHeadersPacket(
7701 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7702 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567703
7704 SpdyTestUtil spdy_util;
7705
Ryan Hamilton0239aac2018-05-19 00:03:137706 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567707 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417708 quic::QuicString header = ConstructDataHeader(get_frame.size());
7709 if (version_ != quic::QUIC_VERSION_99) {
7710 mock_quic_data.AddWrite(
7711 SYNCHRONOUS,
7712 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357713 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7714 false, 0,
Renjief49758b2019-01-11 23:32:417715 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7716 } else {
7717 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417718 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357719 ConstructClientAckAndMultipleDataFramesPacket(
7720 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7721 false, 0,
7722 {header, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417723 }
Ryan Hamilton0239aac2018-05-19 00:03:137724 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567725 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417726 quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437727 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337728 ASYNC,
7729 ConstructServerDataPacket(
7730 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Renjief49758b2019-01-11 23:32:417731 header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567732
Ryan Hamilton0239aac2018-05-19 00:03:137733 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197734 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Renjief49758b2019-01-11 23:32:417735 quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437736 mock_quic_data.AddRead(
7737 SYNCHRONOUS,
7738 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337739 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417740 resp_frame.size() + header2.length(),
7741 header3 + quic::QuicString(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357742 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567743 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7744
7745 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437746 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357747 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7748 quic::QUIC_STREAM_CANCELLED,
7749 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567750
7751 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7752
7753 SSLSocketDataProvider ssl_data(ASYNC, OK);
7754 ssl_data.next_proto = kProtoHTTP2;
7755 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7756
7757 CreateSession();
7758
7759 request_.url = GURL("https://mail.example.org/");
7760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7761 HeadersHandler headers_handler;
7762 trans.SetBeforeHeadersSentCallback(
7763 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7764 base::Unretained(&headers_handler)));
7765 RunTransaction(&trans);
7766 CheckWasSpdyResponse(&trans);
7767 CheckResponsePort(&trans, 70);
7768 CheckResponseData(&trans, "0123456789");
7769 EXPECT_TRUE(headers_handler.was_proxied());
7770 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7771
Wez0e717112018-06-18 23:09:227772 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7773 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567774 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7775
7776 base::RunLoop().RunUntilIdle();
7777 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7778 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7779}
7780
7781// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7782// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147783TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567784 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147785 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567786 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497787 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567788
7789 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527790 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417791 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567792 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417793 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7794 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337795 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417796 SYNCHRONOUS,
7797 ConstructClientRequestHeadersPacket(
7798 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7799 true, false, ConnectRequestHeaders("mail.example.org:443"),
7800 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337801 mock_quic_data.AddRead(
7802 ASYNC, ConstructServerResponseHeadersPacket(
7803 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7804 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567805
Ryan Hamilton8d9ee76e2018-05-29 23:52:527806 quic::QuicStreamOffset client_data_offset = 0;
7807 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567808 const char get_request_1[] =
7809 "GET / HTTP/1.1\r\n"
7810 "Host: mail.example.org\r\n"
7811 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417812 quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
7813 if (version_ != quic::QUIC_VERSION_99) {
7814 mock_quic_data.AddWrite(
7815 SYNCHRONOUS,
7816 ConstructClientAckAndDataPacket(
7817 write_packet_index++, false,
7818 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7819 client_data_offset, quic::QuicStringPiece(get_request_1)));
7820 } else {
7821 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417822 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357823 ConstructClientAckAndMultipleDataFramesPacket(
7824 write_packet_index++, false,
7825 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7826 client_data_offset, {header, quic::QuicString(get_request_1)}));
Renjief49758b2019-01-11 23:32:417827 }
7828
7829 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567830
7831 const char get_response_1[] =
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_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437835 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417836 ASYNC,
7837 ConstructServerDataPacket(
7838 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7839 server_data_offset, header2 + quic::QuicString(get_response_1)));
7840 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567841
Renjief49758b2019-01-11 23:32:417842 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337843 mock_quic_data.AddRead(
7844 SYNCHRONOUS,
7845 ConstructServerDataPacket(
7846 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417847 server_data_offset, header3 + quic::QuicString("0123456789")));
7848 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567849
Renjief49758b2019-01-11 23:32:417850 mock_quic_data.AddWrite(
7851 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567852
7853 const char get_request_2[] =
7854 "GET /2 HTTP/1.1\r\n"
7855 "Host: mail.example.org\r\n"
7856 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417857 quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
7858 if (version_ == quic::QUIC_VERSION_99) {
7859 mock_quic_data.AddWrite(
7860 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357861 ConstructClientMultipleDataFramesPacket(
7862 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7863 false, false, client_data_offset,
7864 {header4, quic::QuicString(get_request_2)}));
7865 client_data_offset += header4.length() + strlen(get_request_2);
7866 } else {
7867 mock_quic_data.AddWrite(
7868 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417869 ConstructClientDataPacket(write_packet_index++,
7870 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357871 false, false, client_data_offset,
7872 quic::QuicStringPiece(get_request_2)));
7873 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417874 }
Yixin Wang46a273ec302018-01-23 17:59:567875
7876 const char get_response_2[] =
7877 "HTTP/1.1 200 OK\r\n"
7878 "Content-Length: 7\r\n\r\n";
Renjief49758b2019-01-11 23:32:417879 quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437880 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417881 ASYNC,
7882 ConstructServerDataPacket(
7883 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7884 server_data_offset, header5 + quic::QuicString(get_response_2)));
7885 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567886
Renjief49758b2019-01-11 23:32:417887 quic::QuicString header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527888 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337889 SYNCHRONOUS,
7890 ConstructServerDataPacket(
7891 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417892 server_data_offset, header6 + quic::QuicString("0123456")));
7893 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567894
Renjief49758b2019-01-11 23:32:417895 mock_quic_data.AddWrite(
7896 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567897 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7898
Renjief49758b2019-01-11 23:32:417899 mock_quic_data.AddWrite(
7900 SYNCHRONOUS,
7901 ConstructClientRstPacket(
7902 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7903 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567904
7905 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7906
7907 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7908
7909 CreateSession();
7910
7911 request_.url = GURL("https://mail.example.org/");
7912 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7913 HeadersHandler headers_handler_1;
7914 trans_1.SetBeforeHeadersSentCallback(
7915 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7916 base::Unretained(&headers_handler_1)));
7917 RunTransaction(&trans_1);
7918 CheckWasHttpResponse(&trans_1);
7919 CheckResponsePort(&trans_1, 70);
7920 CheckResponseData(&trans_1, "0123456789");
7921 EXPECT_TRUE(headers_handler_1.was_proxied());
7922 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7923
7924 request_.url = GURL("https://mail.example.org/2");
7925 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7926 HeadersHandler headers_handler_2;
7927 trans_2.SetBeforeHeadersSentCallback(
7928 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7929 base::Unretained(&headers_handler_2)));
7930 RunTransaction(&trans_2);
7931 CheckWasHttpResponse(&trans_2);
7932 CheckResponsePort(&trans_2, 70);
7933 CheckResponseData(&trans_2, "0123456");
7934 EXPECT_TRUE(headers_handler_2.was_proxied());
7935 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7936
7937 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7938 // proxy socket to disconnect.
7939 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7940
7941 base::RunLoop().RunUntilIdle();
7942 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7943 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7944}
7945
7946// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7947// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7948// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147949TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567950 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147951 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567952 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497953 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567954
7955 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527956 quic::QuicStreamOffset client_header_stream_offset = 0;
7957 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357958 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7959 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567960
7961 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337962 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357963 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7964 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7965 false, ConnectRequestHeaders("mail.example.org:443"),
7966 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437967 mock_quic_data.AddRead(
7968 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337969 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437970 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567971
7972 // GET request, response, and data over QUIC tunnel for first request
7973 const char get_request[] =
7974 "GET / HTTP/1.1\r\n"
7975 "Host: mail.example.org\r\n"
7976 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417977 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7978 if (version_ != quic::QUIC_VERSION_99) {
7979 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357980 SYNCHRONOUS,
7981 ConstructClientAckAndDataPacket(
7982 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7983 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417984 } else {
7985 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417986 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357987 ConstructClientAckAndMultipleDataFramesPacket(
7988 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7989 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417990 }
7991
Yixin Wang46a273ec302018-01-23 17:59:567992 const char get_response[] =
7993 "HTTP/1.1 200 OK\r\n"
7994 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417995 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567996 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337997 ASYNC, ConstructServerDataPacket(
7998 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417999 0, header2 + quic::QuicString(get_response)));
8000 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338001 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418002 SYNCHRONOUS, ConstructServerDataPacket(
8003 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8004 false, strlen(get_response) + header2.length(),
8005 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358006 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568007
8008 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438009 mock_quic_data.AddWrite(
8010 SYNCHRONOUS,
8011 ConstructClientRequestHeadersPacket(
Renjied172e812019-01-16 05:12:358012 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8013 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:338014 GetNthClientInitiatedBidirectionalStreamId(0),
8015 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438016 mock_quic_data.AddRead(
8017 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338018 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438019 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568020
8021 // GET request, response, and data over QUIC tunnel for second request
8022 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138023 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568024 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:418025 quic::QuicString header4 = ConstructDataHeader(get_frame.size());
8026 if (version_ != quic::QUIC_VERSION_99) {
8027 mock_quic_data.AddWrite(
8028 SYNCHRONOUS,
8029 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:358030 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
8031 false, 0,
Renjief49758b2019-01-11 23:32:418032 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
8033 } else {
8034 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418035 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358036 ConstructClientAckAndMultipleDataFramesPacket(
8037 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
8038 false, 0,
8039 {header4, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418040 }
Yixin Wang46a273ec302018-01-23 17:59:568041
Ryan Hamilton0239aac2018-05-19 00:03:138042 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568043 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:418044 quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438045 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338046 ASYNC,
8047 ConstructServerDataPacket(
8048 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Renjief49758b2019-01-11 23:32:418049 header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568050
Ryan Hamilton0239aac2018-05-19 00:03:138051 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198052 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Renjief49758b2019-01-11 23:32:418053 quic::QuicString header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438054 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418055 ASYNC,
8056 ConstructServerDataPacket(
8057 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8058 resp_frame.size() + header5.length(),
8059 header6 + quic::QuicString(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568060
Renjied172e812019-01-16 05:12:358061 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568062 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8063
8064 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418065 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358066 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
8067 quic::QUIC_STREAM_CANCELLED,
8068 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568069 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438070 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358071 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
8072 quic::QUIC_STREAM_CANCELLED,
8073 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:568074
8075 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8076
8077 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8078
8079 SSLSocketDataProvider ssl_data(ASYNC, OK);
8080 ssl_data.next_proto = kProtoHTTP2;
8081 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8082
8083 CreateSession();
8084
8085 request_.url = GURL("https://mail.example.org/");
8086 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8087 HeadersHandler headers_handler_1;
8088 trans_1.SetBeforeHeadersSentCallback(
8089 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8090 base::Unretained(&headers_handler_1)));
8091 RunTransaction(&trans_1);
8092 CheckWasHttpResponse(&trans_1);
8093 CheckResponsePort(&trans_1, 70);
8094 CheckResponseData(&trans_1, "0123456789");
8095 EXPECT_TRUE(headers_handler_1.was_proxied());
8096 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8097
8098 request_.url = GURL("https://different.example.org/");
8099 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8100 HeadersHandler headers_handler_2;
8101 trans_2.SetBeforeHeadersSentCallback(
8102 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8103 base::Unretained(&headers_handler_2)));
8104 RunTransaction(&trans_2);
8105 CheckWasSpdyResponse(&trans_2);
8106 CheckResponsePort(&trans_2, 70);
8107 CheckResponseData(&trans_2, "0123456");
8108 EXPECT_TRUE(headers_handler_2.was_proxied());
8109 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8110
8111 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8112 // proxy socket to disconnect.
8113 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8114
8115 base::RunLoop().RunUntilIdle();
8116 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8117 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8118}
8119
8120// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148121TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568122 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148123 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568124 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498125 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568126
8127 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528128 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568129 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438130 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528131 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338132 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8133 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8134 false, ConnectRequestHeaders("mail.example.org:443"),
8135 &header_stream_offset));
8136 mock_quic_data.AddRead(
8137 ASYNC, ConstructServerResponseHeadersPacket(
8138 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8139 GetResponseHeaders("500")));
8140 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8141 mock_quic_data.AddWrite(SYNCHRONOUS,
8142 ConstructClientAckAndRstPacket(
8143 3, GetNthClientInitiatedBidirectionalStreamId(0),
8144 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568145
8146 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8147
8148 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8149
8150 CreateSession();
8151
8152 request_.url = GURL("https://mail.example.org/");
8153 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8154 HeadersHandler headers_handler;
8155 trans.SetBeforeHeadersSentCallback(
8156 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8157 base::Unretained(&headers_handler)));
8158 TestCompletionCallback callback;
8159 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8160 EXPECT_EQ(ERR_IO_PENDING, rv);
8161 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8162 EXPECT_EQ(false, headers_handler.was_proxied());
8163
8164 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8165 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8166}
8167
8168// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148169TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568170 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148171 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568172 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498173 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568174
8175 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528176 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568177 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438178 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338179 mock_quic_data.AddWrite(
8180 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8181 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8182 false, ConnectRequestHeaders("mail.example.org:443"),
8183 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568184 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8185
8186 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8187
8188 CreateSession();
8189
8190 request_.url = GURL("https://mail.example.org/");
8191 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8192 HeadersHandler headers_handler;
8193 trans.SetBeforeHeadersSentCallback(
8194 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8195 base::Unretained(&headers_handler)));
8196 TestCompletionCallback callback;
8197 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8198 EXPECT_EQ(ERR_IO_PENDING, rv);
8199 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8200
8201 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8202 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8203}
8204
8205// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8206// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148207TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568208 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148209 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568210 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498211 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568212
8213 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528214 quic::QuicStreamOffset client_header_stream_offset = 0;
8215 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358216 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8217 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338218 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358219 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8220 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8221 false, ConnectRequestHeaders("mail.example.org:443"),
8222 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438223 mock_quic_data.AddRead(
8224 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338225 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438226 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358227 mock_quic_data.AddWrite(SYNCHRONOUS,
8228 ConstructClientAckAndRstPacket(
8229 3, GetNthClientInitiatedBidirectionalStreamId(0),
8230 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568231
Zhongyi Shi32f2fd02018-04-16 18:23:438232 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358233 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8234 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8235 false, ConnectRequestHeaders("mail.example.org:443"),
8236 GetNthClientInitiatedBidirectionalStreamId(0),
8237 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438238 mock_quic_data.AddRead(
8239 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338240 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438241 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568242
8243 const char get_request[] =
8244 "GET / HTTP/1.1\r\n"
8245 "Host: mail.example.org\r\n"
8246 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:418247 quic::QuicString header = ConstructDataHeader(strlen(get_request));
8248 if (version_ != quic::QUIC_VERSION_99) {
8249 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358250 SYNCHRONOUS,
8251 ConstructClientAckAndDataPacket(
8252 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8253 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418254 } else {
8255 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418256 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358257 ConstructClientAckAndMultipleDataFramesPacket(
8258 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8259 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:418260 }
Yixin Wang46a273ec302018-01-23 17:59:568261 const char get_response[] =
8262 "HTTP/1.1 200 OK\r\n"
8263 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:418264 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438265 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338266 ASYNC, ConstructServerDataPacket(
8267 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Renjief49758b2019-01-11 23:32:418268 0, header2 + quic::QuicString(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528269
Renjief49758b2019-01-11 23:32:418270 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338271 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418272 SYNCHRONOUS, ConstructServerDataPacket(
8273 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8274 false, strlen(get_response) + header2.length(),
8275 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358276 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568277 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8278
8279 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418280 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358281 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8282 quic::QUIC_STREAM_CANCELLED,
8283 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568284
8285 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8286
8287 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8288 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8289
8290 SSLSocketDataProvider ssl_data(ASYNC, OK);
8291 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8292
8293 CreateSession();
8294
8295 request_.url = GURL("https://mail.example.org/");
8296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8297 HeadersHandler headers_handler;
8298 trans.SetBeforeHeadersSentCallback(
8299 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8300 base::Unretained(&headers_handler)));
8301 TestCompletionCallback callback;
8302 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8303 EXPECT_EQ(ERR_IO_PENDING, rv);
8304 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8305
8306 rv = trans.RestartIgnoringLastError(callback.callback());
8307 EXPECT_EQ(ERR_IO_PENDING, rv);
8308 EXPECT_EQ(OK, callback.WaitForResult());
8309
8310 CheckWasHttpResponse(&trans);
8311 CheckResponsePort(&trans, 70);
8312 CheckResponseData(&trans, "0123456789");
8313 EXPECT_EQ(true, headers_handler.was_proxied());
8314 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8315
8316 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8317 // proxy socket to disconnect.
8318 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8319
8320 base::RunLoop().RunUntilIdle();
8321 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8322 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8323}
8324
8325// Checks if a request's specified "user-agent" header shows up correctly in the
8326// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148327TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Yixin Wang46a273ec302018-01-23 17:59:568328 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148329 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568330 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498331 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568332
8333 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528334 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568335 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438336 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568337
Ryan Hamilton0239aac2018-05-19 00:03:138338 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568339 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338340 mock_quic_data.AddWrite(
8341 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8342 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8343 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568344 // Return an error, so the transaction stops here (this test isn't interested
8345 // in the rest).
8346 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8347
8348 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8349
8350 CreateSession();
8351
8352 request_.url = GURL("https://mail.example.org/");
8353 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8354 "Chromium Ultra Awesome X Edition");
8355 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8356 HeadersHandler headers_handler;
8357 trans.SetBeforeHeadersSentCallback(
8358 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8359 base::Unretained(&headers_handler)));
8360 TestCompletionCallback callback;
8361 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8362 EXPECT_EQ(ERR_IO_PENDING, rv);
8363 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8364
8365 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8366 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8367}
8368
Yixin Wang00fc44c2018-01-23 21:12:208369// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8370// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148371TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208372 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148373 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208374 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498375 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208376
8377 const RequestPriority request_priority = MEDIUM;
8378
8379 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528380 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208381 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438382 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8383 mock_quic_data.AddWrite(
8384 SYNCHRONOUS,
8385 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338386 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8387 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438388 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208389 // Return an error, so the transaction stops here (this test isn't interested
8390 // in the rest).
8391 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8392
8393 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8394
8395 CreateSession();
8396
8397 request_.url = GURL("https://mail.example.org/");
8398 HttpNetworkTransaction trans(request_priority, session_.get());
8399 TestCompletionCallback callback;
8400 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8401 EXPECT_EQ(ERR_IO_PENDING, rv);
8402 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8403
8404 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8405 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8406}
8407
Yixin Wang46a273ec302018-01-23 17:59:568408// Test the request-challenge-retry sequence for basic auth, over a QUIC
8409// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148410TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568411 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8412 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138413 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568414 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8415
8416 std::unique_ptr<QuicTestPacketMaker> client_maker;
8417 std::unique_ptr<QuicTestPacketMaker> server_maker;
8418
8419 // On the second pass, the body read of the auth challenge is synchronous, so
8420 // IsConnectedAndIdle returns false. The socket should still be drained and
8421 // reused. See http://crbug.com/544255.
8422 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338423 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178424 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8425 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338426 client_headers_include_h2_stream_dependency_));
8427 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178428 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8429 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568430
8431 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148432 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568433 proxy_resolution_service_ =
8434 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498435 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568436
8437 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528438 quic::QuicStreamOffset client_header_stream_offset = 0;
8439 quic::QuicStreamOffset server_header_stream_offset = 0;
8440 quic::QuicStreamOffset client_data_offset = 0;
8441 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568442
Zhongyi Shi32f2fd02018-04-16 18:23:438443 mock_quic_data.AddWrite(SYNCHRONOUS,
8444 client_maker->MakeInitialSettingsPacket(
8445 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568446
8447 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438448 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568449 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338450 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8451 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568452 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8453 &client_header_stream_offset));
8454
Ryan Hamilton0239aac2018-05-19 00:03:138455 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568456 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8457 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8458 headers["content-length"] = "10";
8459 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438460 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338461 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8462 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568463
8464 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438465 mock_quic_data.AddRead(
8466 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338467 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8468 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568469 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438470 mock_quic_data.AddRead(
8471 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338472 2, GetNthClientInitiatedBidirectionalStreamId(0),
8473 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568474 }
8475 server_data_offset += 10;
8476
Zhongyi Shi32f2fd02018-04-16 18:23:438477 mock_quic_data.AddWrite(SYNCHRONOUS,
8478 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568479
8480 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338481 SYNCHRONOUS,
8482 client_maker->MakeRstPacket(
8483 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188484 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8485 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568486
8487 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8488 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8489 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338490 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8491 5, GetNthClientInitiatedBidirectionalStreamId(1),
8492 false, false, default_priority, std::move(headers),
8493 GetNthClientInitiatedBidirectionalStreamId(0),
8494 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568495
8496 // Response to wrong password
8497 headers =
8498 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8499 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8500 headers["content-length"] = "10";
8501 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438502 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338503 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8504 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568505 mock_quic_data.AddRead(SYNCHRONOUS,
8506 ERR_IO_PENDING); // No more data to read
8507
Fan Yang32c5a112018-12-10 20:06:338508 mock_quic_data.AddWrite(
8509 SYNCHRONOUS,
8510 client_maker->MakeAckAndRstPacket(
8511 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8512 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568513
8514 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8515 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8516
8517 CreateSession();
8518
8519 request_.url = GURL("https://mail.example.org/");
8520 // Ensure that proxy authentication is attempted even
8521 // when the no authentication data flag is set.
8522 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8523 {
8524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8525 HeadersHandler headers_handler;
8526 trans.SetBeforeHeadersSentCallback(
8527 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8528 base::Unretained(&headers_handler)));
8529 RunTransaction(&trans);
8530
8531 const HttpResponseInfo* response = trans.GetResponseInfo();
8532 ASSERT_TRUE(response != nullptr);
8533 ASSERT_TRUE(response->headers.get() != nullptr);
8534 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8535 response->headers->GetStatusLine());
8536 EXPECT_TRUE(response->headers->IsKeepAlive());
8537 EXPECT_EQ(407, response->headers->response_code());
8538 EXPECT_EQ(10, response->headers->GetContentLength());
8539 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8540 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8541 ASSERT_TRUE(auth_challenge != nullptr);
8542 EXPECT_TRUE(auth_challenge->is_proxy);
8543 EXPECT_EQ("https://proxy.example.org:70",
8544 auth_challenge->challenger.Serialize());
8545 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8546 EXPECT_EQ("basic", auth_challenge->scheme);
8547
8548 TestCompletionCallback callback;
8549 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8550 callback.callback());
8551 EXPECT_EQ(ERR_IO_PENDING, rv);
8552 EXPECT_EQ(OK, callback.WaitForResult());
8553
8554 response = trans.GetResponseInfo();
8555 ASSERT_TRUE(response != nullptr);
8556 ASSERT_TRUE(response->headers.get() != nullptr);
8557 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8558 response->headers->GetStatusLine());
8559 EXPECT_TRUE(response->headers->IsKeepAlive());
8560 EXPECT_EQ(407, response->headers->response_code());
8561 EXPECT_EQ(10, response->headers->GetContentLength());
8562 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8563 auth_challenge = response->auth_challenge.get();
8564 ASSERT_TRUE(auth_challenge != nullptr);
8565 EXPECT_TRUE(auth_challenge->is_proxy);
8566 EXPECT_EQ("https://proxy.example.org:70",
8567 auth_challenge->challenger.Serialize());
8568 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8569 EXPECT_EQ("basic", auth_challenge->scheme);
8570 }
8571 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8572 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8573 // reused because it's not connected).
8574 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8575 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8576 }
8577}
8578
Yixin Wang385652a2018-02-16 02:37:238579TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8580 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8581 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268582 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238583 !client_headers_include_h2_stream_dependency_) {
8584 return;
8585 }
8586
8587 session_params_.origins_to_force_quic_on.insert(
8588 HostPortPair::FromString("mail.example.org:443"));
8589
Fan Yang32c5a112018-12-10 20:06:338590 const quic::QuicStreamId client_stream_0 =
8591 GetNthClientInitiatedBidirectionalStreamId(0);
8592 const quic::QuicStreamId client_stream_1 =
8593 GetNthClientInitiatedBidirectionalStreamId(1);
8594 const quic::QuicStreamId client_stream_2 =
8595 GetNthClientInitiatedBidirectionalStreamId(2);
8596 const quic::QuicStreamId push_stream_0 =
8597 GetNthServerInitiatedUnidirectionalStreamId(0);
8598 const quic::QuicStreamId push_stream_1 =
8599 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238600
8601 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528602 quic::QuicStreamOffset header_stream_offset = 0;
8603 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238604 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438605 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238606
8607 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438608 mock_quic_data.AddWrite(SYNCHRONOUS,
8609 ConstructClientRequestHeadersPacket(
8610 2, client_stream_0, true, true, HIGHEST,
8611 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8612 &header_stream_offset));
8613 mock_quic_data.AddWrite(SYNCHRONOUS,
8614 ConstructClientRequestHeadersPacket(
8615 3, client_stream_1, true, true, MEDIUM,
8616 GetRequestHeaders("GET", "https", "/1.jpg"),
8617 client_stream_0, &header_stream_offset));
8618 mock_quic_data.AddWrite(SYNCHRONOUS,
8619 ConstructClientRequestHeadersPacket(
8620 4, client_stream_2, true, true, MEDIUM,
8621 GetRequestHeaders("GET", "https", "/2.jpg"),
8622 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238623
8624 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438625 mock_quic_data.AddRead(
8626 ASYNC, ConstructServerResponseHeadersPacket(
8627 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8628 &server_header_offset));
8629 mock_quic_data.AddRead(
8630 ASYNC, ConstructServerResponseHeadersPacket(
8631 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8632 &server_header_offset));
8633 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8634 mock_quic_data.AddRead(
8635 ASYNC, ConstructServerResponseHeadersPacket(
8636 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8637 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238638
8639 // Server sends two push promises associated with |client_stream_0|; client
8640 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8641 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438642 mock_quic_data.AddRead(ASYNC,
8643 ConstructServerPushPromisePacket(
8644 4, client_stream_0, push_stream_0, false,
8645 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8646 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238647 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438648 SYNCHRONOUS,
8649 ConstructClientAckAndPriorityFramesPacket(
8650 6, false, 4, 3, 1,
8651 {{push_stream_0, client_stream_2,
8652 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8653 &header_stream_offset));
8654 mock_quic_data.AddRead(ASYNC,
8655 ConstructServerPushPromisePacket(
8656 5, client_stream_0, push_stream_1, false,
8657 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8658 &server_header_offset, &server_maker_));
8659 mock_quic_data.AddWrite(
8660 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238661 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8662 DEFAULT_PRIORITY, &header_stream_offset));
8663
8664 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438665 mock_quic_data.AddRead(
8666 ASYNC, ConstructServerResponseHeadersPacket(
8667 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8668 &server_header_offset));
8669 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8670 mock_quic_data.AddRead(
8671 ASYNC, ConstructServerResponseHeadersPacket(
8672 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8673 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238674
8675 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8676 // priority updates to match the request's priority. Client sends PRIORITY
8677 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438678 mock_quic_data.AddWrite(
8679 SYNCHRONOUS,
8680 ConstructClientAckAndPriorityFramesPacket(
8681 9, false, 7, 7, 1,
8682 {{push_stream_1, client_stream_2,
8683 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8684 {push_stream_0, client_stream_0,
8685 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8686 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238687
8688 // Server sends data for the three requests and the two push promises.
Renjief49758b2019-01-11 23:32:418689 quic::QuicString header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438690 mock_quic_data.AddRead(
8691 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418692 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438693 mock_quic_data.AddRead(
8694 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418695 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438696 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8697 mock_quic_data.AddRead(
8698 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418699 header + "hello 2!"));
8700 quic::QuicString header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438701 mock_quic_data.AddRead(
8702 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418703 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438704 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8705 mock_quic_data.AddRead(
8706 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418707 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238708
Yixin Wang385652a2018-02-16 02:37:238709 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8710 mock_quic_data.AddRead(ASYNC, 0); // EOF
8711 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8712
8713 // The non-alternate protocol job needs to hang in order to guarantee that
8714 // the alternate-protocol job will "win".
8715 AddHangingNonAlternateProtocolSocketData();
8716
8717 CreateSession();
8718
8719 request_.url = GURL("https://mail.example.org/0.jpg");
8720 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8721 TestCompletionCallback callback_0;
8722 EXPECT_EQ(ERR_IO_PENDING,
8723 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8724 base::RunLoop().RunUntilIdle();
8725
8726 request_.url = GURL("https://mail.example.org/1.jpg");
8727 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8728 TestCompletionCallback callback_1;
8729 EXPECT_EQ(ERR_IO_PENDING,
8730 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8731 base::RunLoop().RunUntilIdle();
8732
8733 request_.url = GURL("https://mail.example.org/2.jpg");
8734 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8735 TestCompletionCallback callback_2;
8736 EXPECT_EQ(ERR_IO_PENDING,
8737 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8738 base::RunLoop().RunUntilIdle();
8739
8740 // Client makes request that matches resource pushed in |pushed_stream_0|.
8741 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8742 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8743 TestCompletionCallback callback_3;
8744 EXPECT_EQ(ERR_IO_PENDING,
8745 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8746 base::RunLoop().RunUntilIdle();
8747
8748 EXPECT_TRUE(callback_0.have_result());
8749 EXPECT_EQ(OK, callback_0.WaitForResult());
8750 EXPECT_TRUE(callback_1.have_result());
8751 EXPECT_EQ(OK, callback_1.WaitForResult());
8752 EXPECT_TRUE(callback_2.have_result());
8753 EXPECT_EQ(OK, callback_2.WaitForResult());
8754
8755 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8756 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8757 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8758 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8759
8760 mock_quic_data.Resume();
8761 base::RunLoop().RunUntilIdle();
8762 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8763 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8764}
8765
[email protected]61a527782013-02-21 03:58:008766} // namespace test
8767} // namespace net