blob: f5bee850067c77d93b8b90e136e7e300bc09e5cd [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 Tambre8c1981d2019-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,
372 bytes_written);
373 }
374
Ryan Hamilton8d9ee76e2018-05-29 23:52:52375 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23376 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
377 uint64_t largest_received,
378 uint64_t smallest_received,
379 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58380 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49381 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20382 }
[email protected]61a527782013-02-21 03:58:00383
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58385 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23386 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23388 uint64_t largest_received,
389 uint64_t smallest_received,
390 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52391 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50392 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58393 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12394 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49395 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12396 }
397
Ryan Hamilton8d9ee76e2018-05-29 23:52:52398 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23399 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12400 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52401 quic::QuicStreamId stream_id,
402 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58403 return server_maker_.MakeRstPacket(num, include_version, stream_id,
404 error_code);
zhongyica364fbb2015-12-12 03:39:12405 }
406
Ryan Hamilton8d9ee76e2018-05-29 23:52:52407 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23408 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36410 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37411 }
412
Ryan Hamilton8d9ee76e2018-05-29 23:52:52413 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23414 uint64_t packet_number,
415 uint64_t largest_received,
416 uint64_t smallest_received,
417 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37418 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49419 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37420 }
421
Ryan Hamilton8d9ee76e2018-05-29 23:52:52422 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23423 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57424 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52425 quic::QuicStreamId id,
426 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57427 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52428 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57429 return client_maker_.MakePriorityPacket(
430 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23431 ConvertRequestPriorityToQuicPriority(request_priority), offset);
432 }
433
Ryan Hamilton8d9ee76e2018-05-29 23:52:52434 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25435 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23436 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23437 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23438 uint64_t largest_received,
439 uint64_t smallest_received,
440 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25441 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
442 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52443 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25444 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23445 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25446 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57447 }
448
zhongyi32569c62016-01-08 02:54:30449 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13450 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
451 const std::string& scheme,
452 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58453 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30454 }
455
456 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13457 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
458 const std::string& scheme,
459 const std::string& path,
460 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50461 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00462 }
463
Ryan Hamilton0239aac2018-05-19 00:03:13464 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56465 return client_maker_.ConnectRequestHeaders(host_port);
466 }
467
Ryan Hamilton0239aac2018-05-19 00:03:13468 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58469 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00470 }
471
zhongyi32569c62016-01-08 02:54:30472 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13473 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
474 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58475 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30476 }
477
Ryan Hamilton8d9ee76e2018-05-29 23:52:52478 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23479 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52480 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05481 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00482 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52483 quic::QuicStreamOffset offset,
484 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58485 return server_maker_.MakeDataPacket(
486 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00487 }
488
Ryan Hamilton8d9ee76e2018-05-29 23:52:52489 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23490 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36492 bool should_include_version,
493 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52494 quic::QuicStreamOffset offset,
495 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36496 return client_maker_.MakeDataPacket(
497 packet_number, stream_id, should_include_version, fin, offset, data);
498 }
499
Renjied172e812019-01-16 05:12:35500 std::unique_ptr<quic::QuicEncryptedPacket>
501 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23502 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35503 quic::QuicStreamId stream_id,
504 bool should_include_version,
505 bool fin,
506 quic::QuicStreamOffset offset,
507 const std::vector<std::string> data_writes) {
508 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
509 should_include_version,
510 fin, offset, data_writes);
511 }
512
Ryan Hamilton8d9ee76e2018-05-29 23:52:52513 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23514 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56515 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52516 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23517 uint64_t largest_received,
518 uint64_t smallest_received,
519 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56520 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52521 quic::QuicStreamOffset offset,
522 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56523 return client_maker_.MakeAckAndDataPacket(
524 packet_number, include_version, stream_id, largest_received,
525 smallest_received, least_unacked, fin, offset, data);
526 }
527
Renjied172e812019-01-16 05:12:35528 std::unique_ptr<quic::QuicEncryptedPacket>
529 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23530 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35531 bool include_version,
532 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23533 uint64_t largest_received,
534 uint64_t smallest_received,
535 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35536 bool fin,
537 quic::QuicStreamOffset offset,
538 const std::vector<std::string> data_writes) {
539 return client_maker_.MakeAckAndMultipleDataFramesPacket(
540 packet_number, include_version, stream_id, largest_received,
541 smallest_received, least_unacked, fin, offset, data_writes);
542 }
543
Ryan Hamilton8d9ee76e2018-05-29 23:52:52544 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23545 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36547 bool should_include_version,
548 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52549 quic::QuicStreamOffset* offset,
550 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36551 return client_maker_.MakeForceHolDataPacket(
552 packet_number, stream_id, should_include_version, fin, offset, data);
553 }
554
Ryan Hamilton8d9ee76e2018-05-29 23:52:52555 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23556 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52557 quic::QuicStreamId stream_id,
558 bool should_include_version,
559 bool fin,
560 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56561 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
562 should_include_version, fin,
563 std::move(headers), nullptr);
564 }
565
Ryan Hamilton8d9ee76e2018-05-29 23:52:52566 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23567 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52568 quic::QuicStreamId stream_id,
569 bool should_include_version,
570 bool fin,
571 spdy::SpdyHeaderBlock headers,
572 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48573 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
574 should_include_version, fin,
575 std::move(headers), 0, offset);
576 }
577
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23579 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52580 quic::QuicStreamId stream_id,
581 bool should_include_version,
582 bool fin,
583 spdy::SpdyHeaderBlock headers,
584 quic::QuicStreamId parent_stream_id,
585 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56586 return ConstructClientRequestHeadersPacket(
587 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48588 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30589 }
590
Ryan Hamilton8d9ee76e2018-05-29 23:52:52591 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23592 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52593 quic::QuicStreamId stream_id,
594 bool should_include_version,
595 bool fin,
596 RequestPriority request_priority,
597 spdy::SpdyHeaderBlock headers,
598 quic::QuicStreamId parent_stream_id,
599 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13600 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56601 ConvertRequestPriorityToQuicPriority(request_priority);
602 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
603 packet_number, stream_id, should_include_version, fin, priority,
604 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00605 }
606
Ryan Hamilton8d9ee76e2018-05-29 23:52:52607 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25608 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23609 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52610 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25611 bool should_include_version,
612 bool fin,
613 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13614 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52615 quic::QuicStreamId parent_stream_id,
616 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25617 size_t* spdy_headers_frame_length,
618 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13619 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25620 ConvertRequestPriorityToQuicPriority(request_priority);
621 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
622 packet_number, stream_id, should_include_version, fin, priority,
623 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
624 data_writes);
625 }
626
Ryan Hamilton8d9ee76e2018-05-29 23:52:52627 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23628 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52629 quic::QuicStreamId stream_id,
630 bool should_include_version,
631 bool fin,
632 const std::vector<std::string>& data,
633 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27634 return client_maker_.MakeMultipleDataFramesPacket(
635 packet_number, stream_id, should_include_version, fin, offset, data);
636 }
637
Ryan Hamilton8d9ee76e2018-05-29 23:52:52638 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23639 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52640 quic::QuicStreamId stream_id,
641 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13642 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13643 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52644 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13645 QuicTestPacketMaker* maker) {
646 return maker->MakePushPromisePacket(
647 packet_number, stream_id, promised_stream_id, should_include_version,
648 false, std::move(headers), nullptr, offset);
649 }
650
Ryan Hamilton8d9ee76e2018-05-29 23:52:52651 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23652 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52653 quic::QuicStreamId stream_id,
654 bool should_include_version,
655 bool fin,
656 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27657 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
658 should_include_version, fin,
659 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30660 }
661
Ryan Hamilton8d9ee76e2018-05-29 23:52:52662 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23663 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52664 quic::QuicStreamId stream_id,
665 bool should_include_version,
666 bool fin,
667 spdy::SpdyHeaderBlock headers,
668 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58669 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25670 packet_number, stream_id, should_include_version, fin,
671 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30672 }
673
Renjief49758b2019-01-11 23:32:41674 quic::QuicString ConstructDataHeader(size_t body_len) {
675 if (version_ != quic::QUIC_VERSION_99) {
676 return "";
677 }
678 quic::HttpEncoder encoder;
679 std::unique_ptr<char[]> buffer;
680 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
681 return quic::QuicString(buffer.get(), header_length);
682 }
683
Ryan Hamilton8d9ee76e2018-05-29 23:52:52684 void CreateSession(
685 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41686 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21687 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05688 session_params_.quic_headers_include_h2_stream_dependency =
689 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00690
mmenke6ddfbea2017-05-31 21:48:41691 session_context_.quic_clock = &clock_;
692 session_context_.quic_random = &random_generator_;
693 session_context_.client_socket_factory = &socket_factory_;
694 session_context_.quic_crypto_client_stream_factory =
695 &crypto_client_stream_factory_;
696 session_context_.host_resolver = &host_resolver_;
697 session_context_.cert_verifier = &cert_verifier_;
698 session_context_.transport_security_state = &transport_security_state_;
699 session_context_.cert_transparency_verifier =
700 cert_transparency_verifier_.get();
701 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
702 session_context_.socket_performance_watcher_factory =
703 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59704 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41705 session_context_.ssl_config_service = ssl_config_service_.get();
706 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
707 session_context_.http_server_properties = &http_server_properties_;
708 session_context_.net_log = net_log_.bound().net_log();
709
710 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12711 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56712 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
713 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00714 }
715
zhongyi86838d52017-06-30 01:19:44716 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21717
bnc691fda62016-08-12 00:43:16718 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19719 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42720 ASSERT_TRUE(response != nullptr);
721 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19722 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
723 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52724 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44725 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19726 response->connection_info);
727 }
728
bnc691fda62016-08-12 00:43:16729 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41730 const HttpResponseInfo* response = trans->GetResponseInfo();
731 ASSERT_TRUE(response != nullptr);
732 EXPECT_EQ(port, response->socket_address.port());
733 }
734
bnc691fda62016-08-12 00:43:16735 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19736 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42737 ASSERT_TRUE(response != nullptr);
738 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19739 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
740 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52741 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52742 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19743 response->connection_info);
744 }
745
Yixin Wang46a273ec302018-01-23 17:59:56746 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
747 const HttpResponseInfo* response = trans->GetResponseInfo();
748 ASSERT_TRUE(response != nullptr);
749 ASSERT_TRUE(response->headers.get() != nullptr);
750 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
751 EXPECT_TRUE(response->was_fetched_via_spdy);
752 EXPECT_TRUE(response->was_alpn_negotiated);
753 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
754 response->connection_info);
755 }
756
bnc691fda62016-08-12 00:43:16757 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19758 const std::string& expected) {
759 std::string response_data;
bnc691fda62016-08-12 00:43:16760 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19761 EXPECT_EQ(expected, response_data);
762 }
763
bnc691fda62016-08-12 00:43:16764 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19765 TestCompletionCallback callback;
766 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01767 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
768 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19769 }
770
771 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16772 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
773 RunTransaction(&trans);
774 CheckWasHttpResponse(&trans);
775 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19776 }
777
tbansalc3308d72016-08-27 10:25:04778 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
779 bool used_proxy,
780 uint16_t port) {
781 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
782 HeadersHandler headers_handler;
783 trans.SetBeforeHeadersSentCallback(
784 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
785 base::Unretained(&headers_handler)));
786 RunTransaction(&trans);
787 CheckWasHttpResponse(&trans);
788 CheckResponsePort(&trans, port);
789 CheckResponseData(&trans, expected);
790 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47791 if (used_proxy) {
792 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
793 } else {
794 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
795 }
tbansalc3308d72016-08-27 10:25:04796 }
797
[email protected]aa9b14d2013-05-10 23:45:19798 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56799 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12800 }
801
bnc62a44f022015-04-02 15:59:41802 void SendRequestAndExpectQuicResponseFromProxyOnPort(
803 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46804 uint16_t port) {
bnc62a44f022015-04-02 15:59:41805 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19806 }
807
808 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27809 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19810 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46811 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21812 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12813 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21814 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44815 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19816 }
817
rchbe69cb902016-02-11 01:10:48818 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27819 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48820 const HostPortPair& alternative) {
821 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46822 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21823 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48824 alternative.port());
825 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21826 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44827 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48828 }
829
[email protected]aa9b14d2013-05-10 23:45:19830 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46831 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34832 const AlternativeServiceInfoVector alternative_service_info_vector =
833 http_server_properties_.GetAlternativeServiceInfos(server);
834 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07835 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54836 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19837 }
838
[email protected]4d590c9c2014-05-02 05:14:33839 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46840 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34841 const AlternativeServiceInfoVector alternative_service_info_vector =
842 http_server_properties_.GetAlternativeServiceInfos(server);
843 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54844 EXPECT_EQ(
845 kProtoQUIC,
846 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23847 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54848 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33849 }
850
[email protected]aa9b14d2013-05-10 23:45:19851 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42852 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30853 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30854 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30855 hanging_data->set_connect_data(hanging_connect);
856 hanging_data_.push_back(std::move(hanging_data));
857 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56858 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19859 }
860
Zhongyi Shia6b68d112018-09-24 07:49:03861 void SetUpTestForRetryConnectionOnAlternateNetwork() {
862 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
863 session_params_.quic_migrate_sessions_early_v2 = true;
864 session_params_.quic_retry_on_alternate_network_before_handshake = true;
865 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
866 MockNetworkChangeNotifier* mock_ncn =
867 scoped_mock_change_notifier_->mock_network_change_notifier();
868 mock_ncn->ForceNetworkHandlesSupported();
869 mock_ncn->SetConnectedNetworksList(
870 {kDefaultNetworkForTests, kNewNetworkForTests});
871 }
872
tbansalc3308d72016-08-27 10:25:04873 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
874 // alternative proxy. Verifies that if the alternative proxy job returns
875 // |error_code|, the request is fetched successfully by the main job.
876 void TestAlternativeProxy(int error_code) {
877 // Use a non-cryptographic scheme for the request URL since this request
878 // will be fetched via proxy with QUIC as the alternative service.
879 request_.url = GURL("http://example.org/");
880 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27881 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04882 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27883 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04884 };
885
Ryan Sleevib8d7ea02018-05-07 20:01:01886 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04887 socket_factory_.AddSocketDataProvider(&quic_data);
888
889 // Main job succeeds and the alternative job fails.
890 // Add data for two requests that will be read by the main job.
891 MockRead http_reads_1[] = {
892 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
893 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
894 MockRead(ASYNC, OK)};
895
896 MockRead http_reads_2[] = {
897 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
898 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
899 MockRead(ASYNC, OK)};
900
Ryan Sleevib8d7ea02018-05-07 20:01:01901 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
902 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04903 socket_factory_.AddSocketDataProvider(&http_data_1);
904 socket_factory_.AddSocketDataProvider(&http_data_2);
905 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
907
908 TestProxyDelegate test_proxy_delegate;
909 // Proxy URL is different from the request URL.
910 test_proxy_delegate.set_alternative_proxy_server(
911 ProxyServer::FromPacString("QUIC myproxy.org:443"));
912
Lily Houghton8c2f97d2018-01-22 05:06:59913 proxy_resolution_service_ =
914 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49915 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52916 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04917
918 CreateSession();
919 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
920
921 // The first request should be fetched via the HTTPS proxy.
922 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
923
Reilly Grant89a7e512018-01-20 01:57:16924 // Since the main job succeeded only the alternative proxy server should be
925 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59926 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16927 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04928
929 // Verify that the second request completes successfully, and the
930 // alternative proxy server job is not started.
931 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
932 }
933
Fan Yang32c5a112018-12-10 20:06:33934 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
935 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36936 }
937
Fan Yang32c5a112018-12-10 20:06:33938 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
939 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36940 }
941
Bence Béky230ac612017-08-30 19:17:08942 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49943 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08944 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49945 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08946 }
947
Ryan Hamilton8d9ee76e2018-05-29 23:52:52948 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05949 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52950 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01951 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52952 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17953 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58954 QuicTestPacketMaker client_maker_;
955 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42956 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00957 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56958 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05959 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43960 MockHostResolver host_resolver_;
961 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11962 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42963 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23964 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38965 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07966 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59967 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42968 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07969 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41970 HttpNetworkSession::Params session_params_;
971 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19972 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51973 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42974 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56975 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03976 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12977
978 private:
979 void SendRequestAndExpectQuicResponseMaybeFromProxy(
980 const std::string& expected,
bnc62a44f022015-04-02 15:59:41981 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46982 uint16_t port) {
bnc691fda62016-08-12 00:43:16983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09984 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16985 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09986 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
987 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16988 RunTransaction(&trans);
989 CheckWasQuicResponse(&trans);
990 CheckResponsePort(&trans, port);
991 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09992 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47993 if (used_proxy) {
994 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
995 } else {
996 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
997 }
tbansal7cec3812015-02-05 21:25:12998 }
[email protected]61a527782013-02-21 03:58:00999};
1000
Victor Costane635086f2019-01-27 05:20:301001INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231002 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051003 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521004 ::testing::Combine(
1005 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1006 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201007
Ryan Hamiltona64a5bcf2017-11-30 07:35:281008TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481009 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281010 base::HistogramTester histograms;
1011 session_params_.origins_to_force_quic_on.insert(
1012 HostPortPair::FromString("mail.example.org:443"));
1013 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271014 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281015
1016 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521017 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281018 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431019 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281020 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1021 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1022 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1023
1024 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1025
1026 CreateSession();
1027
1028 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1029 TestCompletionCallback callback;
1030 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1032 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1033
1034 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1035 -ERR_INTERNET_DISCONNECTED, 1);
1036 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1037 -ERR_INTERNET_DISCONNECTED, 1);
1038}
1039
1040TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481041 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281042 base::HistogramTester histograms;
1043 session_params_.origins_to_force_quic_on.insert(
1044 HostPortPair::FromString("mail.example.org:443"));
1045 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271046 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281047
1048 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521049 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281050 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431051 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281052 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1053 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1054 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1055
1056 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1057
1058 CreateSession();
1059
1060 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1061 TestCompletionCallback callback;
1062 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1064 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1065
1066 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1067 -ERR_INTERNET_DISCONNECTED, 1);
1068 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1069 -ERR_INTERNET_DISCONNECTED, 1);
1070}
1071
tbansal180587c2017-02-16 15:13:231072TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411073 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231074 HostPortPair::FromString("mail.example.org:443"));
1075
1076 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521077 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361078 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431079 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1080 mock_quic_data.AddWrite(
1081 SYNCHRONOUS,
1082 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331083 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431084 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431085 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331086 ASYNC, ConstructServerResponseHeadersPacket(
1087 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1088 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411089 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331090 mock_quic_data.AddRead(
1091 ASYNC, ConstructServerDataPacket(
1092 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411093 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431094 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231095 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1096
1097 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1098
1099 CreateSession();
1100 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1101
1102 EXPECT_FALSE(
1103 test_socket_performance_watcher_factory_.rtt_notification_received());
1104 SendRequestAndExpectQuicResponse("hello!");
1105 EXPECT_TRUE(
1106 test_socket_performance_watcher_factory_.rtt_notification_received());
1107}
1108
1109TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411110 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231111 HostPortPair::FromString("mail.example.org:443"));
1112
1113 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521114 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361115 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431116 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1117 mock_quic_data.AddWrite(
1118 SYNCHRONOUS,
1119 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331120 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431121 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431122 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331123 ASYNC, ConstructServerResponseHeadersPacket(
1124 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1125 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411126 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331127 mock_quic_data.AddRead(
1128 ASYNC, ConstructServerDataPacket(
1129 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411130 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431131 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231132 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1133
1134 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1135
1136 CreateSession();
1137 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1138
1139 EXPECT_FALSE(
1140 test_socket_performance_watcher_factory_.rtt_notification_received());
1141 SendRequestAndExpectQuicResponse("hello!");
1142 EXPECT_FALSE(
1143 test_socket_performance_watcher_factory_.rtt_notification_received());
1144}
1145
[email protected]1e960032013-12-20 19:00:201146TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411147 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571148 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471149
[email protected]1e960032013-12-20 19:00:201150 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521151 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361152 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431153 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1154 mock_quic_data.AddWrite(
1155 SYNCHRONOUS,
1156 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331157 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431158 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431159 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331160 ASYNC, ConstructServerResponseHeadersPacket(
1161 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1162 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411163 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331164 mock_quic_data.AddRead(
1165 ASYNC, ConstructServerDataPacket(
1166 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411167 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431168 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591169 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471170
rcha5399e02015-04-21 19:32:041171 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471172
[email protected]4dca587c2013-03-07 16:54:471173 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471174
[email protected]aa9b14d2013-05-10 23:45:191175 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471176
[email protected]98b20ce2013-05-10 05:55:261177 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461178 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191179 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261180 EXPECT_LT(0u, entries.size());
1181
1182 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291183 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001184 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1185 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261186 EXPECT_LT(0, pos);
1187
rchfd527212015-08-25 00:41:261188 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291189 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261190 entries, 0,
mikecirone8b85c432016-09-08 19:11:001191 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1192 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261193 EXPECT_LT(0, pos);
1194
Eric Romanaefc98c2018-12-18 21:38:011195 int packet_number;
1196 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1197 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261198
rchfd527212015-08-25 00:41:261199 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1200 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001201 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1202 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261203 EXPECT_LT(0, pos);
1204
[email protected]98b20ce2013-05-10 05:55:261205 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291206 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001207 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1208 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261209 EXPECT_LT(0, pos);
1210
1211 int log_stream_id;
1212 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381213 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1214 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471215}
1216
rchbd089ab2017-05-26 23:05:041217TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411218 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041219 HostPortPair::FromString("mail.example.org:443"));
1220
1221 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521222 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041223 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431224 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1225 mock_quic_data.AddWrite(
1226 SYNCHRONOUS,
1227 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331228 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431229 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131230 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041231 response_headers["key1"] = std::string(30000, 'A');
1232 response_headers["key2"] = std::string(30000, 'A');
1233 response_headers["key3"] = std::string(30000, 'A');
1234 response_headers["key4"] = std::string(30000, 'A');
1235 response_headers["key5"] = std::string(30000, 'A');
1236 response_headers["key6"] = std::string(30000, 'A');
1237 response_headers["key7"] = std::string(30000, 'A');
1238 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331239 spdy::SpdyHeadersIR headers_frame(
1240 GetNthClientInitiatedBidirectionalStreamId(0),
1241 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131242 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1243 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041244 response_framer.SerializeFrame(headers_frame);
1245
Fan Yangac867502019-01-28 21:10:231246 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041247 size_t chunk_size = 1200;
1248 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1249 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431250 mock_quic_data.AddRead(
1251 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091252 packet_number++,
1253 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521254 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041255 }
1256
Renjief49758b2019-01-11 23:32:411257 quic::QuicString header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041258 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331259 ASYNC, ConstructServerDataPacket(
1260 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411261 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041262 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431263 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1264 mock_quic_data.AddWrite(ASYNC,
1265 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041266
1267 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1268
1269 CreateSession();
1270
1271 SendRequestAndExpectQuicResponse("hello!");
1272}
1273
1274TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481275 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411276 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041277 HostPortPair::FromString("mail.example.org:443"));
1278
1279 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521280 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041281 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431282 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1283 mock_quic_data.AddWrite(
1284 SYNCHRONOUS,
1285 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331286 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431287 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131288 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041289 response_headers["key1"] = std::string(30000, 'A');
1290 response_headers["key2"] = std::string(30000, 'A');
1291 response_headers["key3"] = std::string(30000, 'A');
1292 response_headers["key4"] = std::string(30000, 'A');
1293 response_headers["key5"] = std::string(30000, 'A');
1294 response_headers["key6"] = std::string(30000, 'A');
1295 response_headers["key7"] = std::string(30000, 'A');
1296 response_headers["key8"] = std::string(30000, 'A');
1297 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331298 spdy::SpdyHeadersIR headers_frame(
1299 GetNthClientInitiatedBidirectionalStreamId(0),
1300 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131301 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1302 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041303 response_framer.SerializeFrame(headers_frame);
1304
Fan Yangac867502019-01-28 21:10:231305 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041306 size_t chunk_size = 1200;
1307 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1308 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431309 mock_quic_data.AddRead(
1310 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091311 packet_number++,
1312 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521313 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041314 }
1315
Renjief49758b2019-01-11 23:32:411316 quic::QuicString header = ConstructDataHeader(6);
1317
rchbd089ab2017-05-26 23:05:041318 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331319 ASYNC, ConstructServerDataPacket(
1320 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411321 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041322 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431323 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1324 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331325 ASYNC, ConstructClientAckAndRstPacket(
1326 4, GetNthClientInitiatedBidirectionalStreamId(0),
1327 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041328
1329 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1330
1331 CreateSession();
1332
1333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1334 TestCompletionCallback callback;
1335 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1336 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1337 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1338}
1339
rcha2bd44b2016-07-02 00:42:551340TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411341 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551342
Ryan Hamilton9835e662018-08-02 05:36:271343 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551344
1345 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521346 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361347 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431348 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1349 mock_quic_data.AddWrite(
1350 SYNCHRONOUS,
1351 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331352 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431353 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431354 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331355 ASYNC, ConstructServerResponseHeadersPacket(
1356 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1357 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411358 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331359 mock_quic_data.AddRead(
1360 ASYNC, ConstructServerDataPacket(
1361 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411362 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431363 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551364 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1365
1366 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1367
1368 CreateSession();
1369
1370 SendRequestAndExpectQuicResponse("hello!");
1371 EXPECT_TRUE(
1372 test_socket_performance_watcher_factory_.rtt_notification_received());
1373}
1374
[email protected]cf3e3cd62014-02-05 16:16:161375TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411376 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591377 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491378 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161379
[email protected]cf3e3cd62014-02-05 16:16:161380 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521381 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361382 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431383 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1384 mock_quic_data.AddWrite(
1385 SYNCHRONOUS,
1386 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331387 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431388 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431389 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331390 ASYNC, ConstructServerResponseHeadersPacket(
1391 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1392 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411393 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331394 mock_quic_data.AddRead(
1395 ASYNC, ConstructServerDataPacket(
1396 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411397 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431398 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501399 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591400 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161401
rcha5399e02015-04-21 19:32:041402 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161403
tbansal0f56a39a2016-04-07 22:03:381404 EXPECT_FALSE(
1405 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161406 // There is no need to set up an alternate protocol job, because
1407 // no attempt will be made to speak to the proxy over TCP.
1408
rch9ae5b3b2016-02-11 00:36:291409 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161410 CreateSession();
1411
bnc62a44f022015-04-02 15:59:411412 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381413 EXPECT_TRUE(
1414 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161415}
1416
bnc313ba9c2015-06-11 15:42:311417// Regression test for https://crbug.com/492458. Test that for an HTTP
1418// connection through a QUIC proxy, the certificate exhibited by the proxy is
1419// checked against the proxy hostname, not the origin hostname.
1420TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291421 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311422 const std::string proxy_host = "www.example.org";
1423
mmenke6ddfbea2017-05-31 21:48:411424 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591425 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491426 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311427
alyssar2adf3ac2016-05-03 17:12:581428 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311429 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521430 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361431 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431432 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1433 mock_quic_data.AddWrite(
1434 SYNCHRONOUS,
1435 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331436 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431437 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431438 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331439 ASYNC, ConstructServerResponseHeadersPacket(
1440 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1441 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411442 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331443 mock_quic_data.AddRead(
1444 ASYNC, ConstructServerDataPacket(
1445 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411446 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431447 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501448 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591449 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311450 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1451
1452 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291453 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311454 ASSERT_TRUE(cert.get());
1455 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241456 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1457 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311458 ProofVerifyDetailsChromium verify_details;
1459 verify_details.cert_verify_result.verified_cert = cert;
1460 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561461 ProofVerifyDetailsChromium verify_details2;
1462 verify_details2.cert_verify_result.verified_cert = cert;
1463 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311464
1465 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091466 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321467 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271468 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311469 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1470}
1471
rchbe69cb902016-02-11 01:10:481472TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341473 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481474 HostPortPair origin("www.example.org", 443);
1475 HostPortPair alternative("mail.example.org", 443);
1476
1477 base::FilePath certs_dir = GetTestCertsDirectory();
1478 scoped_refptr<X509Certificate> cert(
1479 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1480 ASSERT_TRUE(cert.get());
1481 // TODO(rch): the connection should be "to" the origin, so if the cert is
1482 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241483 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1484 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481485 ProofVerifyDetailsChromium verify_details;
1486 verify_details.cert_verify_result.verified_cert = cert;
1487 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1488
alyssar2adf3ac2016-05-03 17:12:581489 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481490 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521491 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361492 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431493 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1494 mock_quic_data.AddWrite(
1495 SYNCHRONOUS,
1496 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331497 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431498 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431499 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331500 ASYNC, ConstructServerResponseHeadersPacket(
1501 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1502 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411503 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331504 mock_quic_data.AddRead(
1505 ASYNC, ConstructServerDataPacket(
1506 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411507 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431508 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481509 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1510 mock_quic_data.AddRead(ASYNC, 0);
1511 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1512
1513 request_.url = GURL("https://" + origin.host());
1514 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271515 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091516 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321517 CreateSession();
rchbe69cb902016-02-11 01:10:481518
1519 SendRequestAndExpectQuicResponse("hello!");
1520}
1521
zhongyief3f4ce52017-07-05 23:53:281522TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521523 quic::QuicTransportVersion unsupported_version =
1524 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281525 // Add support for another QUIC version besides |version_|. Also find a
1526 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521527 for (const quic::QuicTransportVersion& version :
1528 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281529 if (version == version_)
1530 continue;
1531 if (supported_versions_.size() != 2) {
1532 supported_versions_.push_back(version);
1533 continue;
1534 }
1535 unsupported_version = version;
1536 break;
1537 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521538 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281539
1540 // Set up alternative service to use QUIC with a version that is not
1541 // supported.
1542 url::SchemeHostPort server(request_.url);
1543 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1544 443);
1545 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1546 http_server_properties_.SetQuicAlternativeService(
1547 server, alternative_service, expiration, {unsupported_version});
1548
1549 AlternativeServiceInfoVector alt_svc_info_vector =
1550 http_server_properties_.GetAlternativeServiceInfos(server);
1551 EXPECT_EQ(1u, alt_svc_info_vector.size());
1552 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1553 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1554 EXPECT_EQ(unsupported_version,
1555 alt_svc_info_vector[0].advertised_versions()[0]);
1556
1557 // First request should still be sent via TCP as the QUIC version advertised
1558 // in the stored AlternativeService is not supported by the client. However,
1559 // the response from the server will advertise new Alt-Svc with supported
1560 // versions.
1561 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521562 GenerateQuicVersionsListForAltSvcHeader(
1563 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281564 std::string altsvc_header =
1565 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1566 advertised_versions_list_str.c_str());
1567 MockRead http_reads[] = {
1568 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1569 MockRead("hello world"),
1570 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1571 MockRead(ASYNC, OK)};
1572
Ryan Sleevib8d7ea02018-05-07 20:01:011573 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281574 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081575 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281576 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1577
1578 // Second request should be sent via QUIC as a new list of verions supported
1579 // by the client has been advertised by the server.
1580 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521581 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281582 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431583 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1584 mock_quic_data.AddWrite(
1585 SYNCHRONOUS,
1586 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331587 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431588 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431589 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331590 ASYNC, ConstructServerResponseHeadersPacket(
1591 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1592 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411593 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331594 mock_quic_data.AddRead(
1595 ASYNC, ConstructServerDataPacket(
1596 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411597 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431598 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281599 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1600 mock_quic_data.AddRead(ASYNC, 0); // EOF
1601
1602 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1603
1604 AddHangingNonAlternateProtocolSocketData();
1605
1606 CreateSession(supported_versions_);
1607
1608 SendRequestAndExpectHttpResponse("hello world");
1609 SendRequestAndExpectQuicResponse("hello!");
1610
1611 // Check alternative service list is updated with new versions.
1612 alt_svc_info_vector =
1613 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1614 EXPECT_EQ(1u, alt_svc_info_vector.size());
1615 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1616 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1617 // Advertised versions will be lised in a sorted order.
1618 std::sort(supported_versions_.begin(), supported_versions_.end());
1619 EXPECT_EQ(supported_versions_[0],
1620 alt_svc_info_vector[0].advertised_versions()[0]);
1621 EXPECT_EQ(supported_versions_[1],
1622 alt_svc_info_vector[0].advertised_versions()[1]);
1623}
1624
bncaccd4962017-04-06 21:00:261625// Regression test for https://crbug.com/546991.
1626// The server might not be able to serve a request on an alternative connection,
1627// and might send a 421 Misdirected Request response status to indicate this.
1628// HttpNetworkTransaction should reset the request and retry without using
1629// alternative services.
1630TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1631 // Set up alternative service to use QUIC.
1632 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1633 // that overrides |enable_alternative_services|.
1634 url::SchemeHostPort server(request_.url);
1635 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1636 443);
1637 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211638 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441639 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261640
davidbena4449722017-05-05 23:30:531641 // First try: The alternative job uses QUIC and reports an HTTP 421
1642 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1643 // paused at Connect(), so it will never exit the socket pool. This ensures
1644 // that the alternate job always wins the race and keeps whether the
1645 // |http_data| exits the socket pool before the main job is aborted
1646 // deterministic. The first main job gets aborted without the socket pool ever
1647 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261648 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521649 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361650 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431651 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1652 mock_quic_data.AddWrite(
1653 SYNCHRONOUS,
1654 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331655 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431656 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331657 mock_quic_data.AddRead(
1658 ASYNC, ConstructServerResponseHeadersPacket(
1659 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1660 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261661 mock_quic_data.AddRead(ASYNC, OK);
1662 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1663
davidbena4449722017-05-05 23:30:531664 // Second try: The main job uses TCP, and there is no alternate job. Once the
1665 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1666 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261667 // Note that if there was an alternative QUIC Job created for the second try,
1668 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1669 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531670 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1671 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1672 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1673 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1674 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1675 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011676 reads, writes);
bncaccd4962017-04-06 21:00:261677 socket_factory_.AddSocketDataProvider(&http_data);
1678 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1679
bncaccd4962017-04-06 21:00:261680 CreateSession();
1681 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531682
1683 // Run until |mock_quic_data| has failed and |http_data| has paused.
1684 TestCompletionCallback callback;
1685 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1687 base::RunLoop().RunUntilIdle();
1688
1689 // |mock_quic_data| must have run to completion.
1690 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1691 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1692
1693 // Now that the QUIC data has been consumed, unblock |http_data|.
1694 http_data.socket()->OnConnectComplete(MockConnect());
1695
1696 // The retry logic must hide the 421 status. The transaction succeeds on
1697 // |http_data|.
1698 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261699 CheckWasHttpResponse(&trans);
1700 CheckResponsePort(&trans, 443);
1701 CheckResponseData(&trans, "hello!");
1702}
1703
[email protected]1e960032013-12-20 19:00:201704TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411705 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571706 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301707
tbansalfdf5665b2015-09-21 22:46:401708 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521709 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361710 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431711 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401712 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401713 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371714 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361715 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431716 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301717 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401718 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431719 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401720
1721 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1722 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301723
1724 CreateSession();
1725
tbansal0f56a39a2016-04-07 22:03:381726 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401727 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161728 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401729 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161730 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011731 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1732 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381733 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531734
1735 NetErrorDetails details;
1736 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521737 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401738 }
[email protected]cebe3282013-05-22 23:49:301739}
1740
tbansalc8a94ea2015-11-02 23:58:511741TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1742 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411743 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571744 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511745
1746 MockRead http_reads[] = {
1747 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1748 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1749 MockRead(ASYNC, OK)};
1750
Ryan Sleevib8d7ea02018-05-07 20:01:011751 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511752 socket_factory_.AddSocketDataProvider(&data);
1753 SSLSocketDataProvider ssl(ASYNC, OK);
1754 socket_factory_.AddSSLSocketDataProvider(&ssl);
1755
1756 CreateSession();
1757
1758 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381759 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511760}
1761
bncc958faa2015-07-31 18:14:521762TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521763 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561764 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1765 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521766 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1767 MockRead(ASYNC, OK)};
1768
Ryan Sleevib8d7ea02018-05-07 20:01:011769 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521770 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081771 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561772 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521773
1774 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521775 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361776 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431777 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1778 mock_quic_data.AddWrite(
1779 SYNCHRONOUS,
1780 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331781 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431782 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431783 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331784 ASYNC, ConstructServerResponseHeadersPacket(
1785 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1786 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411787 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331788 mock_quic_data.AddRead(
1789 ASYNC, ConstructServerDataPacket(
1790 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411791 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431792 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521793 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591794 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521795
1796 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1797
rtennetib8e80fb2016-05-16 00:12:091798 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321799 CreateSession();
bncc958faa2015-07-31 18:14:521800
1801 SendRequestAndExpectHttpResponse("hello world");
1802 SendRequestAndExpectQuicResponse("hello!");
1803}
1804
zhongyia00ca012017-07-06 23:36:391805TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1806 // Both server advertises and client supports two QUIC versions.
1807 // Only |version_| is advertised and supported.
1808 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1809 // PacketMakers are using |version_|.
1810
1811 // Add support for another QUIC version besides |version_| on the client side.
1812 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521813 quic::QuicTransportVersion advertised_version_2 =
1814 quic::QUIC_VERSION_UNSUPPORTED;
1815 for (const quic::QuicTransportVersion& version :
1816 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391817 if (version == version_)
1818 continue;
1819 if (supported_versions_.size() != 2) {
1820 supported_versions_.push_back(version);
1821 continue;
1822 }
1823 advertised_version_2 = version;
1824 break;
1825 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521826 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391827
1828 std::string QuicAltSvcWithVersionHeader =
1829 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1830 advertised_version_2, version_);
1831
1832 MockRead http_reads[] = {
1833 MockRead("HTTP/1.1 200 OK\r\n"),
1834 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1835 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1836 MockRead(ASYNC, OK)};
1837
Ryan Sleevib8d7ea02018-05-07 20:01:011838 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391839 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081840 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391841 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1842
1843 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521844 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391845 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431846 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1847 mock_quic_data.AddWrite(
1848 SYNCHRONOUS,
1849 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331850 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431851 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431852 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331853 ASYNC, ConstructServerResponseHeadersPacket(
1854 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1855 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411856 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331857 mock_quic_data.AddRead(
1858 ASYNC, ConstructServerDataPacket(
1859 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411860 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431861 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391862 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1863 mock_quic_data.AddRead(ASYNC, 0); // EOF
1864
1865 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1866
1867 AddHangingNonAlternateProtocolSocketData();
1868 CreateSession(supported_versions_);
1869
1870 SendRequestAndExpectHttpResponse("hello world");
1871 SendRequestAndExpectQuicResponse("hello!");
1872}
1873
1874TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1875 // Client and server mutually support more than one QUIC_VERSION.
1876 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1877 // which is verified as the PacketMakers are using |version_|.
1878
Ryan Hamilton8d9ee76e2018-05-29 23:52:521879 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1880 for (const quic::QuicTransportVersion& version :
1881 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391882 if (version == version_)
1883 continue;
1884 common_version_2 = version;
1885 break;
1886 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521887 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391888
1889 supported_versions_.push_back(
1890 common_version_2); // Supported but unpreferred.
1891
1892 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1893 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1894
1895 MockRead http_reads[] = {
1896 MockRead("HTTP/1.1 200 OK\r\n"),
1897 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1898 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1899 MockRead(ASYNC, OK)};
1900
Ryan Sleevib8d7ea02018-05-07 20:01:011901 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391902 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081903 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391904 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1905
1906 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521907 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391908 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431909 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1910 mock_quic_data.AddWrite(
1911 SYNCHRONOUS,
1912 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331913 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431914 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431915 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331916 ASYNC, ConstructServerResponseHeadersPacket(
1917 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1918 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411919 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331920 mock_quic_data.AddRead(
1921 ASYNC, ConstructServerDataPacket(
1922 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411923 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431924 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391925 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1926 mock_quic_data.AddRead(ASYNC, 0); // EOF
1927
1928 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1929
1930 AddHangingNonAlternateProtocolSocketData();
1931 CreateSession(supported_versions_);
1932
1933 SendRequestAndExpectHttpResponse("hello world");
1934 SendRequestAndExpectQuicResponse("hello!");
1935}
1936
rchf47265dc2016-03-21 21:33:121937TEST_P(QuicNetworkTransactionTest,
1938 UseAlternativeServiceWithProbabilityForQuic) {
1939 MockRead http_reads[] = {
1940 MockRead("HTTP/1.1 200 OK\r\n"),
1941 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1942 MockRead("hello world"),
1943 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1944 MockRead(ASYNC, OK)};
1945
Ryan Sleevib8d7ea02018-05-07 20:01:011946 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121947 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081948 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121949 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1950
1951 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521952 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361953 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431954 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1955 mock_quic_data.AddWrite(
1956 SYNCHRONOUS,
1957 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331958 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431959 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431960 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331961 ASYNC, ConstructServerResponseHeadersPacket(
1962 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1963 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411964 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331965 mock_quic_data.AddRead(
1966 ASYNC, ConstructServerDataPacket(
1967 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411968 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431969 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121970 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1971 mock_quic_data.AddRead(ASYNC, 0); // EOF
1972
1973 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1974
rtennetib8e80fb2016-05-16 00:12:091975 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121976 CreateSession();
1977
1978 SendRequestAndExpectHttpResponse("hello world");
1979 SendRequestAndExpectQuicResponse("hello!");
1980}
1981
zhongyi3d4a55e72016-04-22 20:36:461982TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1983 MockRead http_reads[] = {
1984 MockRead("HTTP/1.1 200 OK\r\n"),
1985 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1986 MockRead("hello world"),
1987 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1988 MockRead(ASYNC, OK)};
1989
Ryan Sleevib8d7ea02018-05-07 20:01:011990 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461991 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081992 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461993 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1994
1995 CreateSession();
bncb26024382016-06-29 02:39:451996 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461997 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451998 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:461999 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402000 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462001 session_->http_server_properties();
2002 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2003 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2004 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462005 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342006 2u,
2007 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452008 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342009 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462010}
2011
2012TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2013 MockRead http_reads[] = {
2014 MockRead("HTTP/1.1 200 OK\r\n"),
2015 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2016 MockRead("hello world"),
2017 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2018 MockRead(ASYNC, OK)};
2019
Ryan Sleevib8d7ea02018-05-07 20:01:012020 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082021 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462022
2023 socket_factory_.AddSocketDataProvider(&http_data);
2024 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2025 socket_factory_.AddSocketDataProvider(&http_data);
2026 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2027
2028 CreateSession();
2029
2030 // Send https request and set alternative services if response header
2031 // advertises alternative service for mail.example.org.
2032 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402033 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462034 session_->http_server_properties();
2035
2036 const url::SchemeHostPort https_server(request_.url);
2037 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342038 EXPECT_EQ(
2039 2u,
2040 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462041
2042 // Send http request to the same origin but with diffrent scheme, should not
2043 // use QUIC.
2044 request_.url = GURL("http://mail.example.org:443");
2045 SendRequestAndExpectHttpResponse("hello world");
2046}
2047
zhongyie537a002017-06-27 16:48:212048TEST_P(QuicNetworkTransactionTest,
2049 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442050 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522051 for (const quic::QuicTransportVersion& version :
2052 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442053 if (version == version_)
2054 continue;
2055 supported_versions_.push_back(version);
2056 break;
2057 }
2058
zhongyie537a002017-06-27 16:48:212059 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522060 GenerateQuicVersionsListForAltSvcHeader(
2061 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212062 std::string altsvc_header =
2063 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2064 advertised_versions_list_str.c_str());
2065 MockRead http_reads[] = {
2066 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2067 MockRead("hello world"),
2068 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2069 MockRead(ASYNC, OK)};
2070
Ryan Sleevib8d7ea02018-05-07 20:01:012071 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212072 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082073 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212074 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2075
2076 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522077 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212078 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432079 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2080 mock_quic_data.AddWrite(
2081 SYNCHRONOUS,
2082 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332083 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432084 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432085 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332086 ASYNC, ConstructServerResponseHeadersPacket(
2087 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2088 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412089 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332090 mock_quic_data.AddRead(
2091 ASYNC, ConstructServerDataPacket(
2092 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412093 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432094 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212095 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2096 mock_quic_data.AddRead(ASYNC, 0); // EOF
2097
2098 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2099
2100 AddHangingNonAlternateProtocolSocketData();
2101
zhongyi86838d52017-06-30 01:19:442102 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212103
2104 SendRequestAndExpectHttpResponse("hello world");
2105 SendRequestAndExpectQuicResponse("hello!");
2106
2107 // Check alternative service is set with only mutually supported versions.
2108 const url::SchemeHostPort https_server(request_.url);
2109 const AlternativeServiceInfoVector alt_svc_info_vector =
2110 session_->http_server_properties()->GetAlternativeServiceInfos(
2111 https_server);
2112 EXPECT_EQ(1u, alt_svc_info_vector.size());
2113 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2114 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2115 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442116 std::sort(supported_versions_.begin(), supported_versions_.end());
2117 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212118 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442119 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212120 alt_svc_info_vector[0].advertised_versions()[1]);
2121}
2122
danzh3134c2562016-08-12 14:07:522123TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442124 std::string altsvc_header =
2125 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072126 MockRead http_reads[] = {
2127 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2128 MockRead("hello world"),
2129 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2130 MockRead(ASYNC, OK)};
2131
Ryan Sleevib8d7ea02018-05-07 20:01:012132 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072133 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082134 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072135 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2136
2137 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522138 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362139 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432140 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2141 mock_quic_data.AddWrite(
2142 SYNCHRONOUS,
2143 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332144 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432145 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432146 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332147 ASYNC, ConstructServerResponseHeadersPacket(
2148 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2149 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412150 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332151 mock_quic_data.AddRead(
2152 ASYNC, ConstructServerDataPacket(
2153 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412154 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432155 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072156 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592157 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072158
2159 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2160
rtennetib8e80fb2016-05-16 00:12:092161 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322162 CreateSession();
bnc8be55ebb2015-10-30 14:12:072163
2164 SendRequestAndExpectHttpResponse("hello world");
2165 SendRequestAndExpectQuicResponse("hello!");
2166}
2167
zhongyi6b5a3892016-03-12 04:46:202168TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092169 if (version_ == quic::QUIC_VERSION_99) {
2170 // Not available under version 99
2171 return;
2172 }
zhongyi6b5a3892016-03-12 04:46:202173 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522174 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362175 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432176 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2177 mock_quic_data.AddWrite(
2178 SYNCHRONOUS,
2179 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332180 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432181 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332182 mock_quic_data.AddRead(
2183 ASYNC, ConstructServerResponseHeadersPacket(
2184 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2185 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202186 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522187 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432188 mock_quic_data.AddRead(SYNCHRONOUS,
2189 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522190 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432191 "connection migration with port change only"));
2192 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:412193 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332194 mock_quic_data.AddRead(
2195 SYNCHRONOUS, ConstructServerDataPacket(
2196 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412197 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332198 mock_quic_data.AddWrite(SYNCHRONOUS,
2199 ConstructClientAckAndRstPacket(
2200 4, GetNthClientInitiatedBidirectionalStreamId(0),
2201 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202202 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2203 mock_quic_data.AddRead(ASYNC, 0); // EOF
2204
2205 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2206
2207 // The non-alternate protocol job needs to hang in order to guarantee that
2208 // the alternate-protocol job will "win".
2209 AddHangingNonAlternateProtocolSocketData();
2210
2211 // In order for a new QUIC session to be established via alternate-protocol
2212 // without racing an HTTP connection, we need the host resolution to happen
2213 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2214 // connection to the the server, in this test we require confirmation
2215 // before encrypting so the HTTP job will still start.
2216 host_resolver_.set_synchronous_mode(true);
2217 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2218 "");
2219 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2220 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102221 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582222 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2223 CompletionOnceCallback(), &request,
2224 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412225 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202226
2227 CreateSession();
2228 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272229 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202230
bnc691fda62016-08-12 00:43:162231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202232 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412233 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012234 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202235
2236 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522237 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012238 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202239
2240 // Check whether this transaction is correctly marked as received a go-away
2241 // because of migrating port.
2242 NetErrorDetails details;
2243 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162244 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202245 EXPECT_TRUE(details.quic_port_migration_detected);
2246}
2247
Zhongyi Shia6b68d112018-09-24 07:49:032248// This test verifies that a new QUIC connection will be attempted on the
2249// alternate network if the original QUIC connection fails with idle timeout
2250// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2251// alternate network as well, QUIC is marked as broken and the brokenness will
2252// not expire when default network changes.
2253TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2254 SetUpTestForRetryConnectionOnAlternateNetwork();
2255
2256 std::string request_data;
2257 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2258 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2259
2260 // The request will initially go out over QUIC.
2261 MockQuicData quic_data;
2262 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2263 int packet_num = 1;
2264 quic_data.AddWrite(SYNCHRONOUS,
2265 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2266 // Retranmit the handshake messages.
2267 quic_data.AddWrite(SYNCHRONOUS,
2268 client_maker_.MakeDummyCHLOPacket(packet_num++));
2269 quic_data.AddWrite(SYNCHRONOUS,
2270 client_maker_.MakeDummyCHLOPacket(packet_num++));
2271 quic_data.AddWrite(SYNCHRONOUS,
2272 client_maker_.MakeDummyCHLOPacket(packet_num++));
2273 quic_data.AddWrite(SYNCHRONOUS,
2274 client_maker_.MakeDummyCHLOPacket(packet_num++));
2275 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2276 if (version_ <= quic::QUIC_VERSION_39) {
2277 quic_data.AddWrite(SYNCHRONOUS,
2278 client_maker_.MakeDummyCHLOPacket(packet_num++));
2279 }
2280 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2281 quic_data.AddWrite(SYNCHRONOUS,
2282 client_maker_.MakeConnectionClosePacket(
2283 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2284 "No recent network activity."));
2285 quic_data.AddSocketDataToFactory(&socket_factory_);
2286
2287 // Add successful TCP data so that TCP job will succeed.
2288 MockWrite http_writes[] = {
2289 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2290 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2291 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2292
2293 MockRead http_reads[] = {
2294 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2295 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2296 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2297 SequencedSocketData http_data(http_reads, http_writes);
2298 socket_factory_.AddSocketDataProvider(&http_data);
2299 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2300
2301 // Add data for the second QUIC connection to fail.
2302 MockQuicData quic_data2;
2303 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2304 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2305 quic_data2.AddSocketDataToFactory(&socket_factory_);
2306
2307 // Resolve the host resolution synchronously.
2308 host_resolver_.set_synchronous_mode(true);
2309 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2310 "");
2311 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2312 AddressList address;
2313 std::unique_ptr<HostResolver::Request> request;
2314 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2315 CompletionOnceCallback(), &request,
2316 net_log_.bound());
2317 EXPECT_THAT(rv, IsOk());
2318
2319 CreateSession();
2320 session_->quic_stream_factory()->set_require_confirmation(true);
2321 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2322 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2323 QuicStreamFactoryPeer::SetAlarmFactory(
2324 session_->quic_stream_factory(),
2325 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2326 &clock_));
2327 // Add alternate protocol mapping to race QUIC and TCP.
2328 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2329 // peer.
2330 AddQuicAlternateProtocolMapping(
2331 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2332
2333 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2334 TestCompletionCallback callback;
2335 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2336 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2337
2338 // Pump the message loop to get the request started.
2339 // Request will be served with TCP job.
2340 base::RunLoop().RunUntilIdle();
2341 EXPECT_THAT(callback.WaitForResult(), IsOk());
2342 CheckResponseData(&trans, "TCP succeeds");
2343
2344 // Fire the retransmission alarm, from this point, connection will idle
2345 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062346 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182347 quic_fix_time_of_first_packet_sent_after_receiving)) {
2348 quic_task_runner_->RunNextTask();
2349 }
Zhongyi Shia6b68d112018-09-24 07:49:032350 // Fast forward to idle timeout the original connection. A new connection will
2351 // be kicked off on the alternate network.
2352 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2353 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2354 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2355
2356 // Run the message loop to execute posted tasks, which will report job status.
2357 base::RunLoop().RunUntilIdle();
2358
2359 // Verify that QUIC is marked as broken.
2360 ExpectBrokenAlternateProtocolMapping();
2361
2362 // Deliver a message to notify the new network becomes default, the brokenness
2363 // will not expire as QUIC is broken on both networks.
2364 scoped_mock_change_notifier_->mock_network_change_notifier()
2365 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2366 ExpectBrokenAlternateProtocolMapping();
2367
2368 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2369 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2370}
2371
2372// This test verifies that a new QUIC connection will be attempted on the
2373// alternate network if the original QUIC connection fails with idle timeout
2374// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2375// alternate network, QUIC is marked as broken. The brokenness will expire when
2376// the default network changes.
2377TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2378 SetUpTestForRetryConnectionOnAlternateNetwork();
2379
2380 std::string request_data;
2381 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2382 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2383
2384 // The request will initially go out over QUIC.
2385 MockQuicData quic_data;
2386 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2387 int packet_num = 1;
2388 quic_data.AddWrite(SYNCHRONOUS,
2389 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2390 // Retranmit the handshake messages.
2391 quic_data.AddWrite(SYNCHRONOUS,
2392 client_maker_.MakeDummyCHLOPacket(packet_num++));
2393 quic_data.AddWrite(SYNCHRONOUS,
2394 client_maker_.MakeDummyCHLOPacket(packet_num++));
2395 quic_data.AddWrite(SYNCHRONOUS,
2396 client_maker_.MakeDummyCHLOPacket(packet_num++));
2397 quic_data.AddWrite(SYNCHRONOUS,
2398 client_maker_.MakeDummyCHLOPacket(packet_num++));
2399 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2400 if (version_ <= quic::QUIC_VERSION_39) {
2401 quic_data.AddWrite(SYNCHRONOUS,
2402 client_maker_.MakeDummyCHLOPacket(packet_num++));
2403 }
2404 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2405 quic_data.AddWrite(SYNCHRONOUS,
2406 client_maker_.MakeConnectionClosePacket(
2407 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2408 "No recent network activity."));
2409 quic_data.AddSocketDataToFactory(&socket_factory_);
2410
2411 // Add successful TCP data so that TCP job will succeed.
2412 MockWrite http_writes[] = {
2413 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2414 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2415 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2416
2417 MockRead http_reads[] = {
2418 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2419 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2420 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2421 SequencedSocketData http_data(http_reads, http_writes);
2422 socket_factory_.AddSocketDataProvider(&http_data);
2423 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2424
2425 // Quic connection will be retried on the alternate network after the initial
2426 // one fails on the default network.
2427 MockQuicData quic_data2;
2428 quic::QuicStreamOffset header_stream_offset = 0;
2429 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2430 quic_data2.AddWrite(SYNCHRONOUS,
2431 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2432
2433 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2434 quic_data2.AddWrite(SYNCHRONOUS,
2435 ConstructInitialSettingsPacket(2, &header_stream_offset));
2436 quic_data2.AddSocketDataToFactory(&socket_factory_);
2437
2438 // Resolve the host resolution synchronously.
2439 host_resolver_.set_synchronous_mode(true);
2440 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2441 "");
2442 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2443 AddressList address;
2444 std::unique_ptr<HostResolver::Request> request;
2445 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2446 CompletionOnceCallback(), &request,
2447 net_log_.bound());
2448 EXPECT_THAT(rv, IsOk());
2449
2450 CreateSession();
2451 session_->quic_stream_factory()->set_require_confirmation(true);
2452 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2453 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2454 QuicStreamFactoryPeer::SetAlarmFactory(
2455 session_->quic_stream_factory(),
2456 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2457 &clock_));
2458 // Add alternate protocol mapping to race QUIC and TCP.
2459 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2460 // peer.
2461 AddQuicAlternateProtocolMapping(
2462 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2463
2464 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2465 TestCompletionCallback callback;
2466 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2468
2469 // Pump the message loop to get the request started.
2470 // Request will be served with TCP job.
2471 base::RunLoop().RunUntilIdle();
2472 EXPECT_THAT(callback.WaitForResult(), IsOk());
2473 CheckResponseData(&trans, "TCP succeeds");
2474
2475 // Fire the retransmission alarm, after which connection will idle
2476 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062477 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182478 quic_fix_time_of_first_packet_sent_after_receiving)) {
2479 quic_task_runner_->RunNextTask();
2480 }
Zhongyi Shia6b68d112018-09-24 07:49:032481 // Fast forward to idle timeout the original connection. A new connection will
2482 // be kicked off on the alternate network.
2483 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2484 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2485 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2486
2487 // The second connection hasn't finish handshake, verify that QUIC is not
2488 // marked as broken.
2489 ExpectQuicAlternateProtocolMapping();
2490 // Explicitly confirm the handshake on the second connection.
2491 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2492 quic::QuicSession::HANDSHAKE_CONFIRMED);
2493 // Run message loop to execute posted tasks, which will notify JoController
2494 // about the orphaned job status.
2495 base::RunLoop().RunUntilIdle();
2496
2497 // Verify that QUIC is marked as broken.
2498 ExpectBrokenAlternateProtocolMapping();
2499
2500 // Deliver a message to notify the new network becomes default, the previous
2501 // brokenness will be clear as the brokenness is bond with old default
2502 // network.
2503 scoped_mock_change_notifier_->mock_network_change_notifier()
2504 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2505 ExpectQuicAlternateProtocolMapping();
2506
2507 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2508 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2509}
2510
2511// This test verifies that a new QUIC connection will be attempted on the
2512// alternate network if the original QUIC connection fails with idle timeout
2513// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2514// alternative network succeeds, QUIC is not marked as broken.
2515TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2516 SetUpTestForRetryConnectionOnAlternateNetwork();
2517
2518 std::string request_data;
2519 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2520 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2521
2522 // The request will initially go out over QUIC.
2523 MockQuicData quic_data;
2524 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2525 int packet_num = 1;
2526 quic_data.AddWrite(SYNCHRONOUS,
2527 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2528 // Retranmit the handshake messages.
2529 quic_data.AddWrite(SYNCHRONOUS,
2530 client_maker_.MakeDummyCHLOPacket(packet_num++));
2531 quic_data.AddWrite(SYNCHRONOUS,
2532 client_maker_.MakeDummyCHLOPacket(packet_num++));
2533 quic_data.AddWrite(SYNCHRONOUS,
2534 client_maker_.MakeDummyCHLOPacket(packet_num++));
2535 quic_data.AddWrite(SYNCHRONOUS,
2536 client_maker_.MakeDummyCHLOPacket(packet_num++));
2537 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2538 // quic_fix_has_pending_crypto_data is introduced and enabled.
2539 if (version_ <= quic::QUIC_VERSION_39) {
2540 quic_data.AddWrite(SYNCHRONOUS,
2541 client_maker_.MakeDummyCHLOPacket(packet_num++));
2542 }
2543 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2544 quic_data.AddWrite(SYNCHRONOUS,
2545 client_maker_.MakeConnectionClosePacket(
2546 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2547 "No recent network activity."));
2548 quic_data.AddSocketDataToFactory(&socket_factory_);
2549
2550 // Add hanging TCP data so that TCP job will never succeeded.
2551 AddHangingNonAlternateProtocolSocketData();
2552
2553 // Quic connection will then be retried on the alternate network.
2554 MockQuicData quic_data2;
2555 quic::QuicStreamOffset header_stream_offset = 0;
2556 quic_data2.AddWrite(SYNCHRONOUS,
2557 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2558
Renjief49758b2019-01-11 23:32:412559 const quic::QuicString body = "hello!";
2560 quic::QuicString header = ConstructDataHeader(body.length());
2561
Zhongyi Shia6b68d112018-09-24 07:49:032562 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2563 quic_data2.AddWrite(SYNCHRONOUS,
2564 ConstructInitialSettingsPacket(2, &header_stream_offset));
2565 quic_data2.AddWrite(
2566 SYNCHRONOUS,
2567 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332568 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032569 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032570 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332571 ASYNC, ConstructServerResponseHeadersPacket(
2572 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2573 GetResponseHeaders("200 OK")));
2574 quic_data2.AddRead(
2575 ASYNC, ConstructServerDataPacket(
2576 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412577 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032578 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2579 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2580 quic_data2.AddSocketDataToFactory(&socket_factory_);
2581
2582 // Resolve the host resolution synchronously.
2583 host_resolver_.set_synchronous_mode(true);
2584 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2585 "");
2586 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2587 AddressList address;
2588 std::unique_ptr<HostResolver::Request> request;
2589 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2590 CompletionOnceCallback(), &request,
2591 net_log_.bound());
2592 EXPECT_THAT(rv, IsOk());
2593
2594 CreateSession();
2595 session_->quic_stream_factory()->set_require_confirmation(true);
2596 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2597 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2598 QuicStreamFactoryPeer::SetAlarmFactory(
2599 session_->quic_stream_factory(),
2600 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2601 &clock_));
2602 // Add alternate protocol mapping to race QUIC and TCP.
2603 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2604 // peer.
2605 AddQuicAlternateProtocolMapping(
2606 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2607
2608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2609 TestCompletionCallback callback;
2610 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2612
2613 // Pump the message loop to get the request started.
2614 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062615 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182616 quic_fix_time_of_first_packet_sent_after_receiving)) {
2617 quic_task_runner_->RunNextTask();
2618 }
Zhongyi Shia6b68d112018-09-24 07:49:032619
2620 // Fast forward to idle timeout the original connection. A new connection will
2621 // be kicked off on the alternate network.
2622 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2623 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2624 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2625
2626 // Verify that QUIC is not marked as broken.
2627 ExpectQuicAlternateProtocolMapping();
2628 // Explicitly confirm the handshake on the second connection.
2629 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2630 quic::QuicSession::HANDSHAKE_CONFIRMED);
2631
2632 // Read the response.
2633 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412634 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032635 // Verify that QUIC is not marked as broken.
2636 ExpectQuicAlternateProtocolMapping();
2637
2638 // Deliver a message to notify the new network becomes default.
2639 scoped_mock_change_notifier_->mock_network_change_notifier()
2640 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2641 ExpectQuicAlternateProtocolMapping();
2642 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2643 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2644}
2645
rch9ecde09b2017-04-08 00:18:232646// Verify that if a QUIC connection times out, the QuicHttpStream will
2647// return QUIC_PROTOCOL_ERROR.
2648TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482649 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412650 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232651
2652 // The request will initially go out over QUIC.
2653 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522654 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132655 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232656 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2657
2658 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522659 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2660 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432661 quic_data.AddWrite(SYNCHRONOUS,
2662 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332663 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2664 true, priority, GetRequestHeaders("GET", "https", "/"),
2665 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232666
2667 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522668 quic::QuicStreamOffset settings_offset = header_stream_offset;
2669 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432670 quic_data.AddWrite(SYNCHRONOUS,
2671 client_maker_.MakeInitialSettingsPacketAndSaveData(
2672 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232673 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092674 quic_data.AddWrite(SYNCHRONOUS,
2675 client_maker_.MakeDataPacket(
2676 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2677 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232678 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092679 quic_data.AddWrite(SYNCHRONOUS,
2680 client_maker_.MakeDataPacket(
2681 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2682 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232683 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092684 quic_data.AddWrite(SYNCHRONOUS,
2685 client_maker_.MakeDataPacket(
2686 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2687 false, 0, request_data));
2688 quic_data.AddWrite(SYNCHRONOUS,
2689 client_maker_.MakeDataPacket(
2690 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2691 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232692 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092693 quic_data.AddWrite(SYNCHRONOUS,
2694 client_maker_.MakeDataPacket(
2695 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2696 false, 0, request_data));
2697 quic_data.AddWrite(SYNCHRONOUS,
2698 client_maker_.MakeDataPacket(
2699 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2700 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232701 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092702 quic_data.AddWrite(SYNCHRONOUS,
2703 client_maker_.MakeDataPacket(
2704 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2705 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522706 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092707 SYNCHRONOUS, client_maker_.MakeDataPacket(
2708 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2709 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232710
Zhongyi Shi32f2fd02018-04-16 18:23:432711 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522712 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432713 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222714
rch9ecde09b2017-04-08 00:18:232715 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2716 quic_data.AddRead(ASYNC, OK);
2717 quic_data.AddSocketDataToFactory(&socket_factory_);
2718
2719 // In order for a new QUIC session to be established via alternate-protocol
2720 // without racing an HTTP connection, we need the host resolution to happen
2721 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2722 // connection to the the server, in this test we require confirmation
2723 // before encrypting so the HTTP job will still start.
2724 host_resolver_.set_synchronous_mode(true);
2725 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2726 "");
2727 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2728 AddressList address;
2729 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582730 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2731 CompletionOnceCallback(), &request,
2732 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412733 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232734
2735 CreateSession();
2736 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552737 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232738 QuicStreamFactoryPeer::SetAlarmFactory(
2739 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192740 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552741 &clock_));
rch9ecde09b2017-04-08 00:18:232742
Ryan Hamilton9835e662018-08-02 05:36:272743 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232744
2745 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2746 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412747 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2749
2750 // Pump the message loop to get the request started.
2751 base::RunLoop().RunUntilIdle();
2752 // Explicitly confirm the handshake.
2753 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522754 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232755
2756 // Run the QUIC session to completion.
2757 quic_task_runner_->RunUntilIdle();
2758
2759 ExpectQuicAlternateProtocolMapping();
2760 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2761 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2762}
2763
2764// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2765// return QUIC_PROTOCOL_ERROR.
2766TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482767 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522768 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232769
2770 // The request will initially go out over QUIC.
2771 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522772 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132773 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232774 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2775
2776 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522777 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2778 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432779 quic_data.AddWrite(SYNCHRONOUS,
2780 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332781 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2782 true, priority, GetRequestHeaders("GET", "https", "/"),
2783 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232784
2785 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522786 quic::QuicStreamOffset settings_offset = header_stream_offset;
2787 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432788 quic_data.AddWrite(SYNCHRONOUS,
2789 client_maker_.MakeInitialSettingsPacketAndSaveData(
2790 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232791 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092792 quic_data.AddWrite(SYNCHRONOUS,
2793 client_maker_.MakeDataPacket(
2794 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2795 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232796 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092797 quic_data.AddWrite(SYNCHRONOUS,
2798 client_maker_.MakeDataPacket(
2799 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2800 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232801 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092802 quic_data.AddWrite(SYNCHRONOUS,
2803 client_maker_.MakeDataPacket(
2804 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2805 false, 0, request_data));
2806 quic_data.AddWrite(SYNCHRONOUS,
2807 client_maker_.MakeDataPacket(
2808 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2809 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232810 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092811 quic_data.AddWrite(SYNCHRONOUS,
2812 client_maker_.MakeDataPacket(
2813 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2814 false, 0, request_data));
2815 quic_data.AddWrite(SYNCHRONOUS,
2816 client_maker_.MakeDataPacket(
2817 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2818 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232819 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092820 quic_data.AddWrite(SYNCHRONOUS,
2821 client_maker_.MakeDataPacket(
2822 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2823 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522824 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092825 SYNCHRONOUS, client_maker_.MakeDataPacket(
2826 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2827 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232828 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522829 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092830 SYNCHRONOUS, client_maker_.MakeDataPacket(
2831 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2832 false, 0, request_data));
2833 quic_data.AddWrite(
2834 SYNCHRONOUS, client_maker_.MakeDataPacket(
2835 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2836 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232837 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432838 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522839 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432840 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232841
2842 quic_data.AddRead(ASYNC, OK);
2843 quic_data.AddSocketDataToFactory(&socket_factory_);
2844
2845 // In order for a new QUIC session to be established via alternate-protocol
2846 // without racing an HTTP connection, we need the host resolution to happen
2847 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2848 // connection to the the server, in this test we require confirmation
2849 // before encrypting so the HTTP job will still start.
2850 host_resolver_.set_synchronous_mode(true);
2851 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2852 "");
2853 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2854 AddressList address;
2855 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582856 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2857 CompletionOnceCallback(), &request,
2858 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412859 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232860
2861 CreateSession();
2862 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552863 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232864 QuicStreamFactoryPeer::SetAlarmFactory(
2865 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192866 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552867 &clock_));
rch9ecde09b2017-04-08 00:18:232868
Ryan Hamilton9835e662018-08-02 05:36:272869 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232870
2871 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2872 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412873 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232874 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2875
2876 // Pump the message loop to get the request started.
2877 base::RunLoop().RunUntilIdle();
2878 // Explicitly confirm the handshake.
2879 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522880 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232881
2882 // Run the QUIC session to completion.
2883 quic_task_runner_->RunUntilIdle();
2884
2885 ExpectQuicAlternateProtocolMapping();
2886 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2887 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2888}
2889
2890// Verify that if a QUIC connection RTOs, while there are no active streams
2891// QUIC will not be marked as broken.
2892TEST_P(QuicNetworkTransactionTest,
2893 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522894 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232895
2896 // The request will initially go out over QUIC.
2897 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522898 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132899 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232900 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2901
2902 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522903 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2904 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432905 quic_data.AddWrite(SYNCHRONOUS,
2906 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332907 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2908 true, priority, GetRequestHeaders("GET", "https", "/"),
2909 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232910
2911 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522912 quic::QuicStreamOffset settings_offset = header_stream_offset;
2913 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432914 quic_data.AddWrite(SYNCHRONOUS,
2915 client_maker_.MakeInitialSettingsPacketAndSaveData(
2916 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232917
Fan Yang32c5a112018-12-10 20:06:332918 quic_data.AddWrite(SYNCHRONOUS,
2919 client_maker_.MakeRstPacket(
2920 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2921 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232922 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092923 quic_data.AddWrite(SYNCHRONOUS,
2924 client_maker_.MakeDataPacket(
2925 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2926 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232927 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092928 quic_data.AddWrite(SYNCHRONOUS,
2929 client_maker_.MakeDataPacket(
2930 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2931 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232932 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332933 quic_data.AddWrite(SYNCHRONOUS,
2934 client_maker_.MakeRstPacket(
2935 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2936 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092937 quic_data.AddWrite(SYNCHRONOUS,
2938 client_maker_.MakeDataPacket(
2939 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2940 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232941 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092942 quic_data.AddWrite(SYNCHRONOUS,
2943 client_maker_.MakeDataPacket(
2944 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2945 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332946 quic_data.AddWrite(SYNCHRONOUS,
2947 client_maker_.MakeRstPacket(
2948 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2949 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232950 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522951 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092952 SYNCHRONOUS, client_maker_.MakeDataPacket(
2953 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2954 false, 0, request_data));
2955 quic_data.AddWrite(
2956 SYNCHRONOUS, client_maker_.MakeDataPacket(
2957 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2958 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232959 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432960 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332961 SYNCHRONOUS, client_maker_.MakeRstPacket(
2962 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2963 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522964 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092965 SYNCHRONOUS, client_maker_.MakeDataPacket(
2966 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2967 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232968 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432969 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522970 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432971 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232972
2973 quic_data.AddRead(ASYNC, OK);
2974 quic_data.AddSocketDataToFactory(&socket_factory_);
2975
2976 // In order for a new QUIC session to be established via alternate-protocol
2977 // without racing an HTTP connection, we need the host resolution to happen
2978 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2979 // connection to the the server, in this test we require confirmation
2980 // before encrypting so the HTTP job will still start.
2981 host_resolver_.set_synchronous_mode(true);
2982 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2983 "");
2984 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2985 AddressList address;
2986 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582987 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2988 CompletionOnceCallback(), &request,
2989 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412990 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232991
2992 CreateSession();
2993 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552994 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232995 QuicStreamFactoryPeer::SetAlarmFactory(
2996 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192997 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552998 &clock_));
rch9ecde09b2017-04-08 00:18:232999
Ryan Hamilton9835e662018-08-02 05:36:273000 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233001
Jeremy Roman0579ed62017-08-29 15:56:193002 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233003 session_.get());
3004 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413005 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3007
3008 // Pump the message loop to get the request started.
3009 base::RunLoop().RunUntilIdle();
3010 // Explicitly confirm the handshake.
3011 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523012 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233013
3014 // Now cancel the request.
3015 trans.reset();
3016
3017 // Run the QUIC session to completion.
3018 quic_task_runner_->RunUntilIdle();
3019
3020 ExpectQuicAlternateProtocolMapping();
3021
3022 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3023}
3024
rch2f2991c2017-04-13 19:28:173025// Verify that if a QUIC protocol error occurs after the handshake is confirmed
3026// the request fails with QUIC_PROTOCOL_ERROR.
3027TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:483028 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:173029 // The request will initially go out over QUIC.
3030 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523031 quic::QuicStreamOffset header_stream_offset = 0;
3032 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3033 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433034 quic_data.AddWrite(
3035 SYNCHRONOUS,
3036 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333037 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433038 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523039 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433040 quic_data.AddWrite(SYNCHRONOUS,
3041 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173042 // Peer sending data from an non-existing stream causes this end to raise
3043 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333044 quic_data.AddRead(
3045 ASYNC, ConstructServerRstPacket(
3046 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3047 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173048 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433049 quic_data.AddWrite(SYNCHRONOUS,
3050 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523051 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3052 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173053 quic_data.AddSocketDataToFactory(&socket_factory_);
3054
3055 // In order for a new QUIC session to be established via alternate-protocol
3056 // without racing an HTTP connection, we need the host resolution to happen
3057 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3058 // connection to the the server, in this test we require confirmation
3059 // before encrypting so the HTTP job will still start.
3060 host_resolver_.set_synchronous_mode(true);
3061 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3062 "");
3063 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3064 AddressList address;
3065 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583066 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3067 CompletionOnceCallback(), &request,
3068 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413069 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173070
3071 CreateSession();
3072
Ryan Hamilton9835e662018-08-02 05:36:273073 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173074
3075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3076 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413077 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173078 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3079
3080 // Pump the message loop to get the request started.
3081 base::RunLoop().RunUntilIdle();
3082 // Explicitly confirm the handshake.
3083 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523084 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173085
3086 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3087
3088 // Run the QUIC session to completion.
3089 base::RunLoop().RunUntilIdle();
3090 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3091 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3092
3093 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3094 ExpectQuicAlternateProtocolMapping();
3095 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3096}
3097
rch9ecde09b2017-04-08 00:18:233098// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3099// connection times out, then QUIC will be marked as broken and the request
3100// retried over TCP.
3101TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413102 session_params_.mark_quic_broken_when_network_blackholes = true;
3103 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233104
3105 // The request will initially go out over QUIC.
3106 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523107 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133108 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233109 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3110
3111 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523112 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3113 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433114 quic_data.AddWrite(SYNCHRONOUS,
3115 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333116 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3117 true, priority, GetRequestHeaders("GET", "https", "/"),
3118 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233119
3120 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523121 quic::QuicStreamOffset settings_offset = header_stream_offset;
3122 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433123 quic_data.AddWrite(SYNCHRONOUS,
3124 client_maker_.MakeInitialSettingsPacketAndSaveData(
3125 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233126 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093127 quic_data.AddWrite(SYNCHRONOUS,
3128 client_maker_.MakeDataPacket(
3129 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3130 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233131 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093132 quic_data.AddWrite(SYNCHRONOUS,
3133 client_maker_.MakeDataPacket(
3134 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3135 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233136 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093137 quic_data.AddWrite(SYNCHRONOUS,
3138 client_maker_.MakeDataPacket(
3139 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3140 false, 0, request_data));
3141 quic_data.AddWrite(SYNCHRONOUS,
3142 client_maker_.MakeDataPacket(
3143 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3144 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233145 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093146 quic_data.AddWrite(SYNCHRONOUS,
3147 client_maker_.MakeDataPacket(
3148 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3149 false, 0, request_data));
3150 quic_data.AddWrite(SYNCHRONOUS,
3151 client_maker_.MakeDataPacket(
3152 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3153 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233154 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093155 quic_data.AddWrite(SYNCHRONOUS,
3156 client_maker_.MakeDataPacket(
3157 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3158 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523159 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093160 SYNCHRONOUS, client_maker_.MakeDataPacket(
3161 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3162 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233163
Zhongyi Shi32f2fd02018-04-16 18:23:433164 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523165 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433166 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223167
rch9ecde09b2017-04-08 00:18:233168 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3169 quic_data.AddRead(ASYNC, OK);
3170 quic_data.AddSocketDataToFactory(&socket_factory_);
3171
3172 // After that fails, it will be resent via TCP.
3173 MockWrite http_writes[] = {
3174 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3175 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3176 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3177
3178 MockRead http_reads[] = {
3179 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3180 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3181 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013182 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233183 socket_factory_.AddSocketDataProvider(&http_data);
3184 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3185
3186 // In order for a new QUIC session to be established via alternate-protocol
3187 // without racing an HTTP connection, we need the host resolution to happen
3188 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3189 // connection to the the server, in this test we require confirmation
3190 // before encrypting so the HTTP job will still start.
3191 host_resolver_.set_synchronous_mode(true);
3192 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3193 "");
3194 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3195 AddressList address;
3196 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583197 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3198 CompletionOnceCallback(), &request,
3199 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413200 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233201
3202 CreateSession();
3203 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553204 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233205 QuicStreamFactoryPeer::SetAlarmFactory(
3206 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193207 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553208 &clock_));
rch9ecde09b2017-04-08 00:18:233209
Ryan Hamilton9835e662018-08-02 05:36:273210 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233211
3212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3213 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413214 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3216
3217 // Pump the message loop to get the request started.
3218 base::RunLoop().RunUntilIdle();
3219 // Explicitly confirm the handshake.
3220 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523221 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233222
3223 // Run the QUIC session to completion.
3224 quic_task_runner_->RunUntilIdle();
3225 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3226
3227 // Let the transaction proceed which will result in QUIC being marked
3228 // as broken and the request falling back to TCP.
3229 EXPECT_THAT(callback.WaitForResult(), IsOk());
3230
3231 ExpectBrokenAlternateProtocolMapping();
3232 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3233 ASSERT_FALSE(http_data.AllReadDataConsumed());
3234
3235 // Read the response body over TCP.
3236 CheckResponseData(&trans, "hello world");
3237 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3238 ASSERT_TRUE(http_data.AllReadDataConsumed());
3239}
3240
rch2f2991c2017-04-13 19:28:173241// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3242// connection times out, then QUIC will be marked as broken and the request
3243// retried over TCP.
3244TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413245 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173246
3247 // The request will initially go out over QUIC.
3248 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523249 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133250 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173251 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3252
3253 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523254 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3255 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433256 quic_data.AddWrite(SYNCHRONOUS,
3257 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333258 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3259 true, priority, GetRequestHeaders("GET", "https", "/"),
3260 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173261
3262 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523263 quic::QuicStreamOffset settings_offset = header_stream_offset;
3264 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433265 quic_data.AddWrite(SYNCHRONOUS,
3266 client_maker_.MakeInitialSettingsPacketAndSaveData(
3267 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173268 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093269 quic_data.AddWrite(SYNCHRONOUS,
3270 client_maker_.MakeDataPacket(
3271 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3272 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173273 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093274 quic_data.AddWrite(SYNCHRONOUS,
3275 client_maker_.MakeDataPacket(
3276 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3277 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173278 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093279 quic_data.AddWrite(SYNCHRONOUS,
3280 client_maker_.MakeDataPacket(
3281 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3282 false, 0, request_data));
3283 quic_data.AddWrite(SYNCHRONOUS,
3284 client_maker_.MakeDataPacket(
3285 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3286 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173287 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093288 quic_data.AddWrite(SYNCHRONOUS,
3289 client_maker_.MakeDataPacket(
3290 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3291 false, 0, request_data));
3292 quic_data.AddWrite(SYNCHRONOUS,
3293 client_maker_.MakeDataPacket(
3294 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3295 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173296 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093297 quic_data.AddWrite(SYNCHRONOUS,
3298 client_maker_.MakeDataPacket(
3299 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3300 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523301 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093302 SYNCHRONOUS, client_maker_.MakeDataPacket(
3303 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3304 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173305
Zhongyi Shi32f2fd02018-04-16 18:23:433306 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523307 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433308 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223309
rch2f2991c2017-04-13 19:28:173310 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3311 quic_data.AddRead(ASYNC, OK);
3312 quic_data.AddSocketDataToFactory(&socket_factory_);
3313
3314 // After that fails, it will be resent via TCP.
3315 MockWrite http_writes[] = {
3316 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3317 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3318 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3319
3320 MockRead http_reads[] = {
3321 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3322 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3323 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013324 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173325 socket_factory_.AddSocketDataProvider(&http_data);
3326 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3327
3328 // In order for a new QUIC session to be established via alternate-protocol
3329 // without racing an HTTP connection, we need the host resolution to happen
3330 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3331 // connection to the the server, in this test we require confirmation
3332 // before encrypting so the HTTP job will still start.
3333 host_resolver_.set_synchronous_mode(true);
3334 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3335 "");
3336 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3337 AddressList address;
3338 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583339 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3340 CompletionOnceCallback(), &request,
3341 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413342 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173343
3344 CreateSession();
3345 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553346 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173347 QuicStreamFactoryPeer::SetAlarmFactory(
3348 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193349 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553350 &clock_));
rch2f2991c2017-04-13 19:28:173351
Ryan Hamilton9835e662018-08-02 05:36:273352 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173353
3354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3355 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413356 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3358
3359 // Pump the message loop to get the request started.
3360 base::RunLoop().RunUntilIdle();
3361 // Explicitly confirm the handshake.
3362 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523363 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173364
3365 // Run the QUIC session to completion.
3366 quic_task_runner_->RunUntilIdle();
3367 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3368
3369 ExpectQuicAlternateProtocolMapping();
3370
3371 // Let the transaction proceed which will result in QUIC being marked
3372 // as broken and the request falling back to TCP.
3373 EXPECT_THAT(callback.WaitForResult(), IsOk());
3374
3375 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3376 ASSERT_FALSE(http_data.AllReadDataConsumed());
3377
3378 // Read the response body over TCP.
3379 CheckResponseData(&trans, "hello world");
3380 ExpectBrokenAlternateProtocolMapping();
3381 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3382 ASSERT_TRUE(http_data.AllReadDataConsumed());
3383}
3384
rch9ecde09b2017-04-08 00:18:233385// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3386// connection times out, then QUIC will be marked as broken but the request
3387// will not be retried over TCP.
3388TEST_P(QuicNetworkTransactionTest,
3389 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413390 session_params_.mark_quic_broken_when_network_blackholes = true;
3391 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233392
3393 // The request will initially go out over QUIC.
3394 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523395 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133396 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233397 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3398
3399 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523400 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3401 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433402 quic_data.AddWrite(SYNCHRONOUS,
3403 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333404 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3405 true, priority, GetRequestHeaders("GET", "https", "/"),
3406 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233407
3408 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523409 quic::QuicStreamOffset settings_offset = header_stream_offset;
3410 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433411 quic_data.AddWrite(SYNCHRONOUS,
3412 client_maker_.MakeInitialSettingsPacketAndSaveData(
3413 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233414
Zhongyi Shi32f2fd02018-04-16 18:23:433415 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333416 1, GetNthClientInitiatedBidirectionalStreamId(0),
3417 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433418 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523419 quic_data.AddWrite(
3420 SYNCHRONOUS,
3421 ConstructClientAckPacket(3, 1, 1, 1,
3422 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233423
3424 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523425 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093426 SYNCHRONOUS, client_maker_.MakeDataPacket(
3427 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3428 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233429 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093430 quic_data.AddWrite(
3431 SYNCHRONOUS, client_maker_.MakeDataPacket(
3432 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3433 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233434 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523435 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093436 SYNCHRONOUS, client_maker_.MakeDataPacket(
3437 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3438 false, 0, request_data));
3439 quic_data.AddWrite(
3440 SYNCHRONOUS, client_maker_.MakeDataPacket(
3441 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3442 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233443 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523444 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093445 SYNCHRONOUS, client_maker_.MakeDataPacket(
3446 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3447 false, 0, request_data));
3448 quic_data.AddWrite(
3449 SYNCHRONOUS, client_maker_.MakeDataPacket(
3450 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3451 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233452 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523453 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093454 SYNCHRONOUS, client_maker_.MakeDataPacket(
3455 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3456 false, 0, request_data));
3457 quic_data.AddWrite(
3458 SYNCHRONOUS, client_maker_.MakeDataPacket(
3459 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3460 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233461
Michael Warres112212822018-12-26 17:51:063462 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183463 quic_fix_time_of_first_packet_sent_after_receiving)) {
3464 quic_data.AddWrite(
3465 SYNCHRONOUS,
3466 client_maker_.MakeAckAndConnectionClosePacket(
3467 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3468 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3469
3470 } else {
3471 quic_data.AddWrite(
3472 SYNCHRONOUS,
3473 client_maker_.MakeAckAndConnectionClosePacket(
3474 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3475 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3476 }
Fan Yang928f1632017-12-14 18:55:223477
rch9ecde09b2017-04-08 00:18:233478 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3479 quic_data.AddRead(ASYNC, OK);
3480 quic_data.AddSocketDataToFactory(&socket_factory_);
3481
3482 // In order for a new QUIC session to be established via alternate-protocol
3483 // without racing an HTTP connection, we need the host resolution to happen
3484 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3485 // connection to the the server, in this test we require confirmation
3486 // before encrypting so the HTTP job will still start.
3487 host_resolver_.set_synchronous_mode(true);
3488 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3489 "");
3490 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3491 AddressList address;
3492 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583493 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3494 CompletionOnceCallback(), &request,
3495 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413496 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233497
3498 CreateSession();
3499 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553500 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233501 QuicStreamFactoryPeer::SetAlarmFactory(
3502 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193503 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553504 &clock_));
rch9ecde09b2017-04-08 00:18:233505
Ryan Hamilton9835e662018-08-02 05:36:273506 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233507
3508 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3509 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413510 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233511 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3512
3513 // Pump the message loop to get the request started.
3514 base::RunLoop().RunUntilIdle();
3515 // Explicitly confirm the handshake.
3516 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523517 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233518
3519 // Pump the message loop to get the request started.
3520 base::RunLoop().RunUntilIdle();
3521
3522 // Run the QUIC session to completion.
3523 quic_task_runner_->RunUntilIdle();
3524 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3525
3526 // Let the transaction proceed which will result in QUIC being marked
3527 // as broken and the request falling back to TCP.
3528 EXPECT_THAT(callback.WaitForResult(), IsOk());
3529
3530 ExpectBrokenAlternateProtocolMapping();
3531 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3532
3533 std::string response_data;
3534 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3535 IsError(ERR_QUIC_PROTOCOL_ERROR));
3536}
3537
3538// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3539// connection RTOs, then QUIC will be marked as broken and the request retried
3540// over TCP.
3541TEST_P(QuicNetworkTransactionTest,
3542 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413543 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523544 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233545
3546 // The request will initially go out over QUIC.
3547 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523548 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133549 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233550 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3551
3552 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523553 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3554 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433555 quic_data.AddWrite(SYNCHRONOUS,
3556 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333557 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3558 true, priority, GetRequestHeaders("GET", "https", "/"),
3559 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233560
3561 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523562 quic::QuicStreamOffset settings_offset = header_stream_offset;
3563 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433564 quic_data.AddWrite(SYNCHRONOUS,
3565 client_maker_.MakeInitialSettingsPacketAndSaveData(
3566 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233567 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093568 quic_data.AddWrite(SYNCHRONOUS,
3569 client_maker_.MakeDataPacket(
3570 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3571 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233572 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093573 quic_data.AddWrite(SYNCHRONOUS,
3574 client_maker_.MakeDataPacket(
3575 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3576 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233577 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093578 quic_data.AddWrite(SYNCHRONOUS,
3579 client_maker_.MakeDataPacket(
3580 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3581 false, 0, request_data));
3582 quic_data.AddWrite(SYNCHRONOUS,
3583 client_maker_.MakeDataPacket(
3584 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3585 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233586 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093587 quic_data.AddWrite(SYNCHRONOUS,
3588 client_maker_.MakeDataPacket(
3589 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3590 false, 0, request_data));
3591 quic_data.AddWrite(SYNCHRONOUS,
3592 client_maker_.MakeDataPacket(
3593 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3594 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233595 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093596 quic_data.AddWrite(SYNCHRONOUS,
3597 client_maker_.MakeDataPacket(
3598 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3599 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523600 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093601 SYNCHRONOUS, client_maker_.MakeDataPacket(
3602 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3603 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233604 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523605 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093606 SYNCHRONOUS, client_maker_.MakeDataPacket(
3607 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3608 false, 0, request_data));
3609 quic_data.AddWrite(
3610 SYNCHRONOUS, client_maker_.MakeDataPacket(
3611 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3612 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233613
Zhongyi Shi32f2fd02018-04-16 18:23:433614 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523615 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433616 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233617
3618 quic_data.AddRead(ASYNC, OK);
3619 quic_data.AddSocketDataToFactory(&socket_factory_);
3620
3621 // After that fails, it will be resent via TCP.
3622 MockWrite http_writes[] = {
3623 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3624 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3625 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3626
3627 MockRead http_reads[] = {
3628 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3629 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3630 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013631 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233632 socket_factory_.AddSocketDataProvider(&http_data);
3633 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3634
3635 // In order for a new QUIC session to be established via alternate-protocol
3636 // without racing an HTTP connection, we need the host resolution to happen
3637 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3638 // connection to the the server, in this test we require confirmation
3639 // before encrypting so the HTTP job will still start.
3640 host_resolver_.set_synchronous_mode(true);
3641 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3642 "");
3643 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3644 AddressList address;
3645 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583646 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3647 CompletionOnceCallback(), &request,
3648 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413649 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233650
3651 CreateSession();
3652 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553653 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233654 QuicStreamFactoryPeer::SetAlarmFactory(
3655 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193656 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553657 &clock_));
rch9ecde09b2017-04-08 00:18:233658
Ryan Hamilton9835e662018-08-02 05:36:273659 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233660
3661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3662 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413663 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3665
3666 // Pump the message loop to get the request started.
3667 base::RunLoop().RunUntilIdle();
3668 // Explicitly confirm the handshake.
3669 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523670 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233671
3672 // Run the QUIC session to completion.
3673 quic_task_runner_->RunUntilIdle();
3674 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3675
3676 // Let the transaction proceed which will result in QUIC being marked
3677 // as broken and the request falling back to TCP.
3678 EXPECT_THAT(callback.WaitForResult(), IsOk());
3679
3680 ExpectBrokenAlternateProtocolMapping();
3681 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3682 ASSERT_FALSE(http_data.AllReadDataConsumed());
3683
3684 // Read the response body over TCP.
3685 CheckResponseData(&trans, "hello world");
3686 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3687 ASSERT_TRUE(http_data.AllReadDataConsumed());
3688}
3689
3690// Verify that if a QUIC connection RTOs, while there are no active streams
3691// QUIC will be marked as broken.
3692TEST_P(QuicNetworkTransactionTest,
3693 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413694 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523695 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233696
3697 // The request will initially go out over QUIC.
3698 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523699 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133700 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233701 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3702
3703 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523704 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3705 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433706 quic_data.AddWrite(SYNCHRONOUS,
3707 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333708 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3709 true, priority, GetRequestHeaders("GET", "https", "/"),
3710 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233711
3712 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523713 quic::QuicStreamOffset settings_offset = header_stream_offset;
3714 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433715 quic_data.AddWrite(SYNCHRONOUS,
3716 client_maker_.MakeInitialSettingsPacketAndSaveData(
3717 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233718
Fan Yang32c5a112018-12-10 20:06:333719 quic_data.AddWrite(SYNCHRONOUS,
3720 client_maker_.MakeRstPacket(
3721 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3722 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233723 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093724 quic_data.AddWrite(SYNCHRONOUS,
3725 client_maker_.MakeDataPacket(
3726 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3727 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233728 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093729 quic_data.AddWrite(SYNCHRONOUS,
3730 client_maker_.MakeDataPacket(
3731 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3732 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233733 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333734 quic_data.AddWrite(SYNCHRONOUS,
3735 client_maker_.MakeRstPacket(
3736 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3737 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093738 quic_data.AddWrite(SYNCHRONOUS,
3739 client_maker_.MakeDataPacket(
3740 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3741 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233742 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093743 quic_data.AddWrite(SYNCHRONOUS,
3744 client_maker_.MakeDataPacket(
3745 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3746 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333747 quic_data.AddWrite(SYNCHRONOUS,
3748 client_maker_.MakeRstPacket(
3749 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3750 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233751 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523752 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093753 SYNCHRONOUS, client_maker_.MakeDataPacket(
3754 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3755 false, 0, request_data));
3756 quic_data.AddWrite(
3757 SYNCHRONOUS, client_maker_.MakeDataPacket(
3758 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3759 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233760 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433761 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333762 SYNCHRONOUS, client_maker_.MakeRstPacket(
3763 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3764 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523765 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093766 SYNCHRONOUS, client_maker_.MakeDataPacket(
3767 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3768 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233769 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433770 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523771 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433772 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233773
3774 quic_data.AddRead(ASYNC, OK);
3775 quic_data.AddSocketDataToFactory(&socket_factory_);
3776
3777 // In order for a new QUIC session to be established via alternate-protocol
3778 // without racing an HTTP connection, we need the host resolution to happen
3779 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3780 // connection to the the server, in this test we require confirmation
3781 // before encrypting so the HTTP job will still start.
3782 host_resolver_.set_synchronous_mode(true);
3783 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3784 "");
3785 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3786 AddressList address;
3787 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583788 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3789 CompletionOnceCallback(), &request,
3790 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413791 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233792
3793 CreateSession();
3794 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553795 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233796 QuicStreamFactoryPeer::SetAlarmFactory(
3797 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193798 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553799 &clock_));
rch9ecde09b2017-04-08 00:18:233800
Ryan Hamilton9835e662018-08-02 05:36:273801 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233802
Jeremy Roman0579ed62017-08-29 15:56:193803 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233804 session_.get());
3805 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413806 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233807 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3808
3809 // Pump the message loop to get the request started.
3810 base::RunLoop().RunUntilIdle();
3811 // Explicitly confirm the handshake.
3812 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523813 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233814
3815 // Now cancel the request.
3816 trans.reset();
3817
3818 // Run the QUIC session to completion.
3819 quic_task_runner_->RunUntilIdle();
3820
3821 ExpectBrokenAlternateProtocolMapping();
3822
3823 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3824}
3825
rch2f2991c2017-04-13 19:28:173826// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3827// protocol error occurs after the handshake is confirmed, the request
3828// retried over TCP and the QUIC will be marked as broken.
3829TEST_P(QuicNetworkTransactionTest,
3830 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413831 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173832
3833 // The request will initially go out over QUIC.
3834 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523835 quic::QuicStreamOffset header_stream_offset = 0;
3836 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3837 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433838 quic_data.AddWrite(
3839 SYNCHRONOUS,
3840 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333841 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433842 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523843 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433844 quic_data.AddWrite(SYNCHRONOUS,
3845 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173846 // Peer sending data from an non-existing stream causes this end to raise
3847 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333848 quic_data.AddRead(
3849 ASYNC, ConstructServerRstPacket(
3850 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3851 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173852 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433853 quic_data.AddWrite(SYNCHRONOUS,
3854 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523855 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3856 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173857 quic_data.AddSocketDataToFactory(&socket_factory_);
3858
3859 // After that fails, it will be resent via TCP.
3860 MockWrite http_writes[] = {
3861 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3862 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3863 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3864
3865 MockRead http_reads[] = {
3866 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3867 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3868 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013869 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173870 socket_factory_.AddSocketDataProvider(&http_data);
3871 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3872
3873 // In order for a new QUIC session to be established via alternate-protocol
3874 // without racing an HTTP connection, we need the host resolution to happen
3875 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3876 // connection to the the server, in this test we require confirmation
3877 // before encrypting so the HTTP job will still start.
3878 host_resolver_.set_synchronous_mode(true);
3879 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3880 "");
3881 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3882 AddressList address;
3883 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583884 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3885 CompletionOnceCallback(), &request,
3886 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413887 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173888
3889 CreateSession();
3890
Ryan Hamilton9835e662018-08-02 05:36:273891 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173892
3893 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3894 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413895 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3897
3898 // Pump the message loop to get the request started.
3899 base::RunLoop().RunUntilIdle();
3900 // Explicitly confirm the handshake.
3901 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523902 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173903
3904 // Run the QUIC session to completion.
3905 base::RunLoop().RunUntilIdle();
3906 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3907
3908 ExpectQuicAlternateProtocolMapping();
3909
3910 // Let the transaction proceed which will result in QUIC being marked
3911 // as broken and the request falling back to TCP.
3912 EXPECT_THAT(callback.WaitForResult(), IsOk());
3913
3914 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3915 ASSERT_FALSE(http_data.AllReadDataConsumed());
3916
3917 // Read the response body over TCP.
3918 CheckResponseData(&trans, "hello world");
3919 ExpectBrokenAlternateProtocolMapping();
3920 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3921 ASSERT_TRUE(http_data.AllReadDataConsumed());
3922}
3923
rch30943ee2017-06-12 21:28:443924// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3925// request is reset from, then QUIC will be marked as broken and the request
3926// retried over TCP.
3927TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443928 // The request will initially go out over QUIC.
3929 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523930 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133931 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443932 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3933
3934 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523935 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3936 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433937 quic_data.AddWrite(SYNCHRONOUS,
3938 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333939 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3940 true, priority, GetRequestHeaders("GET", "https", "/"),
3941 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443942
3943 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523944 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3945 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433946 quic_data.AddWrite(SYNCHRONOUS,
3947 client_maker_.MakeInitialSettingsPacketAndSaveData(
3948 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443949
Fan Yang32c5a112018-12-10 20:06:333950 quic_data.AddRead(ASYNC,
3951 ConstructServerRstPacket(
3952 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3953 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443954
3955 quic_data.AddRead(ASYNC, OK);
3956 quic_data.AddSocketDataToFactory(&socket_factory_);
3957
3958 // After that fails, it will be resent via TCP.
3959 MockWrite http_writes[] = {
3960 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3961 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3962 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3963
3964 MockRead http_reads[] = {
3965 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3966 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3967 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013968 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443969 socket_factory_.AddSocketDataProvider(&http_data);
3970 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3971
3972 // In order for a new QUIC session to be established via alternate-protocol
3973 // without racing an HTTP connection, we need the host resolution to happen
3974 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3975 // connection to the the server, in this test we require confirmation
3976 // before encrypting so the HTTP job will still start.
3977 host_resolver_.set_synchronous_mode(true);
3978 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3979 "");
3980 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3981 AddressList address;
3982 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583983 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3984 CompletionOnceCallback(), &request,
3985 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413986 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443987
3988 CreateSession();
3989
Ryan Hamilton9835e662018-08-02 05:36:273990 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443991
3992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3993 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413994 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443995 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3996
3997 // Pump the message loop to get the request started.
3998 base::RunLoop().RunUntilIdle();
3999 // Explicitly confirm the handshake.
4000 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524001 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:444002
4003 // Run the QUIC session to completion.
4004 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4005
4006 ExpectQuicAlternateProtocolMapping();
4007
4008 // Let the transaction proceed which will result in QUIC being marked
4009 // as broken and the request falling back to TCP.
4010 EXPECT_THAT(callback.WaitForResult(), IsOk());
4011
4012 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
4013 ASSERT_FALSE(http_data.AllReadDataConsumed());
4014
4015 // Read the response body over TCP.
4016 CheckResponseData(&trans, "hello world");
4017 ExpectBrokenAlternateProtocolMapping();
4018 ASSERT_TRUE(http_data.AllWriteDataConsumed());
4019 ASSERT_TRUE(http_data.AllReadDataConsumed());
4020}
4021
Ryan Hamilton6c2a2a82017-12-15 02:06:284022// Verify that when an origin has two alt-svc advertisements, one local and one
4023// remote, that when the local is broken the request will go over QUIC via
4024// the remote Alt-Svc.
4025// This is a regression test for crbug/825646.
4026TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
4027 session_params_.quic_allow_remote_alt_svc = true;
4028
4029 GURL origin1 = request_.url; // mail.example.org
4030 GURL origin2("https://www.example.org/");
4031 ASSERT_NE(origin1.host(), origin2.host());
4032
4033 scoped_refptr<X509Certificate> cert(
4034 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244035 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4036 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:284037
4038 ProofVerifyDetailsChromium verify_details;
4039 verify_details.cert_verify_result.verified_cert = cert;
4040 verify_details.cert_verify_result.is_issued_by_known_root = true;
4041 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4042
4043 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524044 quic::QuicStreamOffset request_header_offset(0);
4045 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:284046 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434047 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4048 mock_quic_data.AddWrite(
4049 SYNCHRONOUS,
4050 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334051 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434052 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4053 mock_quic_data.AddRead(
4054 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334055 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434056 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414057 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434058 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334059 ASYNC, ConstructServerDataPacket(
4060 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414061 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434062 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284063 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4064 mock_quic_data.AddRead(ASYNC, 0); // EOF
4065
4066 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4067 MockQuicData mock_quic_data2;
4068 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4069 AddHangingNonAlternateProtocolSocketData();
4070
4071 CreateSession();
4072
4073 // Set up alternative service for |origin1|.
4074 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4075 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4076 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4077 AlternativeServiceInfoVector alternative_services;
4078 alternative_services.push_back(
4079 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4080 local_alternative, expiration,
4081 session_->params().quic_supported_versions));
4082 alternative_services.push_back(
4083 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4084 remote_alternative, expiration,
4085 session_->params().quic_supported_versions));
4086 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4087 alternative_services);
4088
4089 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4090
4091 SendRequestAndExpectQuicResponse("hello!");
4092}
4093
rch30943ee2017-06-12 21:28:444094// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4095// request is reset from, then QUIC will be marked as broken and the request
4096// retried over TCP. Then, subsequent requests will go over a new QUIC
4097// connection instead of going back to the broken QUIC connection.
4098// This is a regression tests for crbug/731303.
4099TEST_P(QuicNetworkTransactionTest,
4100 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344101 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444102
4103 GURL origin1 = request_.url;
4104 GURL origin2("https://www.example.org/");
4105 ASSERT_NE(origin1.host(), origin2.host());
4106
4107 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524108 quic::QuicStreamOffset request_header_offset(0);
4109 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444110
4111 scoped_refptr<X509Certificate> cert(
4112 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244113 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4114 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444115
4116 ProofVerifyDetailsChromium verify_details;
4117 verify_details.cert_verify_result.verified_cert = cert;
4118 verify_details.cert_verify_result.is_issued_by_known_root = true;
4119 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4120
4121 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434122 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444123 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434124 mock_quic_data.AddWrite(
4125 SYNCHRONOUS,
4126 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334127 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434128 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4129 mock_quic_data.AddRead(
4130 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334131 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434132 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414133 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434134 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334135 ASYNC, ConstructServerDataPacket(
4136 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414137 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434138 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444139
4140 // Second request will go over the pooled QUIC connection, but will be
4141 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054142 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174143 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4144 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054145 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174146 QuicTestPacketMaker server_maker2(
4147 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4148 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434149 mock_quic_data.AddWrite(
4150 SYNCHRONOUS,
4151 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334152 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434153 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334154 GetNthClientInitiatedBidirectionalStreamId(0),
4155 &request_header_offset));
4156 mock_quic_data.AddRead(
4157 ASYNC, ConstructServerRstPacket(
4158 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4159 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444160 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4161 mock_quic_data.AddRead(ASYNC, 0); // EOF
4162
4163 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4164
4165 // After that fails, it will be resent via TCP.
4166 MockWrite http_writes[] = {
4167 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4168 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4169 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4170
4171 MockRead http_reads[] = {
4172 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4173 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4174 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014175 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444176 socket_factory_.AddSocketDataProvider(&http_data);
4177 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4178
Ryan Hamilton6c2a2a82017-12-15 02:06:284179 // Then the next request to the second origin will be sent over TCP.
4180 socket_factory_.AddSocketDataProvider(&http_data);
4181 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444182
4183 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564184 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4185 QuicStreamFactoryPeer::SetAlarmFactory(
4186 session_->quic_stream_factory(),
4187 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4188 &clock_));
rch30943ee2017-06-12 21:28:444189
4190 // Set up alternative service for |origin1|.
4191 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244192 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214193 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244194 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444195 supported_versions_);
rch30943ee2017-06-12 21:28:444196
4197 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244198 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214199 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244200 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444201 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344202
rch30943ee2017-06-12 21:28:444203 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524204 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444205 SendRequestAndExpectQuicResponse("hello!");
4206
4207 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524208 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444209 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4210 request_.url = origin2;
4211 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284212 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244213 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284214 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244215 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444216
4217 // The third request should use a new QUIC connection, not the broken
4218 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284219 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444220}
4221
bnc8be55ebb2015-10-30 14:12:074222TEST_P(QuicNetworkTransactionTest,
4223 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4224 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444225 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074226 MockRead http_reads[] = {
4227 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4228 MockRead("hello world"),
4229 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4230 MockRead(ASYNC, OK)};
4231
Ryan Sleevib8d7ea02018-05-07 20:01:014232 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074233 socket_factory_.AddSocketDataProvider(&http_data);
4234 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4235 socket_factory_.AddSocketDataProvider(&http_data);
4236 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4237
rch3f4b8452016-02-23 16:59:324238 CreateSession();
bnc8be55ebb2015-10-30 14:12:074239
4240 SendRequestAndExpectHttpResponse("hello world");
4241 SendRequestAndExpectHttpResponse("hello world");
4242}
4243
Xida Chen9bfe0b62018-04-24 19:52:214244// When multiple alternative services are advertised, HttpStreamFactory should
4245// select the alternative service which uses existing QUIC session if available.
4246// If no existing QUIC session can be used, use the first alternative service
4247// from the list.
zhongyi32569c62016-01-08 02:54:304248TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344249 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524250 MockRead http_reads[] = {
4251 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294252 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524253 MockRead("hello world"),
4254 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4255 MockRead(ASYNC, OK)};
4256
Ryan Sleevib8d7ea02018-05-07 20:01:014257 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524258 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084259 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564260 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524261
Ryan Hamilton8d9ee76e2018-05-29 23:52:524262 quic::QuicStreamOffset request_header_offset = 0;
4263 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304264 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294265 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304266 // alternative service list.
bncc958faa2015-07-31 18:14:524267 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364268 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434269 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4270 mock_quic_data.AddWrite(
4271 SYNCHRONOUS,
4272 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334273 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434274 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304275
4276 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294277 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4278 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434279 mock_quic_data.AddRead(
4280 ASYNC,
4281 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334282 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434283 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414284 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434285 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334286 ASYNC, ConstructServerDataPacket(
4287 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414288 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434289 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304290
4291 // Second QUIC request data.
4292 // Connection pooling, using existing session, no need to include version
4293 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584294 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334295 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4296 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4297 true, GetRequestHeaders("GET", "https", "/"),
4298 GetNthClientInitiatedBidirectionalStreamId(0),
4299 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434300 mock_quic_data.AddRead(
4301 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334302 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434303 GetResponseHeaders("200 OK"), &response_header_offset));
4304 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334305 ASYNC, ConstructServerDataPacket(
4306 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414307 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434308 mock_quic_data.AddWrite(
4309 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524310 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594311 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524312
4313 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4314
rtennetib8e80fb2016-05-16 00:12:094315 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324316 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564317 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4318 QuicStreamFactoryPeer::SetAlarmFactory(
4319 session_->quic_stream_factory(),
4320 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4321 &clock_));
bncc958faa2015-07-31 18:14:524322
4323 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304324
bnc359ed2a2016-04-29 20:43:454325 SendRequestAndExpectQuicResponse("hello!");
4326 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304327}
4328
tbansal6490783c2016-09-20 17:55:274329// Check that an existing QUIC connection to an alternative proxy server is
4330// used.
4331TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4332 base::HistogramTester histogram_tester;
4333
Ryan Hamilton8d9ee76e2018-05-29 23:52:524334 quic::QuicStreamOffset request_header_offset = 0;
4335 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274336 // First QUIC request data.
4337 // Open a session to foo.example.org:443 using the first entry of the
4338 // alternative service list.
4339 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364340 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434341 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4342 mock_quic_data.AddWrite(
4343 SYNCHRONOUS,
4344 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334345 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434346 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274347
4348 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434349 mock_quic_data.AddRead(
4350 ASYNC,
4351 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334352 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434353 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414354 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434355 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334356 ASYNC, ConstructServerDataPacket(
4357 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414358 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434359 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274360
4361 // Second QUIC request data.
4362 // Connection pooling, using existing session, no need to include version
4363 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274364 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334365 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4366 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4367 true, GetRequestHeaders("GET", "http", "/"),
4368 GetNthClientInitiatedBidirectionalStreamId(0),
4369 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434370 mock_quic_data.AddRead(
4371 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334372 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434373 GetResponseHeaders("200 OK"), &response_header_offset));
4374 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334375 ASYNC, ConstructServerDataPacket(
4376 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414377 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434378 mock_quic_data.AddWrite(
4379 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274380 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4381 mock_quic_data.AddRead(ASYNC, 0); // EOF
4382
4383 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4384
4385 AddHangingNonAlternateProtocolSocketData();
4386
4387 TestProxyDelegate test_proxy_delegate;
4388
Lily Houghton8c2f97d2018-01-22 05:06:594389 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494390 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274391
4392 test_proxy_delegate.set_alternative_proxy_server(
4393 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524394 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274395
4396 request_.url = GURL("http://mail.example.org/");
4397
4398 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564399 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4400 QuicStreamFactoryPeer::SetAlarmFactory(
4401 session_->quic_stream_factory(),
4402 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4403 &clock_));
tbansal6490783c2016-09-20 17:55:274404
4405 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4406 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4407 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4408 1);
4409
4410 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4411 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4412 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4413 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4414 1);
4415}
4416
Ryan Hamilton8d9ee76e2018-05-29 23:52:524417// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454418// even if alternative service destination is different.
4419TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344420 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304421 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524422 quic::QuicStreamOffset request_header_offset(0);
4423 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454424
rch5cb522462017-04-25 20:18:364425 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434426 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454427 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434428 mock_quic_data.AddWrite(
4429 SYNCHRONOUS,
4430 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334431 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434432 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4433 mock_quic_data.AddRead(
4434 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334435 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434436 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414437 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434438 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334439 ASYNC, ConstructServerDataPacket(
4440 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414441 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434442 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304443
bnc359ed2a2016-04-29 20:43:454444 // Second request.
alyssar2adf3ac2016-05-03 17:12:584445 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334446 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4447 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4448 true, GetRequestHeaders("GET", "https", "/"),
4449 GetNthClientInitiatedBidirectionalStreamId(0),
4450 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434451 mock_quic_data.AddRead(
4452 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334453 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434454 GetResponseHeaders("200 OK"), &response_header_offset));
4455 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334456 ASYNC, ConstructServerDataPacket(
4457 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414458 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434459 mock_quic_data.AddWrite(
4460 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304461 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4462 mock_quic_data.AddRead(ASYNC, 0); // EOF
4463
4464 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454465
4466 AddHangingNonAlternateProtocolSocketData();
4467 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304468
rch3f4b8452016-02-23 16:59:324469 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564470 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4471 QuicStreamFactoryPeer::SetAlarmFactory(
4472 session_->quic_stream_factory(),
4473 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4474 &clock_));
zhongyi32569c62016-01-08 02:54:304475
bnc359ed2a2016-04-29 20:43:454476 const char destination1[] = "first.example.com";
4477 const char destination2[] = "second.example.com";
4478
4479 // Set up alternative service entry to destination1.
4480 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214481 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454482 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214483 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444484 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454485 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524486 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454487 SendRequestAndExpectQuicResponse("hello!");
4488
4489 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214490 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214491 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444492 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524493 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454494 // even though alternative service destination is different.
4495 SendRequestAndExpectQuicResponse("hello!");
4496}
4497
4498// Pool to existing session with matching destination and matching certificate
4499// even if origin is different, and even if the alternative service with
4500// matching destination is not the first one on the list.
4501TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344502 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454503 GURL origin1 = request_.url;
4504 GURL origin2("https://www.example.org/");
4505 ASSERT_NE(origin1.host(), origin2.host());
4506
4507 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524508 quic::QuicStreamOffset request_header_offset(0);
4509 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454510
rch5cb522462017-04-25 20:18:364511 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434512 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454513 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434514 mock_quic_data.AddWrite(
4515 SYNCHRONOUS,
4516 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334517 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434518 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4519 mock_quic_data.AddRead(
4520 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334521 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434522 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414523 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434524 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334525 ASYNC, ConstructServerDataPacket(
4526 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414527 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434528 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454529
4530 // Second request.
Yixin Wang079ad542018-01-11 04:06:054531 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174532 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4533 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054534 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174535 QuicTestPacketMaker server_maker2(
4536 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4537 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584538 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434539 SYNCHRONOUS,
4540 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334541 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434542 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334543 GetNthClientInitiatedBidirectionalStreamId(0),
4544 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434545 mock_quic_data.AddRead(
4546 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334547 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434548 GetResponseHeaders("200 OK"), &response_header_offset));
4549 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334550 ASYNC, ConstructServerDataPacket(
4551 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414552 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434553 mock_quic_data.AddWrite(
4554 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454555 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4556 mock_quic_data.AddRead(ASYNC, 0); // EOF
4557
4558 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4559
4560 AddHangingNonAlternateProtocolSocketData();
4561 AddHangingNonAlternateProtocolSocketData();
4562
4563 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564564 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4565 QuicStreamFactoryPeer::SetAlarmFactory(
4566 session_->quic_stream_factory(),
4567 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4568 &clock_));
bnc359ed2a2016-04-29 20:43:454569
4570 const char destination1[] = "first.example.com";
4571 const char destination2[] = "second.example.com";
4572
4573 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214574 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454575 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214576 http_server_properties_.SetQuicAlternativeService(
4577 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444578 supported_versions_);
bnc359ed2a2016-04-29 20:43:454579
4580 // Set up multiple alternative service entries for |origin2|,
4581 // the first one with a different destination as for |origin1|,
4582 // the second one with the same. The second one should be used,
4583 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214584 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454585 AlternativeServiceInfoVector alternative_services;
4586 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214587 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4588 alternative_service2, expiration,
4589 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454590 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214591 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4592 alternative_service1, expiration,
4593 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454594 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4595 alternative_services);
bnc359ed2a2016-04-29 20:43:454596 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524597 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454598 SendRequestAndExpectQuicResponse("hello!");
4599
4600 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524601 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454602 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584603
bnc359ed2a2016-04-29 20:43:454604 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304605}
4606
4607// Multiple origins have listed the same alternative services. When there's a
4608// existing QUIC session opened by a request to other origin,
4609// if the cert is valid, should select this QUIC session to make the request
4610// if this is also the first existing QUIC session.
4611TEST_P(QuicNetworkTransactionTest,
4612 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344613 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294614 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304615
rch9ae5b3b2016-02-11 00:36:294616 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304617 MockRead http_reads[] = {
4618 MockRead("HTTP/1.1 200 OK\r\n"),
4619 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294620 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304621 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4622 MockRead(ASYNC, OK)};
4623
Ryan Sleevib8d7ea02018-05-07 20:01:014624 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304625 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084626 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304627 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4628
4629 // HTTP data for request to mail.example.org.
4630 MockRead http_reads2[] = {
4631 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294632 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304633 MockRead("hello world from mail.example.org"),
4634 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4635 MockRead(ASYNC, OK)};
4636
Ryan Sleevib8d7ea02018-05-07 20:01:014637 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304638 socket_factory_.AddSocketDataProvider(&http_data2);
4639 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4640
Ryan Hamilton8d9ee76e2018-05-29 23:52:524641 quic::QuicStreamOffset request_header_offset = 0;
4642 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304643
Yixin Wang079ad542018-01-11 04:06:054644 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174645 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4646 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054647 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584648 server_maker_.set_hostname("www.example.org");
4649 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304650 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364651 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434652 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304653 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584654 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434655 SYNCHRONOUS,
4656 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334657 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434658 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4659
4660 mock_quic_data.AddRead(
4661 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334662 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434663 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414664 quic::QuicString header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334665 mock_quic_data.AddRead(
4666 ASYNC, ConstructServerDataPacket(
4667 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414668 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434669 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4670 // Second QUIC request data.
4671 mock_quic_data.AddWrite(
4672 SYNCHRONOUS,
4673 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334674 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434675 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334676 GetNthClientInitiatedBidirectionalStreamId(0),
4677 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434678 mock_quic_data.AddRead(
4679 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334680 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434681 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334682 mock_quic_data.AddRead(
4683 ASYNC, ConstructServerDataPacket(
4684 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414685 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434686 mock_quic_data.AddWrite(
4687 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304688 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4689 mock_quic_data.AddRead(ASYNC, 0); // EOF
4690
4691 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304692
rtennetib8e80fb2016-05-16 00:12:094693 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324694 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564695 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4696 QuicStreamFactoryPeer::SetAlarmFactory(
4697 session_->quic_stream_factory(),
4698 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4699 &clock_));
zhongyi32569c62016-01-08 02:54:304700
4701 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294702 request_.url = GURL("https://www.example.org/");
4703 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304704 request_.url = GURL("https://mail.example.org/");
4705 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4706
rch9ae5b3b2016-02-11 00:36:294707 // Open a QUIC session to mail.example.org:443 when making request
4708 // to mail.example.org.
4709 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454710 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304711
rch9ae5b3b2016-02-11 00:36:294712 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304713 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454714 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524715}
4716
4717TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524718 MockRead http_reads[] = {
4719 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564720 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524721 MockRead("hello world"),
4722 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4723 MockRead(ASYNC, OK)};
4724
Ryan Sleevib8d7ea02018-05-07 20:01:014725 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524726 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084727 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564728 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524729
rtennetib8e80fb2016-05-16 00:12:094730 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324731 CreateSession();
bncc958faa2015-07-31 18:14:524732
4733 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454734
4735 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344736 AlternativeServiceInfoVector alternative_service_info_vector =
4737 http_server_properties_.GetAlternativeServiceInfos(http_server);
4738 ASSERT_EQ(1u, alternative_service_info_vector.size());
4739 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544740 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344741 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4742 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4743 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524744}
4745
4746TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524747 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564748 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4749 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524750 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4751 MockRead(ASYNC, OK)};
4752
Ryan Sleevib8d7ea02018-05-07 20:01:014753 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524754 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084755 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564756 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524757
4758 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524759 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364760 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434761 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4762 mock_quic_data.AddWrite(
4763 SYNCHRONOUS,
4764 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334765 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434766 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434767 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334768 ASYNC, ConstructServerResponseHeadersPacket(
4769 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4770 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414771 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334772 mock_quic_data.AddRead(
4773 ASYNC, ConstructServerDataPacket(
4774 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414775 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434776 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524777 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4778 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524779
4780 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4781
rtennetib8e80fb2016-05-16 00:12:094782 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324783 CreateSession();
bncc958faa2015-07-31 18:14:524784
bnc3472afd2016-11-17 15:27:214785 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524786 HostPortPair::FromURL(request_.url));
4787 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4788 alternative_service);
4789 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4790 alternative_service));
4791
4792 SendRequestAndExpectHttpResponse("hello world");
4793 SendRequestAndExpectQuicResponse("hello!");
4794
mmenkee24011922015-12-17 22:12:594795 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524796
4797 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4798 alternative_service));
rchac7f35e2017-03-15 20:42:304799 EXPECT_NE(nullptr,
4800 http_server_properties_.GetServerNetworkStats(
4801 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524802}
4803
bncc958faa2015-07-31 18:14:524804TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524805 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564806 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4807 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524808 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4809 MockRead(ASYNC, OK)};
4810
Ryan Sleevib8d7ea02018-05-07 20:01:014811 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524812 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564813 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524814
4815 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524816 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364817 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434818 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4819 mock_quic_data.AddWrite(
4820 SYNCHRONOUS,
4821 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334822 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434823 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434824 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334825 ASYNC, ConstructServerResponseHeadersPacket(
4826 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4827 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414828 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334829 mock_quic_data.AddRead(
4830 ASYNC, ConstructServerDataPacket(
4831 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414832 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434833 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524834 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4835
4836 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4837
4838 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324839 CreateSession();
bncc958faa2015-07-31 18:14:524840
4841 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4842 SendRequestAndExpectHttpResponse("hello world");
4843}
4844
tbansalc3308d72016-08-27 10:25:044845// Tests that the connection to an HTTPS proxy is raced with an available
4846// alternative proxy server.
4847TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274848 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594849 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494850 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044851
4852 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524853 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364854 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434855 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4856 mock_quic_data.AddWrite(
4857 SYNCHRONOUS,
4858 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334859 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434860 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434861 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334862 ASYNC, ConstructServerResponseHeadersPacket(
4863 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4864 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414865 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334866 mock_quic_data.AddRead(
4867 ASYNC, ConstructServerDataPacket(
4868 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414869 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434870 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044871 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4872 mock_quic_data.AddRead(ASYNC, 0); // EOF
4873
4874 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4875
4876 // There is no need to set up main job, because no attempt will be made to
4877 // speak to the proxy over TCP.
4878 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044879 TestProxyDelegate test_proxy_delegate;
4880 const HostPortPair host_port_pair("mail.example.org", 443);
4881
4882 test_proxy_delegate.set_alternative_proxy_server(
4883 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524884 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044885 CreateSession();
4886 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4887
4888 // The main job needs to hang in order to guarantee that the alternative
4889 // proxy server job will "win".
4890 AddHangingNonAlternateProtocolSocketData();
4891
4892 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4893
4894 // Verify that the alternative proxy server is not marked as broken.
4895 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4896
4897 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594898 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274899
4900 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4901 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4902 1);
tbansalc3308d72016-08-27 10:25:044903}
4904
bnc1c196c6e2016-05-28 13:51:484905TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304906 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274907 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304908
4909 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564910 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294911 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564912 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304913
4914 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564915 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484916 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564917 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304918
Ryan Sleevib8d7ea02018-05-07 20:01:014919 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504920 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084921 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504922 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304923
4924 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454925 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304926 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454927 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304928 };
Ryan Sleevib8d7ea02018-05-07 20:01:014929 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504930 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304931
4932 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014933 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504934 socket_factory_.AddSocketDataProvider(&http_data2);
4935 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304936
bnc912a04b2016-04-20 14:19:504937 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304938
4939 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304940 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174941 ASSERT_TRUE(http_data.AllReadDataConsumed());
4942 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304943
4944 // Now run the second request in which the QUIC socket hangs,
4945 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304946 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454947 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304948
rch37de576c2015-05-17 20:28:174949 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4950 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454951 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304952}
4953
[email protected]1e960032013-12-20 19:00:204954TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204955 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524956 quic::QuicStreamOffset header_stream_offset = 0;
4957 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4958 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434959 mock_quic_data.AddWrite(
4960 SYNCHRONOUS,
4961 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334962 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434963 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434964 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334965 ASYNC, ConstructServerResponseHeadersPacket(
4966 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4967 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414968 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334969 mock_quic_data.AddRead(
4970 ASYNC, ConstructServerDataPacket(
4971 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414972 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434973 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504974 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594975 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484976
rcha5399e02015-04-21 19:32:044977 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484978
rtennetib8e80fb2016-05-16 00:12:094979 // The non-alternate protocol job needs to hang in order to guarantee that
4980 // the alternate-protocol job will "win".
4981 AddHangingNonAlternateProtocolSocketData();
4982
rch3f4b8452016-02-23 16:59:324983 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274984 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194985 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304986
4987 EXPECT_EQ(nullptr,
4988 http_server_properties_.GetServerNetworkStats(
4989 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484990}
4991
[email protected]1e960032013-12-20 19:00:204992TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204993 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524994 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4995 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334996 mock_quic_data.AddWrite(
4997 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4998 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4999 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435000 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335001 ASYNC, ConstructServerResponseHeadersPacket(
5002 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5003 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415004 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335005 mock_quic_data.AddRead(
5006 ASYNC, ConstructServerDataPacket(
5007 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415008 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435009 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:505010 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:595011 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:045012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:275013
5014 // In order for a new QUIC session to be established via alternate-protocol
5015 // without racing an HTTP connection, we need the host resolution to happen
5016 // synchronously.
5017 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295018 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565019 "");
rch9ae5b3b2016-02-11 00:36:295020 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:275021 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105022 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585023 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5024 CompletionOnceCallback(), &request,
5025 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415026 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:275027
rtennetib8e80fb2016-05-16 00:12:095028 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325029 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275030 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:275031 SendRequestAndExpectQuicResponse("hello!");
5032}
5033
[email protected]0fc924b2014-03-31 04:34:155034TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:495035 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5036 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:155037
5038 // Since we are using a proxy, the QUIC job will not succeed.
5039 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:295040 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
5041 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:565042 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:155043
5044 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:565045 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:485046 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565047 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:155048
Ryan Sleevib8d7ea02018-05-07 20:01:015049 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:155050 socket_factory_.AddSocketDataProvider(&http_data);
5051
5052 // In order for a new QUIC session to be established via alternate-protocol
5053 // without racing an HTTP connection, we need the host resolution to happen
5054 // synchronously.
5055 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295056 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565057 "");
rch9ae5b3b2016-02-11 00:36:295058 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:155059 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105060 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585061 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5062 CompletionOnceCallback(), &request,
5063 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415064 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:155065
rch9ae5b3b2016-02-11 00:36:295066 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:325067 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275068 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:155069 SendRequestAndExpectHttpResponse("hello world");
5070}
5071
[email protected]1e960032013-12-20 19:00:205072TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:205073 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525074 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365075 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435076 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5077 mock_quic_data.AddWrite(
5078 SYNCHRONOUS,
5079 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335080 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435081 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435082 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335083 ASYNC, ConstructServerResponseHeadersPacket(
5084 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5085 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415086 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335087 mock_quic_data.AddRead(
5088 ASYNC, ConstructServerDataPacket(
5089 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415090 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435091 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595092 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045093 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125094
rtennetib8e80fb2016-05-16 00:12:095095 // The non-alternate protocol job needs to hang in order to guarantee that
5096 // the alternate-protocol job will "win".
5097 AddHangingNonAlternateProtocolSocketData();
5098
[email protected]11c05872013-08-20 02:04:125099 // In order for a new QUIC session to be established via alternate-protocol
5100 // without racing an HTTP connection, we need the host resolution to happen
5101 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5102 // connection to the the server, in this test we require confirmation
5103 // before encrypting so the HTTP job will still start.
5104 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295105 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565106 "");
rch9ae5b3b2016-02-11 00:36:295107 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:125108 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105109 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585110 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5111 CompletionOnceCallback(), &request,
5112 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415113 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:125114
rch3f4b8452016-02-23 16:59:325115 CreateSession();
[email protected]11c05872013-08-20 02:04:125116 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275117 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125118
bnc691fda62016-08-12 00:43:165119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125120 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415121 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125123
5124 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525125 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015126 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505127
bnc691fda62016-08-12 00:43:165128 CheckWasQuicResponse(&trans);
5129 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125130}
5131
Steven Valdez58097ec32018-07-16 18:29:045132TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5133 MockQuicData mock_quic_data;
5134 quic::QuicStreamOffset client_header_stream_offset = 0;
5135 quic::QuicStreamOffset server_header_stream_offset = 0;
5136 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5137 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045138 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335139 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5140 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5141 true, GetRequestHeaders("GET", "https", "/"),
5142 &client_header_stream_offset));
5143 mock_quic_data.AddRead(
5144 ASYNC,
5145 ConstructServerResponseHeadersPacket(
5146 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5147 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5148 mock_quic_data.AddWrite(SYNCHRONOUS,
5149 ConstructClientAckAndRstPacket(
5150 2, GetNthClientInitiatedBidirectionalStreamId(0),
5151 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045152
5153 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5154
5155 spdy::SpdySettingsIR settings_frame;
5156 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5157 quic::kDefaultMaxUncompressedHeaderSize);
5158 spdy::SpdySerializedFrame spdy_frame(
5159 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5160 mock_quic_data.AddWrite(
5161 SYNCHRONOUS,
5162 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385163 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5164 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045165 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5166 client_header_stream_offset += spdy_frame.size();
5167
5168 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335169 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5170 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5171 true, GetRequestHeaders("GET", "https", "/"),
5172 GetNthClientInitiatedBidirectionalStreamId(0),
5173 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045174 mock_quic_data.AddRead(
5175 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335176 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045177 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:415178 quic::QuicString header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045179 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335180 ASYNC, ConstructServerDataPacket(
5181 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415182 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045183 mock_quic_data.AddWrite(
5184 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5185 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5186 mock_quic_data.AddRead(ASYNC, 0); // EOF
5187
5188 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5189
5190 // In order for a new QUIC session to be established via alternate-protocol
5191 // without racing an HTTP connection, we need the host resolution to happen
5192 // synchronously.
5193 host_resolver_.set_synchronous_mode(true);
5194 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5195 "");
5196 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5197 AddressList address;
5198 std::unique_ptr<HostResolver::Request> request;
5199 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5200 CompletionOnceCallback(), &request, net_log_.bound());
5201
5202 AddHangingNonAlternateProtocolSocketData();
5203 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275204 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565205 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5206 QuicStreamFactoryPeer::SetAlarmFactory(
5207 session_->quic_stream_factory(),
5208 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5209 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045210
5211 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5212 TestCompletionCallback callback;
5213 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5214 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5215
5216 // Confirm the handshake after the 425 Too Early.
5217 base::RunLoop().RunUntilIdle();
5218
5219 // The handshake hasn't been confirmed yet, so the retry should not have
5220 // succeeded.
5221 EXPECT_FALSE(callback.have_result());
5222
5223 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5224 quic::QuicSession::HANDSHAKE_CONFIRMED);
5225
5226 EXPECT_THAT(callback.WaitForResult(), IsOk());
5227 CheckWasQuicResponse(&trans);
5228 CheckResponseData(&trans, "hello!");
5229}
5230
5231TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5232 MockQuicData mock_quic_data;
5233 quic::QuicStreamOffset client_header_stream_offset = 0;
5234 quic::QuicStreamOffset server_header_stream_offset = 0;
5235 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5236 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045237 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335238 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5239 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5240 true, GetRequestHeaders("GET", "https", "/"),
5241 &client_header_stream_offset));
5242 mock_quic_data.AddRead(
5243 ASYNC,
5244 ConstructServerResponseHeadersPacket(
5245 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5246 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5247 mock_quic_data.AddWrite(SYNCHRONOUS,
5248 ConstructClientAckAndRstPacket(
5249 2, GetNthClientInitiatedBidirectionalStreamId(0),
5250 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045251
5252 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5253
5254 spdy::SpdySettingsIR settings_frame;
5255 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5256 quic::kDefaultMaxUncompressedHeaderSize);
5257 spdy::SpdySerializedFrame spdy_frame(
5258 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5259 mock_quic_data.AddWrite(
5260 SYNCHRONOUS,
5261 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385262 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5263 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045264 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5265 client_header_stream_offset += spdy_frame.size();
5266
5267 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335268 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5269 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5270 true, GetRequestHeaders("GET", "https", "/"),
5271 GetNthClientInitiatedBidirectionalStreamId(0),
5272 &client_header_stream_offset));
5273 mock_quic_data.AddRead(
5274 ASYNC,
5275 ConstructServerResponseHeadersPacket(
5276 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5277 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5278 mock_quic_data.AddWrite(SYNCHRONOUS,
5279 ConstructClientAckAndRstPacket(
5280 5, GetNthClientInitiatedBidirectionalStreamId(1),
5281 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045282 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5283 mock_quic_data.AddRead(ASYNC, 0); // EOF
5284
5285 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5286
5287 // In order for a new QUIC session to be established via alternate-protocol
5288 // without racing an HTTP connection, we need the host resolution to happen
5289 // synchronously.
5290 host_resolver_.set_synchronous_mode(true);
5291 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5292 "");
5293 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5294 AddressList address;
5295 std::unique_ptr<HostResolver::Request> request;
5296 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5297 CompletionOnceCallback(), &request, net_log_.bound());
5298
5299 AddHangingNonAlternateProtocolSocketData();
5300 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275301 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565302 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5303 QuicStreamFactoryPeer::SetAlarmFactory(
5304 session_->quic_stream_factory(),
5305 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5306 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045307
5308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5309 TestCompletionCallback callback;
5310 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5311 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5312
5313 // Confirm the handshake after the 425 Too Early.
5314 base::RunLoop().RunUntilIdle();
5315
5316 // The handshake hasn't been confirmed yet, so the retry should not have
5317 // succeeded.
5318 EXPECT_FALSE(callback.have_result());
5319
5320 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5321 quic::QuicSession::HANDSHAKE_CONFIRMED);
5322
5323 EXPECT_THAT(callback.WaitForResult(), IsOk());
5324 const HttpResponseInfo* response = trans.GetResponseInfo();
5325 ASSERT_TRUE(response != nullptr);
5326 ASSERT_TRUE(response->headers.get() != nullptr);
5327 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5328 EXPECT_TRUE(response->was_fetched_via_spdy);
5329 EXPECT_TRUE(response->was_alpn_negotiated);
5330 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5331 response->connection_info);
5332}
5333
zhongyica364fbb2015-12-12 03:39:125334TEST_P(QuicNetworkTransactionTest,
5335 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485336 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125337 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525338 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365339 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435340 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5341 mock_quic_data.AddWrite(
5342 SYNCHRONOUS,
5343 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335344 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435345 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125346 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525347 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435348 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125349 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5350
5351 // The non-alternate protocol job needs to hang in order to guarantee that
5352 // the alternate-protocol job will "win".
5353 AddHangingNonAlternateProtocolSocketData();
5354
5355 // In order for a new QUIC session to be established via alternate-protocol
5356 // without racing an HTTP connection, we need the host resolution to happen
5357 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5358 // connection to the the server, in this test we require confirmation
5359 // before encrypting so the HTTP job will still start.
5360 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295361 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125362 "");
rch9ae5b3b2016-02-11 00:36:295363 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125364 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105365 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585366 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5367 CompletionOnceCallback(), &request,
5368 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415369 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125370
rch3f4b8452016-02-23 16:59:325371 CreateSession();
zhongyica364fbb2015-12-12 03:39:125372 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275373 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125374
bnc691fda62016-08-12 00:43:165375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125376 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415377 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015378 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125379
5380 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525381 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015382 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125383
5384 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525385 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125386
bnc691fda62016-08-12 00:43:165387 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125388 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525389 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5390 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125391}
5392
5393TEST_P(QuicNetworkTransactionTest,
5394 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485395 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125396 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525397 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365398 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435399 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5400 mock_quic_data.AddWrite(
5401 SYNCHRONOUS,
5402 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335403 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435404 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215405 // Peer sending data from an non-existing stream causes this end to raise
5406 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335407 mock_quic_data.AddRead(
5408 ASYNC, ConstructServerRstPacket(
5409 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5410 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215411 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525412 mock_quic_data.AddWrite(
5413 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5414 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5415 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125416 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5417
5418 // The non-alternate protocol job needs to hang in order to guarantee that
5419 // the alternate-protocol job will "win".
5420 AddHangingNonAlternateProtocolSocketData();
5421
5422 // In order for a new QUIC session to be established via alternate-protocol
5423 // without racing an HTTP connection, we need the host resolution to happen
5424 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5425 // connection to the the server, in this test we require confirmation
5426 // before encrypting so the HTTP job will still start.
5427 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295428 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125429 "");
rch9ae5b3b2016-02-11 00:36:295430 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125431 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105432 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585433 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5434 CompletionOnceCallback(), &request,
5435 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415436 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125437
rch3f4b8452016-02-23 16:59:325438 CreateSession();
zhongyica364fbb2015-12-12 03:39:125439 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275440 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125441
bnc691fda62016-08-12 00:43:165442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125443 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415444 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125446
5447 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525448 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015449 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125450 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525451 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125452
bnc691fda62016-08-12 00:43:165453 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525454 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125455}
5456
rchcd5f1c62016-06-23 02:43:485457TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5458 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525459 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365460 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435461 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5462 mock_quic_data.AddWrite(
5463 SYNCHRONOUS,
5464 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335465 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435466 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485467 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335468 mock_quic_data.AddRead(
5469 ASYNC, ConstructServerResponseHeadersPacket(
5470 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5471 GetResponseHeaders("200 OK")));
5472 mock_quic_data.AddRead(
5473 ASYNC, ConstructServerRstPacket(
5474 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5475 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435476 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485477 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5478 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5479
5480 // The non-alternate protocol job needs to hang in order to guarantee that
5481 // the alternate-protocol job will "win".
5482 AddHangingNonAlternateProtocolSocketData();
5483
5484 // In order for a new QUIC session to be established via alternate-protocol
5485 // without racing an HTTP connection, we need the host resolution to happen
5486 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5487 // connection to the the server, in this test we require confirmation
5488 // before encrypting so the HTTP job will still start.
5489 host_resolver_.set_synchronous_mode(true);
5490 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5491 "");
5492 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5493 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105494 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585495 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5496 CompletionOnceCallback(), &request,
5497 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415498 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485499
5500 CreateSession();
5501 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275502 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485503
bnc691fda62016-08-12 00:43:165504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485505 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415506 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485508
5509 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525510 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485511 // Read the headers.
robpercival214763f2016-07-01 23:27:015512 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485513
bnc691fda62016-08-12 00:43:165514 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485515 ASSERT_TRUE(response != nullptr);
5516 ASSERT_TRUE(response->headers.get() != nullptr);
5517 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5518 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525519 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445520 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5521 response->connection_info);
rchcd5f1c62016-06-23 02:43:485522
5523 std::string response_data;
bnc691fda62016-08-12 00:43:165524 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485525}
5526
5527TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485528 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485529 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525530 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365531 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435532 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5533 mock_quic_data.AddWrite(
5534 SYNCHRONOUS,
5535 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335536 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435537 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335538 mock_quic_data.AddRead(
5539 ASYNC, ConstructServerRstPacket(
5540 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5541 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485542 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5543 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5544
5545 // The non-alternate protocol job needs to hang in order to guarantee that
5546 // the alternate-protocol job will "win".
5547 AddHangingNonAlternateProtocolSocketData();
5548
5549 // In order for a new QUIC session to be established via alternate-protocol
5550 // without racing an HTTP connection, we need the host resolution to happen
5551 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5552 // connection to the the server, in this test we require confirmation
5553 // before encrypting so the HTTP job will still start.
5554 host_resolver_.set_synchronous_mode(true);
5555 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5556 "");
5557 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5558 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105559 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585560 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5561 CompletionOnceCallback(), &request,
5562 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415563 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485564
5565 CreateSession();
5566 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275567 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485568
bnc691fda62016-08-12 00:43:165569 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485570 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415571 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015572 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485573
5574 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525575 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485576 // Read the headers.
robpercival214763f2016-07-01 23:27:015577 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485578}
5579
[email protected]1e960032013-12-20 19:00:205580TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305581 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525582 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585583 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305584 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505585 MockRead(ASYNC, close->data(), close->length()),
5586 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5587 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305588 };
Ryan Sleevib8d7ea02018-05-07 20:01:015589 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305590 socket_factory_.AddSocketDataProvider(&quic_data);
5591
5592 // Main job which will succeed even though the alternate job fails.
5593 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025594 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5595 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5596 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305597
Ryan Sleevib8d7ea02018-05-07 20:01:015598 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305599 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565600 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305601
rch3f4b8452016-02-23 16:59:325602 CreateSession();
David Schinazic8281052019-01-24 06:14:175603 AddQuicAlternateProtocolMapping(
5604 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195605 SendRequestAndExpectHttpResponse("hello from http");
5606 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305607}
5608
[email protected]1e960032013-12-20 19:00:205609TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595610 // Alternate-protocol job
5611 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025612 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595613 };
Ryan Sleevib8d7ea02018-05-07 20:01:015614 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595615 socket_factory_.AddSocketDataProvider(&quic_data);
5616
5617 // Main job which will succeed even though the alternate job fails.
5618 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025619 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5620 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5621 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595622
Ryan Sleevib8d7ea02018-05-07 20:01:015623 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595624 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565625 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595626
rch3f4b8452016-02-23 16:59:325627 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595628
Ryan Hamilton9835e662018-08-02 05:36:275629 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195630 SendRequestAndExpectHttpResponse("hello from http");
5631 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595632}
5633
[email protected]00c159f2014-05-21 22:38:165634TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535635 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165636 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025637 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165638 };
Ryan Sleevib8d7ea02018-05-07 20:01:015639 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165640 socket_factory_.AddSocketDataProvider(&quic_data);
5641
[email protected]eb71ab62014-05-23 07:57:535642 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165643 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025644 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165645 };
5646
Ryan Sleevib8d7ea02018-05-07 20:01:015647 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165648 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5649 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565650 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165651
rtennetib8e80fb2016-05-16 00:12:095652 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325653 CreateSession();
[email protected]00c159f2014-05-21 22:38:165654
Ryan Hamilton9835e662018-08-02 05:36:275655 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165657 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165658 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5660 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165661 ExpectQuicAlternateProtocolMapping();
5662}
5663
Zhongyi Shia0cef1082017-08-25 01:49:505664TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5665 // Tests that TCP job is delayed and QUIC job does not require confirmation
5666 // if QUIC was recently supported on the same IP on start.
5667
5668 // Set QUIC support on the last IP address, which is same with the local IP
5669 // address. Require confirmation mode will be turned off immediately when
5670 // local IP address is sorted out after we configure the UDP socket.
5671 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5672
5673 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525674 quic::QuicStreamOffset header_stream_offset = 0;
5675 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5676 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435677 mock_quic_data.AddWrite(
5678 SYNCHRONOUS,
5679 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335680 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435681 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435682 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335683 ASYNC, ConstructServerResponseHeadersPacket(
5684 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5685 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415686 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335687 mock_quic_data.AddRead(
5688 ASYNC, ConstructServerDataPacket(
5689 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415690 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435691 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505692 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5693 mock_quic_data.AddRead(ASYNC, 0); // EOF
5694
5695 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5696 // No HTTP data is mocked as TCP job never starts in this case.
5697
5698 CreateSession();
5699 // QuicStreamFactory by default requires confirmation on construction.
5700 session_->quic_stream_factory()->set_require_confirmation(true);
5701
Ryan Hamilton9835e662018-08-02 05:36:275702 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505703
5704 // Stall host resolution so that QUIC job will not succeed synchronously.
5705 // Socket will not be configured immediately and QUIC support is not sorted
5706 // out, TCP job will still be delayed as server properties indicates QUIC
5707 // support on last IP address.
5708 host_resolver_.set_synchronous_mode(false);
5709
5710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5711 TestCompletionCallback callback;
5712 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5713 IsError(ERR_IO_PENDING));
5714 // Complete host resolution in next message loop so that QUIC job could
5715 // proceed.
5716 base::RunLoop().RunUntilIdle();
5717 EXPECT_THAT(callback.WaitForResult(), IsOk());
5718
5719 CheckWasQuicResponse(&trans);
5720 CheckResponseData(&trans, "hello!");
5721}
5722
5723TEST_P(QuicNetworkTransactionTest,
5724 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5725 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5726 // was recently supported on a different IP address on start.
5727
5728 // Set QUIC support on the last IP address, which is different with the local
5729 // IP address. Require confirmation mode will remain when local IP address is
5730 // sorted out after we configure the UDP socket.
5731 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5732
5733 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525734 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505735 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435736 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5737 mock_quic_data.AddWrite(
5738 SYNCHRONOUS,
5739 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335740 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435741 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435742 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335743 ASYNC, ConstructServerResponseHeadersPacket(
5744 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5745 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415746 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335747 mock_quic_data.AddRead(
5748 ASYNC, ConstructServerDataPacket(
5749 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415750 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435751 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505752 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5753 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5754 // No HTTP data is mocked as TCP job will be delayed and never starts.
5755
5756 CreateSession();
5757 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275758 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505759
5760 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5761 // Socket will not be configured immediately and QUIC support is not sorted
5762 // out, TCP job will still be delayed as server properties indicates QUIC
5763 // support on last IP address.
5764 host_resolver_.set_synchronous_mode(false);
5765
5766 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5767 TestCompletionCallback callback;
5768 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5769 IsError(ERR_IO_PENDING));
5770
5771 // Complete host resolution in next message loop so that QUIC job could
5772 // proceed.
5773 base::RunLoop().RunUntilIdle();
5774 // Explicitly confirm the handshake so that QUIC job could succeed.
5775 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525776 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505777 EXPECT_THAT(callback.WaitForResult(), IsOk());
5778
5779 CheckWasQuicResponse(&trans);
5780 CheckResponseData(&trans, "hello!");
5781}
5782
Ryan Hamilton75f197262017-08-17 14:00:075783TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5784 // Test that NetErrorDetails is correctly populated, even if the
5785 // handshake has not yet been confirmed and no stream has been created.
5786
5787 // QUIC job will pause. When resumed, it will fail.
5788 MockQuicData mock_quic_data;
5789 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5790 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5791 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5792
5793 // Main job will also fail.
5794 MockRead http_reads[] = {
5795 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5796 };
5797
Ryan Sleevib8d7ea02018-05-07 20:01:015798 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075799 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5800 socket_factory_.AddSocketDataProvider(&http_data);
5801 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5802
5803 AddHangingNonAlternateProtocolSocketData();
5804 CreateSession();
5805 // Require handshake confirmation to ensure that no QUIC streams are
5806 // created, and to ensure that the TCP job does not wait for the QUIC
5807 // job to fail before it starts.
5808 session_->quic_stream_factory()->set_require_confirmation(true);
5809
Ryan Hamilton9835e662018-08-02 05:36:275810 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075811 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5812 TestCompletionCallback callback;
5813 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5814 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5815 // Allow the TCP job to fail.
5816 base::RunLoop().RunUntilIdle();
5817 // Now let the QUIC job fail.
5818 mock_quic_data.Resume();
5819 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5820 ExpectQuicAlternateProtocolMapping();
5821 NetErrorDetails details;
5822 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525823 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075824}
5825
[email protected]1e960032013-12-20 19:00:205826TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455827 // Alternate-protocol job
5828 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025829 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455830 };
Ryan Sleevib8d7ea02018-05-07 20:01:015831 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455832 socket_factory_.AddSocketDataProvider(&quic_data);
5833
[email protected]c92c1b52014-05-31 04:16:065834 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015835 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065836 socket_factory_.AddSocketDataProvider(&quic_data2);
5837
[email protected]4d283b32013-10-17 12:57:275838 // Final job that will proceed when the QUIC job fails.
5839 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025840 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5841 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5842 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275843
Ryan Sleevib8d7ea02018-05-07 20:01:015844 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275845 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565846 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275847
rtennetiafccbc062016-05-16 18:21:145848 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325849 CreateSession();
[email protected]77c6c162013-08-17 02:57:455850
Ryan Hamilton9835e662018-08-02 05:36:275851 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455852
[email protected]4d283b32013-10-17 12:57:275853 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455854
5855 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275856
rch37de576c2015-05-17 20:28:175857 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5858 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455859}
5860
[email protected]93b31772014-06-19 08:03:355861TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035862 // Alternate-protocol job
5863 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595864 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035865 };
Ryan Sleevib8d7ea02018-05-07 20:01:015866 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035867 socket_factory_.AddSocketDataProvider(&quic_data);
5868
5869 // Main job that will proceed when the QUIC job fails.
5870 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025871 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5872 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5873 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035874
Ryan Sleevib8d7ea02018-05-07 20:01:015875 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035876 socket_factory_.AddSocketDataProvider(&http_data);
5877
rtennetib8e80fb2016-05-16 00:12:095878 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325879 CreateSession();
[email protected]65768442014-06-06 23:37:035880
Ryan Hamilton9835e662018-08-02 05:36:275881 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035882
5883 SendRequestAndExpectHttpResponse("hello from http");
5884}
5885
[email protected]eb71ab62014-05-23 07:57:535886TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335887 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015888 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495889 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335890 socket_factory_.AddSocketDataProvider(&quic_data);
5891
5892 // Main job which will succeed even though the alternate job fails.
5893 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025894 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5895 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5896 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335897
Ryan Sleevib8d7ea02018-05-07 20:01:015898 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335899 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565900 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335901
rch3f4b8452016-02-23 16:59:325902 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275903 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335904 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535905
5906 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335907}
5908
[email protected]4fee9672014-01-08 14:47:155909TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155910 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175911 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5912 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045913 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155914
5915 // When the QUIC connection fails, we will try the request again over HTTP.
5916 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485917 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565918 MockRead("hello world"),
5919 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5920 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155921
Ryan Sleevib8d7ea02018-05-07 20:01:015922 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155923 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565924 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155925
5926 // In order for a new QUIC session to be established via alternate-protocol
5927 // without racing an HTTP connection, we need the host resolution to happen
5928 // synchronously.
5929 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295930 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565931 "");
rch9ae5b3b2016-02-11 00:36:295932 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155933 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105934 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585935 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5936 CompletionOnceCallback(), &request,
5937 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415938 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155939
rch3f4b8452016-02-23 16:59:325940 CreateSession();
David Schinazic8281052019-01-24 06:14:175941 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5942 AddQuicAlternateProtocolMapping(
5943 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155944 SendRequestAndExpectHttpResponse("hello world");
5945}
5946
tbansalc3308d72016-08-27 10:25:045947// For an alternative proxy that supports QUIC, test that the request is
5948// successfully fetched by the main job when the alternate proxy job encounters
5949// an error.
5950TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5951 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5952}
5953TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5954 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5955}
5956TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5957 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5958}
5959TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5960 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5961}
5962TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5963 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5964}
5965TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5966 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5967}
5968TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5969 TestAlternativeProxy(ERR_IO_PENDING);
5970}
5971TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5972 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5973}
5974
5975TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5976 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175977 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5978 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335979 mock_quic_data.AddWrite(
5980 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5981 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5982 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435983 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045984 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5985
5986 // When the QUIC connection fails, we will try the request again over HTTP.
5987 MockRead http_reads[] = {
5988 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5989 MockRead("hello world"),
5990 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5991 MockRead(ASYNC, OK)};
5992
Ryan Sleevib8d7ea02018-05-07 20:01:015993 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045994 socket_factory_.AddSocketDataProvider(&http_data);
5995 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5996
5997 TestProxyDelegate test_proxy_delegate;
5998 const HostPortPair host_port_pair("myproxy.org", 443);
5999 test_proxy_delegate.set_alternative_proxy_server(
6000 ProxyServer::FromPacString("QUIC myproxy.org:443"));
6001 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6002
Ramin Halavatica8d5252018-03-12 05:33:496003 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
6004 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:526005 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046006 request_.url = GURL("http://mail.example.org/");
6007
6008 // In order for a new QUIC session to be established via alternate-protocol
6009 // without racing an HTTP connection, we need the host resolution to happen
6010 // synchronously.
6011 host_resolver_.set_synchronous_mode(true);
6012 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
6013 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
6014 AddressList address;
6015 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:586016 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
6017 CompletionOnceCallback(), &request,
6018 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:416019 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:046020
6021 CreateSession();
David Schinazic8281052019-01-24 06:14:176022 crypto_client_stream_factory_.set_handshake_mode(
6023 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:046024 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:596025 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:166026 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:046027}
6028
bnc508835902015-05-12 20:10:296029TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:586030 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:386031 EXPECT_FALSE(
6032 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296033 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526034 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366035 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436036 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6037 mock_quic_data.AddWrite(
6038 SYNCHRONOUS,
6039 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336040 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436041 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436042 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336043 ASYNC, ConstructServerResponseHeadersPacket(
6044 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6045 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416046 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336047 mock_quic_data.AddRead(
6048 ASYNC, ConstructServerDataPacket(
6049 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416050 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436051 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:506052 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:296053 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6054
bncb07c05532015-05-14 19:07:206055 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:096056 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:326057 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:276058 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:296059 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:386060 EXPECT_TRUE(
6061 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:296062}
6063
zhongyi363c91c2017-03-23 23:16:086064// TODO(zhongyi): disabled this broken test as it was not testing the correct
6065// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
6066TEST_P(QuicNetworkTransactionTest,
6067 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:276068 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:596069 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:496070 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:046071
6072 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:046073
6074 test_proxy_delegate.set_alternative_proxy_server(
6075 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:526076 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:046077
6078 request_.url = GURL("http://mail.example.org/");
6079
6080 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6081 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016082 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046083 socket_factory_.AddSocketDataProvider(&socket_data);
6084
6085 // The non-alternate protocol job needs to hang in order to guarantee that
6086 // the alternate-protocol job will "win".
6087 AddHangingNonAlternateProtocolSocketData();
6088
6089 CreateSession();
6090 request_.method = "POST";
6091 ChunkedUploadDataStream upload_data(0);
6092 upload_data.AppendData("1", 1, true);
6093
6094 request_.upload_data_stream = &upload_data;
6095
6096 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6097 TestCompletionCallback callback;
6098 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6099 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6100 EXPECT_NE(OK, callback.WaitForResult());
6101
6102 // Verify that the alternative proxy server is not marked as broken.
6103 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6104
6105 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596106 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276107
6108 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6109 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6110 1);
tbansalc3308d72016-08-27 10:25:046111}
6112
rtenneti56977812016-01-15 19:26:566113TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:416114 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576115 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566116
6117 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6118 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016119 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:566120 socket_factory_.AddSocketDataProvider(&socket_data);
6121
rtennetib8e80fb2016-05-16 00:12:096122 // The non-alternate protocol job needs to hang in order to guarantee that
6123 // the alternate-protocol job will "win".
6124 AddHangingNonAlternateProtocolSocketData();
6125
rtenneti56977812016-01-15 19:26:566126 CreateSession();
6127 request_.method = "POST";
6128 ChunkedUploadDataStream upload_data(0);
6129 upload_data.AppendData("1", 1, true);
6130
6131 request_.upload_data_stream = &upload_data;
6132
bnc691fda62016-08-12 00:43:166133 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566134 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166135 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566137 EXPECT_NE(OK, callback.WaitForResult());
6138}
6139
rche11300ef2016-09-02 01:44:286140TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486141 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286142 ScopedMockNetworkChangeNotifier network_change_notifier;
6143 MockNetworkChangeNotifier* mock_ncn =
6144 network_change_notifier.mock_network_change_notifier();
6145 mock_ncn->ForceNetworkHandlesSupported();
6146 mock_ncn->SetConnectedNetworksList(
6147 {kDefaultNetworkForTests, kNewNetworkForTests});
6148
mmenke6ddfbea2017-05-31 21:48:416149 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286150 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316151 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286152
6153 MockQuicData socket_data;
6154 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526155 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436156 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336157 socket_data.AddWrite(
6158 SYNCHRONOUS,
6159 ConstructClientRequestHeadersPacket(
6160 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6161 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286162 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6163 socket_data.AddSocketDataToFactory(&socket_factory_);
6164
6165 MockQuicData socket_data2;
6166 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6167 socket_data2.AddSocketDataToFactory(&socket_factory_);
6168
6169 // The non-alternate protocol job needs to hang in order to guarantee that
6170 // the alternate-protocol job will "win".
6171 AddHangingNonAlternateProtocolSocketData();
6172
6173 CreateSession();
6174 request_.method = "POST";
6175 ChunkedUploadDataStream upload_data(0);
6176
6177 request_.upload_data_stream = &upload_data;
6178
rdsmith1d343be52016-10-21 20:37:506179 std::unique_ptr<HttpNetworkTransaction> trans(
6180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286181 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506182 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286183 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6184
6185 base::RunLoop().RunUntilIdle();
6186 upload_data.AppendData("1", 1, true);
6187 base::RunLoop().RunUntilIdle();
6188
6189 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506190 trans.reset();
rche11300ef2016-09-02 01:44:286191 session_.reset();
6192}
6193
Ryan Hamilton4b3574532017-10-30 20:17:256194TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6195 session_params_.origins_to_force_quic_on.insert(
6196 HostPortPair::FromString("mail.example.org:443"));
6197
6198 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526199 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436200 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256201 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336202 socket_data.AddWrite(
6203 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6204 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6205 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436206 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336207 ASYNC, ConstructServerResponseHeadersPacket(
6208 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6209 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416210 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336211 socket_data.AddRead(
6212 ASYNC, ConstructServerDataPacket(
6213 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416214 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436215 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256216 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166217 socket_data.AddWrite(
6218 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6219 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6220 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256221
6222 socket_data.AddSocketDataToFactory(&socket_factory_);
6223
6224 CreateSession();
6225
6226 SendRequestAndExpectQuicResponse("hello!");
6227 session_.reset();
6228}
6229
6230TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6231 session_params_.origins_to_force_quic_on.insert(
6232 HostPortPair::FromString("mail.example.org:443"));
6233
6234 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526235 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436236 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256237 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336238 socket_data.AddWrite(
6239 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6240 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6241 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436242 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336243 ASYNC, ConstructServerResponseHeadersPacket(
6244 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6245 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416246 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336247 socket_data.AddRead(
6248 ASYNC, ConstructServerDataPacket(
6249 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416250 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436251 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256252 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166253 socket_data.AddWrite(
6254 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6255 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6256 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256257
6258 socket_data.AddSocketDataToFactory(&socket_factory_);
6259
6260 CreateSession();
6261
6262 SendRequestAndExpectQuicResponse("hello!");
6263 session_.reset();
6264}
6265
Ryan Hamilton9edcf1a2017-11-22 05:55:176266TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486267 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256268 session_params_.origins_to_force_quic_on.insert(
6269 HostPortPair::FromString("mail.example.org:443"));
6270
6271 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526272 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256273 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436274 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176275 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256276 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6277 }
6278 socket_data.AddSocketDataToFactory(&socket_factory_);
6279
6280 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176281 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6282 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6283 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6284 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256285
Ryan Hamilton8d9ee76e2018-05-29 23:52:526286 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256287 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6288 TestCompletionCallback callback;
6289 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6290 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176291 while (!callback.have_result()) {
6292 base::RunLoop().RunUntilIdle();
6293 quic_task_runner_->RunUntilIdle();
6294 }
6295 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256296 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176297 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6298 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6299 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526300 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6301 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256302}
6303
Ryan Hamilton9edcf1a2017-11-22 05:55:176304TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486305 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256306 session_params_.origins_to_force_quic_on.insert(
6307 HostPortPair::FromString("mail.example.org:443"));
6308
6309 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526310 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256311 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436312 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176313 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256314 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6315 }
6316 socket_data.AddSocketDataToFactory(&socket_factory_);
6317
6318 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176319 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6320 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6321 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6322 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256323
Ryan Hamilton8d9ee76e2018-05-29 23:52:526324 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256325 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6326 TestCompletionCallback callback;
6327 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176329 while (!callback.have_result()) {
6330 base::RunLoop().RunUntilIdle();
6331 quic_task_runner_->RunUntilIdle();
6332 }
6333 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256334 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176335 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6336 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6337 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526338 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6339 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256340}
6341
Cherie Shi7596de632018-02-22 07:28:186342TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486343 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186344 session_params_.origins_to_force_quic_on.insert(
6345 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526346 const quic::QuicString error_details =
6347 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6348 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186349
6350 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526351 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186352 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436353 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186354 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6355 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526356 socket_data.AddWrite(
6357 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6358 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186359 socket_data.AddSocketDataToFactory(&socket_factory_);
6360
6361 CreateSession();
6362
6363 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6364 TestCompletionCallback callback;
6365 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6366 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6367 base::RunLoop().RunUntilIdle();
6368 ASSERT_TRUE(callback.have_result());
6369 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6370 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6371 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6372}
6373
ckrasic769733c2016-06-30 00:42:136374// Adds coverage to catch regression such as https://crbug.com/622043
6375TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416376 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136377 HostPortPair::FromString("mail.example.org:443"));
6378
6379 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526380 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236381 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436382 mock_quic_data.AddWrite(
6383 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6384 &header_stream_offset));
6385 mock_quic_data.AddWrite(
6386 SYNCHRONOUS,
6387 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336388 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6389 true, true, GetRequestHeaders("GET", "https", "/"),
6390 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526391 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436392 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336393 ASYNC, ConstructServerPushPromisePacket(
6394 1, GetNthClientInitiatedBidirectionalStreamId(0),
6395 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6396 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6397 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576398 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266399 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336400 mock_quic_data.AddWrite(SYNCHRONOUS,
6401 ConstructClientPriorityPacket(
6402 client_packet_number++, false,
6403 GetNthServerInitiatedUnidirectionalStreamId(0),
6404 GetNthClientInitiatedBidirectionalStreamId(0),
6405 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576406 }
Zhongyi Shi32f2fd02018-04-16 18:23:436407 mock_quic_data.AddRead(
6408 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336409 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436410 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576411 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436412 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6413 mock_quic_data.AddRead(
6414 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336415 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6416 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416417 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436418 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336419 ASYNC, ConstructServerDataPacket(
6420 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416421 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576422 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436423 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416424 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436425 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336426 ASYNC, ConstructServerDataPacket(
6427 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416428 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336429 mock_quic_data.AddWrite(SYNCHRONOUS,
6430 ConstructClientAckAndRstPacket(
6431 client_packet_number++,
6432 GetNthServerInitiatedUnidirectionalStreamId(0),
6433 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136434 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6435 mock_quic_data.AddRead(ASYNC, 0); // EOF
6436 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6437
6438 // The non-alternate protocol job needs to hang in order to guarantee that
6439 // the alternate-protocol job will "win".
6440 AddHangingNonAlternateProtocolSocketData();
6441
6442 CreateSession();
6443
6444 // PUSH_PROMISE handling in the http layer gets exercised here.
6445 SendRequestAndExpectQuicResponse("hello!");
6446
6447 request_.url = GURL("https://mail.example.org/pushed.jpg");
6448 SendRequestAndExpectQuicResponse("and hello!");
6449
6450 // Check that the NetLog was filled reasonably.
6451 TestNetLogEntry::List entries;
6452 net_log_.GetEntries(&entries);
6453 EXPECT_LT(0u, entries.size());
6454
6455 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6456 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006457 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6458 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136459 EXPECT_LT(0, pos);
6460}
6461
rch56ec40a2017-06-23 14:48:446462// Regression test for http://crbug.com/719461 in which a promised stream
6463// is closed before the pushed headers arrive, but after the connection
6464// is closed and before the callbacks are executed.
6465TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486466 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446467 session_params_.origins_to_force_quic_on.insert(
6468 HostPortPair::FromString("mail.example.org:443"));
6469
6470 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526471 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236472 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446473 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436474 mock_quic_data.AddWrite(
6475 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6476 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446477 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436478 mock_quic_data.AddWrite(
6479 SYNCHRONOUS,
6480 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336481 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6482 true, true, GetRequestHeaders("GET", "https", "/"),
6483 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526484 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446485 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436486 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336487 ASYNC, ConstructServerPushPromisePacket(
6488 1, GetNthClientInitiatedBidirectionalStreamId(0),
6489 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6490 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6491 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576492 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266493 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336494 mock_quic_data.AddWrite(SYNCHRONOUS,
6495 ConstructClientPriorityPacket(
6496 client_packet_number++, false,
6497 GetNthServerInitiatedUnidirectionalStreamId(0),
6498 GetNthClientInitiatedBidirectionalStreamId(0),
6499 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576500 }
rch56ec40a2017-06-23 14:48:446501 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436502 mock_quic_data.AddRead(
6503 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336504 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436505 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446506 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576507 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436508 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446509 // Response body for first request.
Renjief49758b2019-01-11 23:32:416510 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436511 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336512 ASYNC, ConstructServerDataPacket(
6513 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416514 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446515 // Write error for the third request.
6516 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6517 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6518 mock_quic_data.AddRead(ASYNC, 0); // EOF
6519 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6520
6521 CreateSession();
6522
6523 // Send a request which triggers a push promise from the server.
6524 SendRequestAndExpectQuicResponse("hello!");
6525
6526 // Start a push transaction that will be cancelled after the connection
6527 // is closed, but before the callback is executed.
6528 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196529 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446530 session_.get());
6531 TestCompletionCallback callback2;
6532 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6533 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6534 base::RunLoop().RunUntilIdle();
6535
6536 // Cause the connection to close on a write error.
6537 HttpRequestInfo request3;
6538 request3.method = "GET";
6539 request3.url = GURL("https://mail.example.org/");
6540 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106541 request3.traffic_annotation =
6542 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446543 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6544 TestCompletionCallback callback3;
6545 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6546 IsError(ERR_IO_PENDING));
6547
6548 base::RunLoop().RunUntilIdle();
6549
6550 // When |trans2| is destroyed, the underlying stream will be closed.
6551 EXPECT_FALSE(callback2.have_result());
6552 trans2 = nullptr;
6553
6554 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6555}
6556
ckrasicda193a82016-07-09 00:39:366557TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416558 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366559 HostPortPair::FromString("mail.example.org:443"));
6560
6561 MockQuicData mock_quic_data;
6562
Ryan Hamilton8d9ee76e2018-05-29 23:52:526563 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416564 int write_packet_index = 1;
6565 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6566 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366567
Renjief49758b2019-01-11 23:32:416568 quic::QuicString header = ConstructDataHeader(1);
6569 if (version_ != quic::QUIC_VERSION_99) {
6570 mock_quic_data.AddWrite(
6571 SYNCHRONOUS,
6572 ConstructClientRequestHeadersAndDataFramesPacket(
6573 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6574 true, true, DEFAULT_PRIORITY,
6575 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6576 {"1"}));
6577 } else {
6578 mock_quic_data.AddWrite(
6579 SYNCHRONOUS,
6580 ConstructClientRequestHeadersAndDataFramesPacket(
6581 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6582 true, true, DEFAULT_PRIORITY,
6583 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6584 {header, "1"}));
6585 }
ckrasicda193a82016-07-09 00:39:366586
Zhongyi Shi32f2fd02018-04-16 18:23:436587 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336588 ASYNC, ConstructServerResponseHeadersPacket(
6589 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6590 GetResponseHeaders("200 OK")));
6591
Renjief49758b2019-01-11 23:32:416592 quic::QuicString header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336593 mock_quic_data.AddRead(
6594 ASYNC, ConstructServerDataPacket(
6595 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416596 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366597
Renjief49758b2019-01-11 23:32:416598 mock_quic_data.AddWrite(
6599 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366600
6601 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6602 mock_quic_data.AddRead(ASYNC, 0); // EOF
6603 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6604
6605 // The non-alternate protocol job needs to hang in order to guarantee that
6606 // the alternate-protocol job will "win".
6607 AddHangingNonAlternateProtocolSocketData();
6608
6609 CreateSession();
6610 request_.method = "POST";
6611 ChunkedUploadDataStream upload_data(0);
6612 upload_data.AppendData("1", 1, true);
6613
6614 request_.upload_data_stream = &upload_data;
6615
6616 SendRequestAndExpectQuicResponse("hello!");
6617}
6618
allada71b2efb2016-09-09 04:57:486619class QuicURLRequestContext : public URLRequestContext {
6620 public:
6621 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6622 MockClientSocketFactory* socket_factory)
6623 : storage_(this) {
6624 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076625 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046626 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486627 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046628 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596629 storage_.set_proxy_resolution_service(
6630 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076631 storage_.set_ssl_config_service(
6632 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486633 storage_.set_http_auth_handler_factory(
6634 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6635 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076636 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046637 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486638 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046639 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6640 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6641 false));
allada71b2efb2016-09-09 04:57:486642 }
6643
6644 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6645
6646 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6647
6648 private:
6649 MockClientSocketFactory* socket_factory_;
6650 URLRequestContextStorage storage_;
6651};
6652
6653TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416654 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486655 HostPortPair::FromString("mail.example.org:443"));
6656
6657 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526658 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366659 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436660 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136661 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486662 headers["user-agent"] = "";
6663 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336664 mock_quic_data.AddWrite(
6665 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6666 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6667 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486668
Ryan Hamilton8d9ee76e2018-05-29 23:52:526669 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336670 mock_quic_data.AddRead(
6671 ASYNC,
6672 ConstructServerResponseHeadersPacket(
6673 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6674 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486675
Renjief49758b2019-01-11 23:32:416676 quic::QuicString header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366677 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336678 ASYNC, ConstructServerDataPacket(
6679 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6680 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436681 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486682
6683 mock_quic_data.AddRead(ASYNC, 0); // EOF
6684
6685 CreateSession();
6686
6687 TestDelegate delegate;
6688 QuicURLRequestContext quic_url_request_context(std::move(session_),
6689 &socket_factory_);
6690
6691 mock_quic_data.AddSocketDataToFactory(
6692 &quic_url_request_context.socket_factory());
6693 TestNetworkDelegate network_delegate;
6694 quic_url_request_context.set_network_delegate(&network_delegate);
6695
6696 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296697 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6698 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486699 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6700 &ssl_data_);
6701
6702 request->Start();
Wez2a31b222018-06-07 22:07:156703 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486704
6705 EXPECT_LT(0, request->GetTotalSentBytes());
6706 EXPECT_LT(0, request->GetTotalReceivedBytes());
6707 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6708 request->GetTotalSentBytes());
6709 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6710 request->GetTotalReceivedBytes());
6711 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6712 request->raw_header_size());
Wez0e717112018-06-18 23:09:226713
6714 // Pump the message loop to allow all data to be consumed.
6715 base::RunLoop().RunUntilIdle();
6716
allada71b2efb2016-09-09 04:57:486717 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6718 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6719}
6720
6721TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416722 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486723 HostPortPair::FromString("mail.example.org:443"));
6724
6725 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526726 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236727 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436728 mock_quic_data.AddWrite(
6729 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6730 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136731 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486732 headers["user-agent"] = "";
6733 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436734 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336735 SYNCHRONOUS,
6736 ConstructClientRequestHeadersPacket(
6737 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6738 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486739
Ryan Hamilton8d9ee76e2018-05-29 23:52:526740 quic::QuicStreamOffset server_header_offset = 0;
6741 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486742
Zhongyi Shi32f2fd02018-04-16 18:23:436743 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336744 ASYNC, ConstructServerPushPromisePacket(
6745 1, GetNthClientInitiatedBidirectionalStreamId(0),
6746 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6747 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6748 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486749
Yixin Wangb470bc882018-02-15 18:43:576750 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266751 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336752 mock_quic_data.AddWrite(SYNCHRONOUS,
6753 ConstructClientPriorityPacket(
6754 client_packet_number++, false,
6755 GetNthServerInitiatedUnidirectionalStreamId(0),
6756 GetNthClientInitiatedBidirectionalStreamId(0),
6757 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576758 }
6759
allada71b2efb2016-09-09 04:57:486760 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436761 mock_quic_data.AddRead(
6762 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336763 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436764 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486765 expected_raw_header_response_size =
6766 server_header_offset - expected_raw_header_response_size;
6767
Yixin Wangb470bc882018-02-15 18:43:576768 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436769 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486770
ckrasicbf2f59c2017-05-04 23:54:366771 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436772 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336773 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6774 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416775 quic::QuicString header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436776 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336777 ASYNC, ConstructServerDataPacket(
6778 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416779 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486780
Yixin Wangb470bc882018-02-15 18:43:576781 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436782 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416783 quic::QuicString header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366784 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336785 ASYNC, ConstructServerDataPacket(
6786 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416787 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486788
Zhongyi Shi32f2fd02018-04-16 18:23:436789 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486790
6791 CreateSession();
6792
6793 TestDelegate delegate;
6794 QuicURLRequestContext quic_url_request_context(std::move(session_),
6795 &socket_factory_);
6796
6797 mock_quic_data.AddSocketDataToFactory(
6798 &quic_url_request_context.socket_factory());
6799 TestNetworkDelegate network_delegate;
6800 quic_url_request_context.set_network_delegate(&network_delegate);
6801
6802 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296803 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6804 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486805 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6806 &ssl_data_);
6807
6808 request->Start();
Wez2a31b222018-06-07 22:07:156809 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486810
6811 EXPECT_LT(0, request->GetTotalSentBytes());
6812 EXPECT_LT(0, request->GetTotalReceivedBytes());
6813 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6814 request->GetTotalSentBytes());
6815 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6816 request->GetTotalReceivedBytes());
6817 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6818 request->raw_header_size());
Wez0e717112018-06-18 23:09:226819
6820 // Pump the message loop to allow all data to be consumed.
6821 base::RunLoop().RunUntilIdle();
6822
allada71b2efb2016-09-09 04:57:486823 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6824 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6825}
6826
Yixin Wang10f477ed2017-11-21 04:20:206827TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6828 session_params_.quic_host_whitelist.insert("mail.example.org");
6829
6830 MockRead http_reads[] = {
6831 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6832 MockRead("hello world"),
6833 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6834 MockRead(ASYNC, OK)};
6835
Ryan Sleevib8d7ea02018-05-07 20:01:016836 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206837 socket_factory_.AddSocketDataProvider(&http_data);
6838 AddCertificate(&ssl_data_);
6839 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6840
6841 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526842 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206843 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436844 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6845 mock_quic_data.AddWrite(
6846 SYNCHRONOUS,
6847 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336848 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436849 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436850 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336851 ASYNC, ConstructServerResponseHeadersPacket(
6852 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6853 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416854 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336855 mock_quic_data.AddRead(
6856 ASYNC, ConstructServerDataPacket(
6857 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416858 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436859 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206860 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6861 mock_quic_data.AddRead(ASYNC, 0); // EOF
6862
6863 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6864
6865 AddHangingNonAlternateProtocolSocketData();
6866 CreateSession();
6867
6868 SendRequestAndExpectHttpResponse("hello world");
6869 SendRequestAndExpectQuicResponse("hello!");
6870}
6871
6872TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6873 session_params_.quic_host_whitelist.insert("mail.example.com");
6874
6875 MockRead http_reads[] = {
6876 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6877 MockRead("hello world"),
6878 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6879 MockRead(ASYNC, OK)};
6880
Ryan Sleevib8d7ea02018-05-07 20:01:016881 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206882 socket_factory_.AddSocketDataProvider(&http_data);
6883 AddCertificate(&ssl_data_);
6884 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6885 socket_factory_.AddSocketDataProvider(&http_data);
6886 AddCertificate(&ssl_data_);
6887 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6888
6889 AddHangingNonAlternateProtocolSocketData();
6890 CreateSession();
6891
6892 SendRequestAndExpectHttpResponse("hello world");
6893 SendRequestAndExpectHttpResponse("hello world");
6894}
6895
bnc359ed2a2016-04-29 20:43:456896class QuicNetworkTransactionWithDestinationTest
6897 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016898 public ::testing::WithParamInterface<PoolingTestParams>,
6899 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456900 protected:
6901 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556902 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056903 client_headers_include_h2_stream_dependency_(
6904 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526905 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456906 destination_type_(GetParam().destination_type),
6907 cert_transparency_verifier_(new MultiLogCTVerifier()),
6908 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596909 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456910 auth_handler_factory_(
6911 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6912 random_generator_(0),
6913 ssl_data_(ASYNC, OK) {}
6914
6915 void SetUp() override {
6916 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556917 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456918
mmenke6ddfbea2017-05-31 21:48:416919 HttpNetworkSession::Params session_params;
6920 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346921 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446922 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056923 session_params.quic_headers_include_h2_stream_dependency =
6924 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416925
6926 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456927
Ryan Hamilton8d9ee76e2018-05-29 23:52:526928 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416929 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456930
6931 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276932 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416933 session_context.quic_crypto_client_stream_factory =
6934 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456935
mmenke6ddfbea2017-05-31 21:48:416936 session_context.quic_random = &random_generator_;
6937 session_context.client_socket_factory = &socket_factory_;
6938 session_context.host_resolver = &host_resolver_;
6939 session_context.cert_verifier = &cert_verifier_;
6940 session_context.transport_security_state = &transport_security_state_;
6941 session_context.cert_transparency_verifier =
6942 cert_transparency_verifier_.get();
6943 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6944 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456945 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416946 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596947 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416948 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6949 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456950
mmenke6ddfbea2017-05-31 21:48:416951 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456952 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456953 }
6954
6955 void TearDown() override {
6956 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6957 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556958 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456959 PlatformTest::TearDown();
6960 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556961 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406962 session_.reset();
bnc359ed2a2016-04-29 20:43:456963 }
6964
zhongyie537a002017-06-27 16:48:216965 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456966 HostPortPair destination;
6967 switch (destination_type_) {
6968 case SAME_AS_FIRST:
6969 destination = HostPortPair(origin1_, 443);
6970 break;
6971 case SAME_AS_SECOND:
6972 destination = HostPortPair(origin2_, 443);
6973 break;
6974 case DIFFERENT:
6975 destination = HostPortPair(kDifferentHostname, 443);
6976 break;
6977 }
bnc3472afd2016-11-17 15:27:216978 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456979 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216980 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456981 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446982 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456983 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526984 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236985 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526986 quic::QuicStreamId stream_id,
6987 bool should_include_version,
6988 quic::QuicStreamOffset* offset,
6989 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486990 return ConstructClientRequestHeadersPacket(
6991 packet_number, stream_id, should_include_version, 0, offset, maker);
6992 }
bnc359ed2a2016-04-29 20:43:456993
Ryan Hamilton8d9ee76e2018-05-29 23:52:526994 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236995 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526996 quic::QuicStreamId stream_id,
6997 bool should_include_version,
6998 quic::QuicStreamId parent_stream_id,
6999 quic::QuicStreamOffset* offset,
7000 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137001 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:457002 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:137003 spdy::SpdyHeaderBlock headers(
7004 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:457005 return maker->MakeRequestHeadersPacketWithOffsetTracking(
7006 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:487007 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:457008 }
7009
Ryan Hamilton8d9ee76e2018-05-29 23:52:527010 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237011 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527012 quic::QuicStreamId stream_id,
7013 bool should_include_version,
7014 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587015 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:457016 packet_number, stream_id, should_include_version, nullptr, maker);
7017 }
7018
Ryan Hamilton8d9ee76e2018-05-29 23:52:527019 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237020 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527021 quic::QuicStreamId stream_id,
7022 quic::QuicStreamOffset* offset,
7023 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:137024 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:457025 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:267026 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:457027 }
7028
Ryan Hamilton8d9ee76e2018-05-29 23:52:527029 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:237030 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527031 quic::QuicStreamId stream_id,
7032 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:587033 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
7034 nullptr, maker);
bnc359ed2a2016-04-29 20:43:457035 }
7036
Ryan Hamilton8d9ee76e2018-05-29 23:52:527037 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:237038 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527039 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:457040 QuicTestPacketMaker* maker) {
Renjief49758b2019-01-11 23:32:417041 quic::QuicString header = "";
7042 if (version_ == quic::QUIC_VERSION_99) {
7043 quic::HttpEncoder encoder;
7044 std::unique_ptr<char[]> buffer;
7045 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
7046 header = quic::QuicString(buffer.get(), header_length);
7047 }
bnc359ed2a2016-04-29 20:43:457048 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:417049 header + "hello");
bnc359ed2a2016-04-29 20:43:457050 }
7051
Ryan Hamilton8d9ee76e2018-05-29 23:52:527052 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:237053 uint64_t packet_number,
7054 uint64_t largest_received,
7055 uint64_t smallest_received,
7056 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:457057 QuicTestPacketMaker* maker) {
7058 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:497059 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:457060 }
7061
Ryan Hamilton8d9ee76e2018-05-29 23:52:527062 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:237063 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527064 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:377065 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:367066 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:377067 }
7068
bnc359ed2a2016-04-29 20:43:457069 void AddRefusedSocketData() {
7070 std::unique_ptr<StaticSocketDataProvider> refused_data(
7071 new StaticSocketDataProvider());
7072 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
7073 refused_data->set_connect_data(refused_connect);
7074 socket_factory_.AddSocketDataProvider(refused_data.get());
7075 static_socket_data_provider_vector_.push_back(std::move(refused_data));
7076 }
7077
7078 void AddHangingSocketData() {
7079 std::unique_ptr<StaticSocketDataProvider> hanging_data(
7080 new StaticSocketDataProvider());
7081 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
7082 hanging_data->set_connect_data(hanging_connect);
7083 socket_factory_.AddSocketDataProvider(hanging_data.get());
7084 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
7085 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7086 }
7087
7088 bool AllDataConsumed() {
7089 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
7090 if (!socket_data_ptr->AllReadDataConsumed() ||
7091 !socket_data_ptr->AllWriteDataConsumed()) {
7092 return false;
7093 }
7094 }
7095 return true;
7096 }
7097
7098 void SendRequestAndExpectQuicResponse(const std::string& host) {
7099 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7100 HttpRequestInfo request;
7101 std::string url("https://");
7102 url.append(host);
7103 request.url = GURL(url);
7104 request.load_flags = 0;
7105 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:107106 request.traffic_annotation =
7107 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457108 TestCompletionCallback callback;
7109 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017110 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:457111
7112 std::string response_data;
robpercival214763f2016-07-01 23:27:017113 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457114 EXPECT_EQ("hello", response_data);
7115
7116 const HttpResponseInfo* response = trans.GetResponseInfo();
7117 ASSERT_TRUE(response != nullptr);
7118 ASSERT_TRUE(response->headers.get() != nullptr);
7119 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7120 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527121 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:447122 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457123 response->connection_info);
7124 EXPECT_EQ(443, response->socket_address.port());
7125 }
7126
Fan Yang32c5a112018-12-10 20:06:337127 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
7128 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:367129 }
7130
Ryan Hamilton8d9ee76e2018-05-29 23:52:527131 quic::MockClock clock_;
7132 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:057133 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527134 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457135 DestinationType destination_type_;
7136 std::string origin1_;
7137 std::string origin2_;
7138 std::unique_ptr<HttpNetworkSession> session_;
7139 MockClientSocketFactory socket_factory_;
7140 MockHostResolver host_resolver_;
7141 MockCertVerifier cert_verifier_;
7142 TransportSecurityState transport_security_state_;
7143 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237144 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457145 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077146 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597147 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457148 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527149 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457150 HttpServerPropertiesImpl http_server_properties_;
7151 BoundTestNetLog net_log_;
7152 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7153 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7154 static_socket_data_provider_vector_;
7155 SSLSocketDataProvider ssl_data_;
7156};
7157
Victor Costane635086f2019-01-27 05:20:307158INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
7159 QuicNetworkTransactionWithDestinationTest,
7160 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:457161
7162// A single QUIC request fails because the certificate does not match the origin
7163// hostname, regardless of whether it matches the alternative service hostname.
7164TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7165 if (destination_type_ == DIFFERENT)
7166 return;
7167
7168 GURL url("https://mail.example.com/");
7169 origin1_ = url.host();
7170
7171 // Not used for requests, but this provides a test case where the certificate
7172 // is valid for the hostname of the alternative service.
7173 origin2_ = "mail.example.org";
7174
zhongyie537a002017-06-27 16:48:217175 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457176
7177 scoped_refptr<X509Certificate> cert(
7178 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247179 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7180 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457181
7182 ProofVerifyDetailsChromium verify_details;
7183 verify_details.cert_verify_result.verified_cert = cert;
7184 verify_details.cert_verify_result.is_issued_by_known_root = true;
7185 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7186
7187 MockQuicData mock_quic_data;
7188 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7189 mock_quic_data.AddRead(ASYNC, 0);
7190
7191 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7192
7193 AddRefusedSocketData();
7194
7195 HttpRequestInfo request;
7196 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107197 request.traffic_annotation =
7198 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457199
7200 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7201 TestCompletionCallback callback;
7202 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017203 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457204
7205 EXPECT_TRUE(AllDataConsumed());
7206}
7207
7208// First request opens QUIC session to alternative service. Second request
7209// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527210// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457211TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7212 origin1_ = "mail.example.org";
7213 origin2_ = "news.example.org";
7214
zhongyie537a002017-06-27 16:48:217215 SetQuicAlternativeService(origin1_);
7216 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457217
7218 scoped_refptr<X509Certificate> cert(
7219 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247220 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7221 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7222 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457223
7224 ProofVerifyDetailsChromium verify_details;
7225 verify_details.cert_verify_result.verified_cert = cert;
7226 verify_details.cert_verify_result.is_issued_by_known_root = true;
7227 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7228
Yixin Wang079ad542018-01-11 04:06:057229 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177230 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7231 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057232 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177233 QuicTestPacketMaker server_maker(
7234 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7235 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457236
Ryan Hamilton8d9ee76e2018-05-29 23:52:527237 quic::QuicStreamOffset request_header_offset(0);
7238 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457239
7240 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057241 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437242 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057243 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337244 mock_quic_data.AddWrite(
7245 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7246 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7247 &request_header_offset, &client_maker));
7248 mock_quic_data.AddRead(ASYNC,
7249 ConstructServerResponseHeadersPacket(
7250 1, GetNthClientInitiatedBidirectionalStreamId(0),
7251 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437252 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337253 ASYNC,
7254 ConstructServerDataPacket(
7255 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437256 mock_quic_data.AddWrite(SYNCHRONOUS,
7257 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457258
Yixin Wang079ad542018-01-11 04:06:057259 client_maker.set_hostname(origin2_);
7260 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457261
Zhongyi Shi32f2fd02018-04-16 18:23:437262 mock_quic_data.AddWrite(
7263 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337264 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7265 GetNthClientInitiatedBidirectionalStreamId(0),
7266 &request_header_offset, &client_maker));
7267 mock_quic_data.AddRead(ASYNC,
7268 ConstructServerResponseHeadersPacket(
7269 3, GetNthClientInitiatedBidirectionalStreamId(1),
7270 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437271 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337272 ASYNC,
7273 ConstructServerDataPacket(
7274 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437275 mock_quic_data.AddWrite(SYNCHRONOUS,
7276 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457277 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7278 mock_quic_data.AddRead(ASYNC, 0); // EOF
7279
7280 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7281
7282 AddHangingSocketData();
7283 AddHangingSocketData();
7284
Fan Yangc9e00dc2018-10-09 14:17:567285 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7286 QuicStreamFactoryPeer::SetAlarmFactory(
7287 session_->quic_stream_factory(),
7288 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7289 &clock_));
7290
bnc359ed2a2016-04-29 20:43:457291 SendRequestAndExpectQuicResponse(origin1_);
7292 SendRequestAndExpectQuicResponse(origin2_);
7293
7294 EXPECT_TRUE(AllDataConsumed());
7295}
7296
7297// First request opens QUIC session to alternative service. Second request does
7298// not pool to it, even though destination matches, because certificate is not
7299// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527300// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457301TEST_P(QuicNetworkTransactionWithDestinationTest,
7302 DoNotPoolIfCertificateInvalid) {
7303 origin1_ = "news.example.org";
7304 origin2_ = "mail.example.com";
7305
zhongyie537a002017-06-27 16:48:217306 SetQuicAlternativeService(origin1_);
7307 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457308
7309 scoped_refptr<X509Certificate> cert1(
7310 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247311 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7312 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7313 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457314
7315 scoped_refptr<X509Certificate> cert2(
7316 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247317 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7318 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457319
7320 ProofVerifyDetailsChromium verify_details1;
7321 verify_details1.cert_verify_result.verified_cert = cert1;
7322 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7323 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7324
7325 ProofVerifyDetailsChromium verify_details2;
7326 verify_details2.cert_verify_result.verified_cert = cert2;
7327 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7328 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7329
Yixin Wang079ad542018-01-11 04:06:057330 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177331 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7332 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057333 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177334 QuicTestPacketMaker server_maker1(
7335 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7336 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457337
7338 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527339 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457340 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437341 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7342 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337343 mock_quic_data1.AddWrite(
7344 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7345 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7346 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437347 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337348 ASYNC,
7349 ConstructServerResponseHeadersPacket(
7350 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437351 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337352 ASYNC,
7353 ConstructServerDataPacket(
7354 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437355 mock_quic_data1.AddWrite(
7356 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457357 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7358 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7359
7360 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7361
Yixin Wang079ad542018-01-11 04:06:057362 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177363 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7364 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057365 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177366 QuicTestPacketMaker server_maker2(
7367 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7368 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457369
7370 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527371 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457372 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437373 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7374 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337375 mock_quic_data2.AddWrite(
7376 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7377 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7378 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437379 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337380 ASYNC,
7381 ConstructServerResponseHeadersPacket(
7382 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437383 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337384 ASYNC,
7385 ConstructServerDataPacket(
7386 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437387 mock_quic_data2.AddWrite(
7388 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457389 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7390 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7391
7392 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7393
bnc359ed2a2016-04-29 20:43:457394 SendRequestAndExpectQuicResponse(origin1_);
7395 SendRequestAndExpectQuicResponse(origin2_);
7396
7397 EXPECT_TRUE(AllDataConsumed());
7398}
7399
ckrasicdee37572017-04-06 22:42:277400// crbug.com/705109 - this confirms that matching request with a body
7401// triggers a crash (pre-fix).
7402TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417403 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277404 HostPortPair::FromString("mail.example.org:443"));
7405
7406 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527407 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237408 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437409 mock_quic_data.AddWrite(
7410 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7411 &header_stream_offset));
7412 mock_quic_data.AddWrite(
7413 SYNCHRONOUS,
7414 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337415 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7416 true, true, GetRequestHeaders("GET", "https", "/"),
7417 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527418 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437419 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337420 ASYNC, ConstructServerPushPromisePacket(
7421 1, GetNthClientInitiatedBidirectionalStreamId(0),
7422 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7423 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7424 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577425 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267426 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337427 mock_quic_data.AddWrite(SYNCHRONOUS,
7428 ConstructClientPriorityPacket(
7429 client_packet_number++, false,
7430 GetNthServerInitiatedUnidirectionalStreamId(0),
7431 GetNthClientInitiatedBidirectionalStreamId(0),
7432 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577433 }
Zhongyi Shi32f2fd02018-04-16 18:23:437434 mock_quic_data.AddRead(
7435 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337436 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437437 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577438 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437439 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7440 mock_quic_data.AddRead(
7441 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337442 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7443 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417444 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437445 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337446 ASYNC, ConstructServerDataPacket(
7447 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417448 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577449 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437450 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417451
7452 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437453 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337454 ASYNC, ConstructServerDataPacket(
7455 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417456 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277457
7458 // Because the matching request has a body, we will see the push
7459 // stream get cancelled, and the matching request go out on the
7460 // wire.
Fan Yang32c5a112018-12-10 20:06:337461 mock_quic_data.AddWrite(SYNCHRONOUS,
7462 ConstructClientAckAndRstPacket(
7463 client_packet_number++,
7464 GetNthServerInitiatedUnidirectionalStreamId(0),
7465 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277466 const char kBody[] = "1";
Renjief49758b2019-01-11 23:32:417467 quic::QuicString header3 = ConstructDataHeader(1);
7468 if (version_ != quic::QUIC_VERSION_99) {
7469 mock_quic_data.AddWrite(
7470 SYNCHRONOUS,
7471 ConstructClientRequestHeadersAndDataFramesPacket(
7472 client_packet_number++,
7473 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7474 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7475 GetNthServerInitiatedUnidirectionalStreamId(0),
7476 &header_stream_offset, nullptr, {kBody}));
7477 } else {
7478 mock_quic_data.AddWrite(
7479 SYNCHRONOUS,
7480 ConstructClientRequestHeadersAndDataFramesPacket(
7481 client_packet_number++,
7482 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7483 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7484 GetNthServerInitiatedUnidirectionalStreamId(0),
7485 &header_stream_offset, nullptr, {header3, kBody}));
7486 }
ckrasicdee37572017-04-06 22:42:277487
7488 // We see the same response as for the earlier pushed and cancelled
7489 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437490 mock_quic_data.AddRead(
7491 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337492 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437493 GetResponseHeaders("200 OK"), &server_header_offset));
7494 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337495 ASYNC, ConstructServerDataPacket(
7496 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417497 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277498
Yixin Wangb470bc882018-02-15 18:43:577499 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437500 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277501 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7502 mock_quic_data.AddRead(ASYNC, 0); // EOF
7503 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7504
7505 // The non-alternate protocol job needs to hang in order to guarantee that
7506 // the alternate-protocol job will "win".
7507 AddHangingNonAlternateProtocolSocketData();
7508
7509 CreateSession();
7510
7511 // PUSH_PROMISE handling in the http layer gets exercised here.
7512 SendRequestAndExpectQuicResponse("hello!");
7513
7514 request_.url = GURL("https://mail.example.org/pushed.jpg");
7515 ChunkedUploadDataStream upload_data(0);
7516 upload_data.AppendData("1", 1, true);
7517 request_.upload_data_stream = &upload_data;
7518 SendRequestAndExpectQuicResponse("and hello!");
7519}
7520
Bence Béky7538a952018-02-01 16:59:527521// Regression test for https://crbug.com/797825: If pushed headers describe a
7522// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7523// not be called (otherwise a DCHECK fails).
7524TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137525 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527526 pushed_request_headers[":authority"] = "";
7527 pushed_request_headers[":method"] = "GET";
7528 pushed_request_headers[":path"] = "/";
7529 pushed_request_headers[":scheme"] = "nosuchscheme";
7530
7531 session_params_.origins_to_force_quic_on.insert(
7532 HostPortPair::FromString("mail.example.org:443"));
7533
7534 MockQuicData mock_quic_data;
7535
Ryan Hamilton8d9ee76e2018-05-29 23:52:527536 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527537 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437538 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7539 mock_quic_data.AddWrite(
7540 SYNCHRONOUS,
7541 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337542 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437543 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527544
Ryan Hamilton8d9ee76e2018-05-29 23:52:527545 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337546 mock_quic_data.AddRead(
7547 ASYNC, ConstructServerPushPromisePacket(
7548 1, GetNthClientInitiatedBidirectionalStreamId(0),
7549 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7550 std::move(pushed_request_headers), &server_header_offset,
7551 &server_maker_));
7552 mock_quic_data.AddWrite(SYNCHRONOUS,
7553 ConstructClientRstPacket(
7554 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7555 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527556
Zhongyi Shi32f2fd02018-04-16 18:23:437557 mock_quic_data.AddRead(
7558 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337559 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437560 GetResponseHeaders("200 OK"), &server_header_offset));
7561 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527562
Zhongyi Shi32f2fd02018-04-16 18:23:437563 mock_quic_data.AddRead(
7564 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337565 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7566 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417567 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437568 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337569 ASYNC, ConstructServerDataPacket(
7570 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417571 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437572 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527573
7574 mock_quic_data.AddRead(ASYNC, 0);
7575 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7576
7577 // The non-alternate protocol job needs to hang in order to guarantee that
7578 // the alternate-protocol job will "win".
7579 AddHangingNonAlternateProtocolSocketData();
7580
7581 CreateSession();
7582
7583 // PUSH_PROMISE handling in the http layer gets exercised here.
7584 SendRequestAndExpectQuicResponse("hello!");
7585
7586 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7587 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7588}
7589
Yixin Wang46a273ec302018-01-23 17:59:567590// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147591TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567592 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147593 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567594 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497595 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567596
7597 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527598 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567599 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357600 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337601 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357602 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7603 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7604 false, ConnectRequestHeaders("mail.example.org:443"),
7605 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337606 mock_quic_data.AddRead(
7607 ASYNC, ConstructServerResponseHeadersPacket(
7608 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7609 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567610
7611 const char get_request[] =
7612 "GET / HTTP/1.1\r\n"
7613 "Host: mail.example.org\r\n"
7614 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417615 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7616 if (version_ != quic::QUIC_VERSION_99) {
7617 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357618 SYNCHRONOUS,
7619 ConstructClientAckAndDataPacket(
7620 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7621 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417622 } else {
7623 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417624 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357625 ConstructClientAckAndMultipleDataFramesPacket(
7626 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7627 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417628 }
7629
Yixin Wang46a273ec302018-01-23 17:59:567630 const char get_response[] =
7631 "HTTP/1.1 200 OK\r\n"
7632 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417633 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437634 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337635 ASYNC, ConstructServerDataPacket(
7636 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417637 0, header2 + quic::QuicString(get_response)));
7638 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337639 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417640 SYNCHRONOUS, ConstructServerDataPacket(
7641 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7642 false, strlen(get_response) + header2.length(),
7643 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357644 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567645 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7646
7647 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417648 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357649 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7650 quic::QUIC_STREAM_CANCELLED,
7651 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567652
7653 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7654
7655 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7656
7657 CreateSession();
7658
7659 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097660 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7662 HeadersHandler headers_handler;
7663 trans.SetBeforeHeadersSentCallback(
7664 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7665 base::Unretained(&headers_handler)));
7666 RunTransaction(&trans);
7667 CheckWasHttpResponse(&trans);
7668 CheckResponsePort(&trans, 70);
7669 CheckResponseData(&trans, "0123456789");
7670 EXPECT_TRUE(headers_handler.was_proxied());
7671 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7672
7673 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7674 // proxy socket to disconnect.
7675 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7676
7677 base::RunLoop().RunUntilIdle();
7678 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7679 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7680}
7681
7682// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147683TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567684 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147685 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567686 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497687 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567688
7689 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527690 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567691 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357692 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337693 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357694 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7695 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7696 false, ConnectRequestHeaders("mail.example.org:443"),
7697 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337698 mock_quic_data.AddRead(
7699 ASYNC, ConstructServerResponseHeadersPacket(
7700 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7701 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567702
7703 SpdyTestUtil spdy_util;
7704
Ryan Hamilton0239aac2018-05-19 00:03:137705 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567706 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417707 quic::QuicString header = ConstructDataHeader(get_frame.size());
7708 if (version_ != quic::QUIC_VERSION_99) {
7709 mock_quic_data.AddWrite(
7710 SYNCHRONOUS,
7711 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357712 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7713 false, 0,
Renjief49758b2019-01-11 23:32:417714 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7715 } else {
7716 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417717 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357718 ConstructClientAckAndMultipleDataFramesPacket(
7719 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7720 false, 0,
7721 {header, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417722 }
Ryan Hamilton0239aac2018-05-19 00:03:137723 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567724 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417725 quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437726 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337727 ASYNC,
7728 ConstructServerDataPacket(
7729 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Renjief49758b2019-01-11 23:32:417730 header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567731
Ryan Hamilton0239aac2018-05-19 00:03:137732 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197733 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Renjief49758b2019-01-11 23:32:417734 quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437735 mock_quic_data.AddRead(
7736 SYNCHRONOUS,
7737 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337738 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417739 resp_frame.size() + header2.length(),
7740 header3 + quic::QuicString(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357741 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567742 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7743
7744 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437745 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357746 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7747 quic::QUIC_STREAM_CANCELLED,
7748 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567749
7750 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7751
7752 SSLSocketDataProvider ssl_data(ASYNC, OK);
7753 ssl_data.next_proto = kProtoHTTP2;
7754 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7755
7756 CreateSession();
7757
7758 request_.url = GURL("https://mail.example.org/");
7759 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7760 HeadersHandler headers_handler;
7761 trans.SetBeforeHeadersSentCallback(
7762 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7763 base::Unretained(&headers_handler)));
7764 RunTransaction(&trans);
7765 CheckWasSpdyResponse(&trans);
7766 CheckResponsePort(&trans, 70);
7767 CheckResponseData(&trans, "0123456789");
7768 EXPECT_TRUE(headers_handler.was_proxied());
7769 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7770
Wez0e717112018-06-18 23:09:227771 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7772 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567773 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7774
7775 base::RunLoop().RunUntilIdle();
7776 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7777 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7778}
7779
7780// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7781// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147782TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567783 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147784 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567785 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497786 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567787
7788 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527789 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417790 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567791 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417792 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7793 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337794 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417795 SYNCHRONOUS,
7796 ConstructClientRequestHeadersPacket(
7797 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7798 true, false, ConnectRequestHeaders("mail.example.org:443"),
7799 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337800 mock_quic_data.AddRead(
7801 ASYNC, ConstructServerResponseHeadersPacket(
7802 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7803 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567804
Ryan Hamilton8d9ee76e2018-05-29 23:52:527805 quic::QuicStreamOffset client_data_offset = 0;
7806 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567807 const char get_request_1[] =
7808 "GET / HTTP/1.1\r\n"
7809 "Host: mail.example.org\r\n"
7810 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417811 quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
7812 if (version_ != quic::QUIC_VERSION_99) {
7813 mock_quic_data.AddWrite(
7814 SYNCHRONOUS,
7815 ConstructClientAckAndDataPacket(
7816 write_packet_index++, false,
7817 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7818 client_data_offset, quic::QuicStringPiece(get_request_1)));
7819 } else {
7820 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417821 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357822 ConstructClientAckAndMultipleDataFramesPacket(
7823 write_packet_index++, false,
7824 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7825 client_data_offset, {header, quic::QuicString(get_request_1)}));
Renjief49758b2019-01-11 23:32:417826 }
7827
7828 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567829
7830 const char get_response_1[] =
7831 "HTTP/1.1 200 OK\r\n"
7832 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417833 quic::QuicString header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437834 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417835 ASYNC,
7836 ConstructServerDataPacket(
7837 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7838 server_data_offset, header2 + quic::QuicString(get_response_1)));
7839 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567840
Renjief49758b2019-01-11 23:32:417841 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337842 mock_quic_data.AddRead(
7843 SYNCHRONOUS,
7844 ConstructServerDataPacket(
7845 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417846 server_data_offset, header3 + quic::QuicString("0123456789")));
7847 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567848
Renjief49758b2019-01-11 23:32:417849 mock_quic_data.AddWrite(
7850 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567851
7852 const char get_request_2[] =
7853 "GET /2 HTTP/1.1\r\n"
7854 "Host: mail.example.org\r\n"
7855 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417856 quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
7857 if (version_ == quic::QUIC_VERSION_99) {
7858 mock_quic_data.AddWrite(
7859 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357860 ConstructClientMultipleDataFramesPacket(
7861 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7862 false, false, client_data_offset,
7863 {header4, quic::QuicString(get_request_2)}));
7864 client_data_offset += header4.length() + strlen(get_request_2);
7865 } else {
7866 mock_quic_data.AddWrite(
7867 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417868 ConstructClientDataPacket(write_packet_index++,
7869 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357870 false, false, client_data_offset,
7871 quic::QuicStringPiece(get_request_2)));
7872 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417873 }
Yixin Wang46a273ec302018-01-23 17:59:567874
7875 const char get_response_2[] =
7876 "HTTP/1.1 200 OK\r\n"
7877 "Content-Length: 7\r\n\r\n";
Renjief49758b2019-01-11 23:32:417878 quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437879 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417880 ASYNC,
7881 ConstructServerDataPacket(
7882 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7883 server_data_offset, header5 + quic::QuicString(get_response_2)));
7884 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567885
Renjief49758b2019-01-11 23:32:417886 quic::QuicString header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527887 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337888 SYNCHRONOUS,
7889 ConstructServerDataPacket(
7890 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417891 server_data_offset, header6 + quic::QuicString("0123456")));
7892 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567893
Renjief49758b2019-01-11 23:32:417894 mock_quic_data.AddWrite(
7895 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567896 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7897
Renjief49758b2019-01-11 23:32:417898 mock_quic_data.AddWrite(
7899 SYNCHRONOUS,
7900 ConstructClientRstPacket(
7901 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7902 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567903
7904 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7905
7906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7907
7908 CreateSession();
7909
7910 request_.url = GURL("https://mail.example.org/");
7911 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7912 HeadersHandler headers_handler_1;
7913 trans_1.SetBeforeHeadersSentCallback(
7914 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7915 base::Unretained(&headers_handler_1)));
7916 RunTransaction(&trans_1);
7917 CheckWasHttpResponse(&trans_1);
7918 CheckResponsePort(&trans_1, 70);
7919 CheckResponseData(&trans_1, "0123456789");
7920 EXPECT_TRUE(headers_handler_1.was_proxied());
7921 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7922
7923 request_.url = GURL("https://mail.example.org/2");
7924 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7925 HeadersHandler headers_handler_2;
7926 trans_2.SetBeforeHeadersSentCallback(
7927 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7928 base::Unretained(&headers_handler_2)));
7929 RunTransaction(&trans_2);
7930 CheckWasHttpResponse(&trans_2);
7931 CheckResponsePort(&trans_2, 70);
7932 CheckResponseData(&trans_2, "0123456");
7933 EXPECT_TRUE(headers_handler_2.was_proxied());
7934 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7935
7936 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7937 // proxy socket to disconnect.
7938 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7939
7940 base::RunLoop().RunUntilIdle();
7941 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7942 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7943}
7944
7945// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7946// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7947// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147948TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567949 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147950 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567951 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497952 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567953
7954 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527955 quic::QuicStreamOffset client_header_stream_offset = 0;
7956 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357957 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7958 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567959
7960 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337961 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357962 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7963 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7964 false, ConnectRequestHeaders("mail.example.org:443"),
7965 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437966 mock_quic_data.AddRead(
7967 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337968 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437969 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567970
7971 // GET request, response, and data over QUIC tunnel for first request
7972 const char get_request[] =
7973 "GET / HTTP/1.1\r\n"
7974 "Host: mail.example.org\r\n"
7975 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417976 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7977 if (version_ != quic::QUIC_VERSION_99) {
7978 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357979 SYNCHRONOUS,
7980 ConstructClientAckAndDataPacket(
7981 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7982 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417983 } else {
7984 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417985 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357986 ConstructClientAckAndMultipleDataFramesPacket(
7987 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7988 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417989 }
7990
Yixin Wang46a273ec302018-01-23 17:59:567991 const char get_response[] =
7992 "HTTP/1.1 200 OK\r\n"
7993 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417994 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567995 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337996 ASYNC, ConstructServerDataPacket(
7997 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417998 0, header2 + quic::QuicString(get_response)));
7999 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338000 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418001 SYNCHRONOUS, ConstructServerDataPacket(
8002 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
8003 false, strlen(get_response) + header2.length(),
8004 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358005 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:568006
8007 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:438008 mock_quic_data.AddWrite(
8009 SYNCHRONOUS,
8010 ConstructClientRequestHeadersPacket(
Renjied172e812019-01-16 05:12:358011 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8012 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:338013 GetNthClientInitiatedBidirectionalStreamId(0),
8014 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438015 mock_quic_data.AddRead(
8016 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338017 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438018 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568019
8020 // GET request, response, and data over QUIC tunnel for second request
8021 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:138022 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:568023 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:418024 quic::QuicString header4 = ConstructDataHeader(get_frame.size());
8025 if (version_ != quic::QUIC_VERSION_99) {
8026 mock_quic_data.AddWrite(
8027 SYNCHRONOUS,
8028 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:358029 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
8030 false, 0,
Renjief49758b2019-01-11 23:32:418031 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
8032 } else {
8033 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418034 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358035 ConstructClientAckAndMultipleDataFramesPacket(
8036 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
8037 false, 0,
8038 {header4, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:418039 }
Yixin Wang46a273ec302018-01-23 17:59:568040
Ryan Hamilton0239aac2018-05-19 00:03:138041 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:568042 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:418043 quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438044 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338045 ASYNC,
8046 ConstructServerDataPacket(
8047 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Renjief49758b2019-01-11 23:32:418048 header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568049
Ryan Hamilton0239aac2018-05-19 00:03:138050 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:198051 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Renjief49758b2019-01-11 23:32:418052 quic::QuicString header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:438053 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418054 ASYNC,
8055 ConstructServerDataPacket(
8056 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8057 resp_frame.size() + header5.length(),
8058 header6 + quic::QuicString(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:568059
Renjied172e812019-01-16 05:12:358060 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:568061 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8062
8063 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418064 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358065 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
8066 quic::QUIC_STREAM_CANCELLED,
8067 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568068 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438069 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358070 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
8071 quic::QUIC_STREAM_CANCELLED,
8072 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:568073
8074 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8075
8076 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8077
8078 SSLSocketDataProvider ssl_data(ASYNC, OK);
8079 ssl_data.next_proto = kProtoHTTP2;
8080 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8081
8082 CreateSession();
8083
8084 request_.url = GURL("https://mail.example.org/");
8085 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
8086 HeadersHandler headers_handler_1;
8087 trans_1.SetBeforeHeadersSentCallback(
8088 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8089 base::Unretained(&headers_handler_1)));
8090 RunTransaction(&trans_1);
8091 CheckWasHttpResponse(&trans_1);
8092 CheckResponsePort(&trans_1, 70);
8093 CheckResponseData(&trans_1, "0123456789");
8094 EXPECT_TRUE(headers_handler_1.was_proxied());
8095 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
8096
8097 request_.url = GURL("https://different.example.org/");
8098 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
8099 HeadersHandler headers_handler_2;
8100 trans_2.SetBeforeHeadersSentCallback(
8101 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8102 base::Unretained(&headers_handler_2)));
8103 RunTransaction(&trans_2);
8104 CheckWasSpdyResponse(&trans_2);
8105 CheckResponsePort(&trans_2, 70);
8106 CheckResponseData(&trans_2, "0123456");
8107 EXPECT_TRUE(headers_handler_2.was_proxied());
8108 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
8109
8110 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8111 // proxy socket to disconnect.
8112 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8113
8114 base::RunLoop().RunUntilIdle();
8115 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8116 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8117}
8118
8119// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:148120TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:568121 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148122 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568123 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498124 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568125
8126 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528127 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568128 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438129 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528130 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338131 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8132 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8133 false, ConnectRequestHeaders("mail.example.org:443"),
8134 &header_stream_offset));
8135 mock_quic_data.AddRead(
8136 ASYNC, ConstructServerResponseHeadersPacket(
8137 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8138 GetResponseHeaders("500")));
8139 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8140 mock_quic_data.AddWrite(SYNCHRONOUS,
8141 ConstructClientAckAndRstPacket(
8142 3, GetNthClientInitiatedBidirectionalStreamId(0),
8143 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568144
8145 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8146
8147 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
8148
8149 CreateSession();
8150
8151 request_.url = GURL("https://mail.example.org/");
8152 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8153 HeadersHandler headers_handler;
8154 trans.SetBeforeHeadersSentCallback(
8155 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8156 base::Unretained(&headers_handler)));
8157 TestCompletionCallback callback;
8158 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8159 EXPECT_EQ(ERR_IO_PENDING, rv);
8160 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
8161 EXPECT_EQ(false, headers_handler.was_proxied());
8162
8163 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8164 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8165}
8166
8167// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:148168TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:568169 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148170 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568171 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498172 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568173
8174 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528175 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568176 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438177 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338178 mock_quic_data.AddWrite(
8179 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8180 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8181 false, ConnectRequestHeaders("mail.example.org:443"),
8182 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568183 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8184
8185 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8186
8187 CreateSession();
8188
8189 request_.url = GURL("https://mail.example.org/");
8190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8191 HeadersHandler headers_handler;
8192 trans.SetBeforeHeadersSentCallback(
8193 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8194 base::Unretained(&headers_handler)));
8195 TestCompletionCallback callback;
8196 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8197 EXPECT_EQ(ERR_IO_PENDING, rv);
8198 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8199
8200 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8201 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8202}
8203
8204// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8205// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148206TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568207 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148208 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568209 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498210 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568211
8212 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528213 quic::QuicStreamOffset client_header_stream_offset = 0;
8214 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358215 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8216 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338217 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358218 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8219 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8220 false, ConnectRequestHeaders("mail.example.org:443"),
8221 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438222 mock_quic_data.AddRead(
8223 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338224 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438225 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358226 mock_quic_data.AddWrite(SYNCHRONOUS,
8227 ConstructClientAckAndRstPacket(
8228 3, GetNthClientInitiatedBidirectionalStreamId(0),
8229 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568230
Zhongyi Shi32f2fd02018-04-16 18:23:438231 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358232 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8233 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8234 false, ConnectRequestHeaders("mail.example.org:443"),
8235 GetNthClientInitiatedBidirectionalStreamId(0),
8236 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438237 mock_quic_data.AddRead(
8238 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338239 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438240 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568241
8242 const char get_request[] =
8243 "GET / HTTP/1.1\r\n"
8244 "Host: mail.example.org\r\n"
8245 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:418246 quic::QuicString header = ConstructDataHeader(strlen(get_request));
8247 if (version_ != quic::QUIC_VERSION_99) {
8248 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358249 SYNCHRONOUS,
8250 ConstructClientAckAndDataPacket(
8251 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8252 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418253 } else {
8254 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418255 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358256 ConstructClientAckAndMultipleDataFramesPacket(
8257 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8258 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:418259 }
Yixin Wang46a273ec302018-01-23 17:59:568260 const char get_response[] =
8261 "HTTP/1.1 200 OK\r\n"
8262 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:418263 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438264 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338265 ASYNC, ConstructServerDataPacket(
8266 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Renjief49758b2019-01-11 23:32:418267 0, header2 + quic::QuicString(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528268
Renjief49758b2019-01-11 23:32:418269 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338270 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418271 SYNCHRONOUS, ConstructServerDataPacket(
8272 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8273 false, strlen(get_response) + header2.length(),
8274 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358275 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568276 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8277
8278 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418279 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358280 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8281 quic::QUIC_STREAM_CANCELLED,
8282 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568283
8284 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8285
8286 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8287 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8288
8289 SSLSocketDataProvider ssl_data(ASYNC, OK);
8290 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8291
8292 CreateSession();
8293
8294 request_.url = GURL("https://mail.example.org/");
8295 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8296 HeadersHandler headers_handler;
8297 trans.SetBeforeHeadersSentCallback(
8298 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8299 base::Unretained(&headers_handler)));
8300 TestCompletionCallback callback;
8301 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8302 EXPECT_EQ(ERR_IO_PENDING, rv);
8303 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8304
8305 rv = trans.RestartIgnoringLastError(callback.callback());
8306 EXPECT_EQ(ERR_IO_PENDING, rv);
8307 EXPECT_EQ(OK, callback.WaitForResult());
8308
8309 CheckWasHttpResponse(&trans);
8310 CheckResponsePort(&trans, 70);
8311 CheckResponseData(&trans, "0123456789");
8312 EXPECT_EQ(true, headers_handler.was_proxied());
8313 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8314
8315 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8316 // proxy socket to disconnect.
8317 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8318
8319 base::RunLoop().RunUntilIdle();
8320 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8321 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8322}
8323
8324// Checks if a request's specified "user-agent" header shows up correctly in the
8325// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148326TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Yixin Wang46a273ec302018-01-23 17:59:568327 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148328 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568329 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498330 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568331
8332 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528333 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568334 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438335 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568336
Ryan Hamilton0239aac2018-05-19 00:03:138337 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568338 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338339 mock_quic_data.AddWrite(
8340 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8341 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8342 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568343 // Return an error, so the transaction stops here (this test isn't interested
8344 // in the rest).
8345 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8346
8347 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8348
8349 CreateSession();
8350
8351 request_.url = GURL("https://mail.example.org/");
8352 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8353 "Chromium Ultra Awesome X Edition");
8354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8355 HeadersHandler headers_handler;
8356 trans.SetBeforeHeadersSentCallback(
8357 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8358 base::Unretained(&headers_handler)));
8359 TestCompletionCallback callback;
8360 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8361 EXPECT_EQ(ERR_IO_PENDING, rv);
8362 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8363
8364 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8365 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8366}
8367
Yixin Wang00fc44c2018-01-23 21:12:208368// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8369// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148370TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208371 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148372 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208373 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498374 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208375
8376 const RequestPriority request_priority = MEDIUM;
8377
8378 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528379 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208380 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438381 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8382 mock_quic_data.AddWrite(
8383 SYNCHRONOUS,
8384 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338385 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8386 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438387 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208388 // Return an error, so the transaction stops here (this test isn't interested
8389 // in the rest).
8390 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8391
8392 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8393
8394 CreateSession();
8395
8396 request_.url = GURL("https://mail.example.org/");
8397 HttpNetworkTransaction trans(request_priority, session_.get());
8398 TestCompletionCallback callback;
8399 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8400 EXPECT_EQ(ERR_IO_PENDING, rv);
8401 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8402
8403 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8404 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8405}
8406
Yixin Wang46a273ec302018-01-23 17:59:568407// Test the request-challenge-retry sequence for basic auth, over a QUIC
8408// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148409TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568410 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8411 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138412 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568413 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8414
8415 std::unique_ptr<QuicTestPacketMaker> client_maker;
8416 std::unique_ptr<QuicTestPacketMaker> server_maker;
8417
8418 // On the second pass, the body read of the auth challenge is synchronous, so
8419 // IsConnectedAndIdle returns false. The socket should still be drained and
8420 // reused. See http://crbug.com/544255.
8421 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338422 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178423 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8424 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338425 client_headers_include_h2_stream_dependency_));
8426 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178427 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8428 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568429
8430 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148431 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568432 proxy_resolution_service_ =
8433 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498434 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568435
8436 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528437 quic::QuicStreamOffset client_header_stream_offset = 0;
8438 quic::QuicStreamOffset server_header_stream_offset = 0;
8439 quic::QuicStreamOffset client_data_offset = 0;
8440 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568441
Zhongyi Shi32f2fd02018-04-16 18:23:438442 mock_quic_data.AddWrite(SYNCHRONOUS,
8443 client_maker->MakeInitialSettingsPacket(
8444 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568445
8446 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438447 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568448 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338449 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8450 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568451 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8452 &client_header_stream_offset));
8453
Ryan Hamilton0239aac2018-05-19 00:03:138454 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568455 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8456 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8457 headers["content-length"] = "10";
8458 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438459 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338460 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8461 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568462
8463 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438464 mock_quic_data.AddRead(
8465 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338466 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8467 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568468 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438469 mock_quic_data.AddRead(
8470 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338471 2, GetNthClientInitiatedBidirectionalStreamId(0),
8472 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568473 }
8474 server_data_offset += 10;
8475
Zhongyi Shi32f2fd02018-04-16 18:23:438476 mock_quic_data.AddWrite(SYNCHRONOUS,
8477 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568478
8479 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338480 SYNCHRONOUS,
8481 client_maker->MakeRstPacket(
8482 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8483 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:568484
8485 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8486 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8487 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338488 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8489 5, GetNthClientInitiatedBidirectionalStreamId(1),
8490 false, false, default_priority, std::move(headers),
8491 GetNthClientInitiatedBidirectionalStreamId(0),
8492 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568493
8494 // Response to wrong password
8495 headers =
8496 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8497 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8498 headers["content-length"] = "10";
8499 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438500 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338501 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8502 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568503 mock_quic_data.AddRead(SYNCHRONOUS,
8504 ERR_IO_PENDING); // No more data to read
8505
Fan Yang32c5a112018-12-10 20:06:338506 mock_quic_data.AddWrite(
8507 SYNCHRONOUS,
8508 client_maker->MakeAckAndRstPacket(
8509 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8510 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568511
8512 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8513 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8514
8515 CreateSession();
8516
8517 request_.url = GURL("https://mail.example.org/");
8518 // Ensure that proxy authentication is attempted even
8519 // when the no authentication data flag is set.
8520 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8521 {
8522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8523 HeadersHandler headers_handler;
8524 trans.SetBeforeHeadersSentCallback(
8525 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8526 base::Unretained(&headers_handler)));
8527 RunTransaction(&trans);
8528
8529 const HttpResponseInfo* response = trans.GetResponseInfo();
8530 ASSERT_TRUE(response != nullptr);
8531 ASSERT_TRUE(response->headers.get() != nullptr);
8532 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8533 response->headers->GetStatusLine());
8534 EXPECT_TRUE(response->headers->IsKeepAlive());
8535 EXPECT_EQ(407, response->headers->response_code());
8536 EXPECT_EQ(10, response->headers->GetContentLength());
8537 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8538 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8539 ASSERT_TRUE(auth_challenge != nullptr);
8540 EXPECT_TRUE(auth_challenge->is_proxy);
8541 EXPECT_EQ("https://proxy.example.org:70",
8542 auth_challenge->challenger.Serialize());
8543 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8544 EXPECT_EQ("basic", auth_challenge->scheme);
8545
8546 TestCompletionCallback callback;
8547 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8548 callback.callback());
8549 EXPECT_EQ(ERR_IO_PENDING, rv);
8550 EXPECT_EQ(OK, callback.WaitForResult());
8551
8552 response = trans.GetResponseInfo();
8553 ASSERT_TRUE(response != nullptr);
8554 ASSERT_TRUE(response->headers.get() != nullptr);
8555 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8556 response->headers->GetStatusLine());
8557 EXPECT_TRUE(response->headers->IsKeepAlive());
8558 EXPECT_EQ(407, response->headers->response_code());
8559 EXPECT_EQ(10, response->headers->GetContentLength());
8560 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8561 auth_challenge = response->auth_challenge.get();
8562 ASSERT_TRUE(auth_challenge != nullptr);
8563 EXPECT_TRUE(auth_challenge->is_proxy);
8564 EXPECT_EQ("https://proxy.example.org:70",
8565 auth_challenge->challenger.Serialize());
8566 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8567 EXPECT_EQ("basic", auth_challenge->scheme);
8568 }
8569 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8570 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8571 // reused because it's not connected).
8572 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8573 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8574 }
8575}
8576
Yixin Wang385652a2018-02-16 02:37:238577TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8578 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8579 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268580 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238581 !client_headers_include_h2_stream_dependency_) {
8582 return;
8583 }
8584
8585 session_params_.origins_to_force_quic_on.insert(
8586 HostPortPair::FromString("mail.example.org:443"));
8587
Fan Yang32c5a112018-12-10 20:06:338588 const quic::QuicStreamId client_stream_0 =
8589 GetNthClientInitiatedBidirectionalStreamId(0);
8590 const quic::QuicStreamId client_stream_1 =
8591 GetNthClientInitiatedBidirectionalStreamId(1);
8592 const quic::QuicStreamId client_stream_2 =
8593 GetNthClientInitiatedBidirectionalStreamId(2);
8594 const quic::QuicStreamId push_stream_0 =
8595 GetNthServerInitiatedUnidirectionalStreamId(0);
8596 const quic::QuicStreamId push_stream_1 =
8597 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238598
8599 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528600 quic::QuicStreamOffset header_stream_offset = 0;
8601 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238602 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438603 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238604
8605 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438606 mock_quic_data.AddWrite(SYNCHRONOUS,
8607 ConstructClientRequestHeadersPacket(
8608 2, client_stream_0, true, true, HIGHEST,
8609 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8610 &header_stream_offset));
8611 mock_quic_data.AddWrite(SYNCHRONOUS,
8612 ConstructClientRequestHeadersPacket(
8613 3, client_stream_1, true, true, MEDIUM,
8614 GetRequestHeaders("GET", "https", "/1.jpg"),
8615 client_stream_0, &header_stream_offset));
8616 mock_quic_data.AddWrite(SYNCHRONOUS,
8617 ConstructClientRequestHeadersPacket(
8618 4, client_stream_2, true, true, MEDIUM,
8619 GetRequestHeaders("GET", "https", "/2.jpg"),
8620 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238621
8622 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438623 mock_quic_data.AddRead(
8624 ASYNC, ConstructServerResponseHeadersPacket(
8625 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8626 &server_header_offset));
8627 mock_quic_data.AddRead(
8628 ASYNC, ConstructServerResponseHeadersPacket(
8629 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8630 &server_header_offset));
8631 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8632 mock_quic_data.AddRead(
8633 ASYNC, ConstructServerResponseHeadersPacket(
8634 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8635 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238636
8637 // Server sends two push promises associated with |client_stream_0|; client
8638 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8639 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438640 mock_quic_data.AddRead(ASYNC,
8641 ConstructServerPushPromisePacket(
8642 4, client_stream_0, push_stream_0, false,
8643 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8644 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238645 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438646 SYNCHRONOUS,
8647 ConstructClientAckAndPriorityFramesPacket(
8648 6, false, 4, 3, 1,
8649 {{push_stream_0, client_stream_2,
8650 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8651 &header_stream_offset));
8652 mock_quic_data.AddRead(ASYNC,
8653 ConstructServerPushPromisePacket(
8654 5, client_stream_0, push_stream_1, false,
8655 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8656 &server_header_offset, &server_maker_));
8657 mock_quic_data.AddWrite(
8658 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238659 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8660 DEFAULT_PRIORITY, &header_stream_offset));
8661
8662 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438663 mock_quic_data.AddRead(
8664 ASYNC, ConstructServerResponseHeadersPacket(
8665 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8666 &server_header_offset));
8667 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8668 mock_quic_data.AddRead(
8669 ASYNC, ConstructServerResponseHeadersPacket(
8670 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8671 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238672
8673 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8674 // priority updates to match the request's priority. Client sends PRIORITY
8675 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438676 mock_quic_data.AddWrite(
8677 SYNCHRONOUS,
8678 ConstructClientAckAndPriorityFramesPacket(
8679 9, false, 7, 7, 1,
8680 {{push_stream_1, client_stream_2,
8681 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8682 {push_stream_0, client_stream_0,
8683 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8684 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238685
8686 // Server sends data for the three requests and the two push promises.
Renjief49758b2019-01-11 23:32:418687 quic::QuicString header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438688 mock_quic_data.AddRead(
8689 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418690 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438691 mock_quic_data.AddRead(
8692 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418693 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438694 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8695 mock_quic_data.AddRead(
8696 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418697 header + "hello 2!"));
8698 quic::QuicString header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438699 mock_quic_data.AddRead(
8700 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418701 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438702 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8703 mock_quic_data.AddRead(
8704 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418705 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238706
Yixin Wang385652a2018-02-16 02:37:238707 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8708 mock_quic_data.AddRead(ASYNC, 0); // EOF
8709 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8710
8711 // The non-alternate protocol job needs to hang in order to guarantee that
8712 // the alternate-protocol job will "win".
8713 AddHangingNonAlternateProtocolSocketData();
8714
8715 CreateSession();
8716
8717 request_.url = GURL("https://mail.example.org/0.jpg");
8718 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8719 TestCompletionCallback callback_0;
8720 EXPECT_EQ(ERR_IO_PENDING,
8721 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8722 base::RunLoop().RunUntilIdle();
8723
8724 request_.url = GURL("https://mail.example.org/1.jpg");
8725 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8726 TestCompletionCallback callback_1;
8727 EXPECT_EQ(ERR_IO_PENDING,
8728 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8729 base::RunLoop().RunUntilIdle();
8730
8731 request_.url = GURL("https://mail.example.org/2.jpg");
8732 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8733 TestCompletionCallback callback_2;
8734 EXPECT_EQ(ERR_IO_PENDING,
8735 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8736 base::RunLoop().RunUntilIdle();
8737
8738 // Client makes request that matches resource pushed in |pushed_stream_0|.
8739 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8740 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8741 TestCompletionCallback callback_3;
8742 EXPECT_EQ(ERR_IO_PENDING,
8743 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8744 base::RunLoop().RunUntilIdle();
8745
8746 EXPECT_TRUE(callback_0.have_result());
8747 EXPECT_EQ(OK, callback_0.WaitForResult());
8748 EXPECT_TRUE(callback_1.have_result());
8749 EXPECT_EQ(OK, callback_1.WaitForResult());
8750 EXPECT_TRUE(callback_2.have_result());
8751 EXPECT_EQ(OK, callback_2.WaitForResult());
8752
8753 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8754 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8755 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8756 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8757
8758 mock_quic_data.Resume();
8759 base::RunLoop().RunUntilIdle();
8760 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8761 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8762}
8763
[email protected]61a527782013-02-21 03:58:008764} // namespace test
8765} // namespace net