blob: 2791f008548a685e372a7df3509ad4ccf806b5b6 [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,
Frank Kastenholz684ea412019-02-13 18:48:18372 bytes_written,
373 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56374 }
375
Ryan Hamilton8d9ee76e2018-05-29 23:52:52376 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23377 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
378 uint64_t largest_received,
379 uint64_t smallest_received,
380 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58381 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49382 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20383 }
[email protected]61a527782013-02-21 03:58:00384
Ryan Hamilton8d9ee76e2018-05-29 23:52:52385 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58386 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23387 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52388 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23389 uint64_t largest_received,
390 uint64_t smallest_received,
391 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52392 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50393 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58394 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12395 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49396 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12397 }
398
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23400 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12401 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52402 quic::QuicStreamId stream_id,
403 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58404 return server_maker_.MakeRstPacket(num, include_version, stream_id,
405 error_code);
zhongyica364fbb2015-12-12 03:39:12406 }
407
Ryan Hamilton8d9ee76e2018-05-29 23:52:52408 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23409 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52410 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36411 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37412 }
413
Ryan Hamilton8d9ee76e2018-05-29 23:52:52414 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23415 uint64_t packet_number,
416 uint64_t largest_received,
417 uint64_t smallest_received,
418 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37419 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49420 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37421 }
422
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23424 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57425 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 quic::QuicStreamId id,
427 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57428 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57430 return client_maker_.MakePriorityPacket(
431 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23432 ConvertRequestPriorityToQuicPriority(request_priority), offset);
433 }
434
Ryan Hamilton8d9ee76e2018-05-29 23:52:52435 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25436 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23437 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23438 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23439 uint64_t largest_received,
440 uint64_t smallest_received,
441 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25442 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
443 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52444 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25445 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23446 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25447 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57448 }
449
zhongyi32569c62016-01-08 02:54:30450 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13451 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
452 const std::string& scheme,
453 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58454 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30455 }
456
457 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13458 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
459 const std::string& scheme,
460 const std::string& path,
461 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50462 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00463 }
464
Ryan Hamilton0239aac2018-05-19 00:03:13465 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56466 return client_maker_.ConnectRequestHeaders(host_port);
467 }
468
Ryan Hamilton0239aac2018-05-19 00:03:13469 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58470 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00471 }
472
zhongyi32569c62016-01-08 02:54:30473 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13474 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
475 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58476 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30477 }
478
Ryan Hamilton8d9ee76e2018-05-29 23:52:52479 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23480 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52481 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05482 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00483 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52484 quic::QuicStreamOffset offset,
485 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58486 return server_maker_.MakeDataPacket(
487 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00488 }
489
Ryan Hamilton8d9ee76e2018-05-29 23:52:52490 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23491 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36493 bool should_include_version,
494 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52495 quic::QuicStreamOffset offset,
496 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36497 return client_maker_.MakeDataPacket(
498 packet_number, stream_id, should_include_version, fin, offset, data);
499 }
500
Renjied172e812019-01-16 05:12:35501 std::unique_ptr<quic::QuicEncryptedPacket>
502 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23503 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35504 quic::QuicStreamId stream_id,
505 bool should_include_version,
506 bool fin,
507 quic::QuicStreamOffset offset,
508 const std::vector<std::string> data_writes) {
509 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
510 should_include_version,
511 fin, offset, data_writes);
512 }
513
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23515 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56516 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52517 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23518 uint64_t largest_received,
519 uint64_t smallest_received,
520 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56521 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52522 quic::QuicStreamOffset offset,
523 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56524 return client_maker_.MakeAckAndDataPacket(
525 packet_number, include_version, stream_id, largest_received,
526 smallest_received, least_unacked, fin, offset, data);
527 }
528
Renjied172e812019-01-16 05:12:35529 std::unique_ptr<quic::QuicEncryptedPacket>
530 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23531 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35532 bool include_version,
533 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23534 uint64_t largest_received,
535 uint64_t smallest_received,
536 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35537 bool fin,
538 quic::QuicStreamOffset offset,
539 const std::vector<std::string> data_writes) {
540 return client_maker_.MakeAckAndMultipleDataFramesPacket(
541 packet_number, include_version, stream_id, largest_received,
542 smallest_received, least_unacked, fin, offset, data_writes);
543 }
544
Ryan Hamilton8d9ee76e2018-05-29 23:52:52545 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23546 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36548 bool should_include_version,
549 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 quic::QuicStreamOffset* offset,
551 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36552 return client_maker_.MakeForceHolDataPacket(
553 packet_number, stream_id, should_include_version, fin, offset, data);
554 }
555
Ryan Hamilton8d9ee76e2018-05-29 23:52:52556 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23557 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52558 quic::QuicStreamId stream_id,
559 bool should_include_version,
560 bool fin,
561 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56562 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
563 should_include_version, fin,
564 std::move(headers), nullptr);
565 }
566
Ryan Hamilton8d9ee76e2018-05-29 23:52:52567 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23568 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52569 quic::QuicStreamId stream_id,
570 bool should_include_version,
571 bool fin,
572 spdy::SpdyHeaderBlock headers,
573 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48574 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
575 should_include_version, fin,
576 std::move(headers), 0, offset);
577 }
578
Ryan Hamilton8d9ee76e2018-05-29 23:52:52579 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23580 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52581 quic::QuicStreamId stream_id,
582 bool should_include_version,
583 bool fin,
584 spdy::SpdyHeaderBlock headers,
585 quic::QuicStreamId parent_stream_id,
586 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56587 return ConstructClientRequestHeadersPacket(
588 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48589 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30590 }
591
Ryan Hamilton8d9ee76e2018-05-29 23:52:52592 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23593 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52594 quic::QuicStreamId stream_id,
595 bool should_include_version,
596 bool fin,
597 RequestPriority request_priority,
598 spdy::SpdyHeaderBlock headers,
599 quic::QuicStreamId parent_stream_id,
600 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13601 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56602 ConvertRequestPriorityToQuicPriority(request_priority);
603 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
604 packet_number, stream_id, should_include_version, fin, priority,
605 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00606 }
607
Ryan Hamilton8d9ee76e2018-05-29 23:52:52608 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25609 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23610 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52611 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25612 bool should_include_version,
613 bool fin,
614 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13615 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52616 quic::QuicStreamId parent_stream_id,
617 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25618 size_t* spdy_headers_frame_length,
619 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13620 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25621 ConvertRequestPriorityToQuicPriority(request_priority);
622 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
623 packet_number, stream_id, should_include_version, fin, priority,
624 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
625 data_writes);
626 }
627
Ryan Hamilton8d9ee76e2018-05-29 23:52:52628 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23629 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52630 quic::QuicStreamId stream_id,
631 bool should_include_version,
632 bool fin,
633 const std::vector<std::string>& data,
634 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27635 return client_maker_.MakeMultipleDataFramesPacket(
636 packet_number, stream_id, should_include_version, fin, offset, data);
637 }
638
Ryan Hamilton8d9ee76e2018-05-29 23:52:52639 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23640 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52641 quic::QuicStreamId stream_id,
642 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13643 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13644 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52645 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13646 QuicTestPacketMaker* maker) {
647 return maker->MakePushPromisePacket(
648 packet_number, stream_id, promised_stream_id, should_include_version,
649 false, std::move(headers), nullptr, offset);
650 }
651
Ryan Hamilton8d9ee76e2018-05-29 23:52:52652 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23653 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52654 quic::QuicStreamId stream_id,
655 bool should_include_version,
656 bool fin,
657 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27658 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
659 should_include_version, fin,
660 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30661 }
662
Ryan Hamilton8d9ee76e2018-05-29 23:52:52663 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23664 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52665 quic::QuicStreamId stream_id,
666 bool should_include_version,
667 bool fin,
668 spdy::SpdyHeaderBlock headers,
669 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58670 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25671 packet_number, stream_id, should_include_version, fin,
672 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30673 }
674
Renjief49758b2019-01-11 23:32:41675 quic::QuicString ConstructDataHeader(size_t body_len) {
676 if (version_ != quic::QUIC_VERSION_99) {
677 return "";
678 }
679 quic::HttpEncoder encoder;
680 std::unique_ptr<char[]> buffer;
681 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
682 return quic::QuicString(buffer.get(), header_length);
683 }
684
Ryan Hamilton8d9ee76e2018-05-29 23:52:52685 void CreateSession(
686 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41687 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21688 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05689 session_params_.quic_headers_include_h2_stream_dependency =
690 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00691
mmenke6ddfbea2017-05-31 21:48:41692 session_context_.quic_clock = &clock_;
693 session_context_.quic_random = &random_generator_;
694 session_context_.client_socket_factory = &socket_factory_;
695 session_context_.quic_crypto_client_stream_factory =
696 &crypto_client_stream_factory_;
697 session_context_.host_resolver = &host_resolver_;
698 session_context_.cert_verifier = &cert_verifier_;
699 session_context_.transport_security_state = &transport_security_state_;
700 session_context_.cert_transparency_verifier =
701 cert_transparency_verifier_.get();
702 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
703 session_context_.socket_performance_watcher_factory =
704 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59705 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41706 session_context_.ssl_config_service = ssl_config_service_.get();
707 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
708 session_context_.http_server_properties = &http_server_properties_;
709 session_context_.net_log = net_log_.bound().net_log();
710
711 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12712 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56713 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
714 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00715 }
716
zhongyi86838d52017-06-30 01:19:44717 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21718
bnc691fda62016-08-12 00:43:16719 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19720 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42721 ASSERT_TRUE(response != nullptr);
722 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19723 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
724 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52725 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44726 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19727 response->connection_info);
728 }
729
bnc691fda62016-08-12 00:43:16730 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41731 const HttpResponseInfo* response = trans->GetResponseInfo();
732 ASSERT_TRUE(response != nullptr);
733 EXPECT_EQ(port, response->socket_address.port());
734 }
735
bnc691fda62016-08-12 00:43:16736 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19737 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42738 ASSERT_TRUE(response != nullptr);
739 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
741 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52742 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52743 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19744 response->connection_info);
745 }
746
Yixin Wang46a273ec302018-01-23 17:59:56747 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
748 const HttpResponseInfo* response = trans->GetResponseInfo();
749 ASSERT_TRUE(response != nullptr);
750 ASSERT_TRUE(response->headers.get() != nullptr);
751 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
752 EXPECT_TRUE(response->was_fetched_via_spdy);
753 EXPECT_TRUE(response->was_alpn_negotiated);
754 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
755 response->connection_info);
756 }
757
bnc691fda62016-08-12 00:43:16758 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19759 const std::string& expected) {
760 std::string response_data;
bnc691fda62016-08-12 00:43:16761 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19762 EXPECT_EQ(expected, response_data);
763 }
764
bnc691fda62016-08-12 00:43:16765 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19766 TestCompletionCallback callback;
767 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
769 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19770 }
771
772 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
774 RunTransaction(&trans);
775 CheckWasHttpResponse(&trans);
776 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19777 }
778
tbansalc3308d72016-08-27 10:25:04779 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
780 bool used_proxy,
781 uint16_t port) {
782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
783 HeadersHandler headers_handler;
784 trans.SetBeforeHeadersSentCallback(
785 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
786 base::Unretained(&headers_handler)));
787 RunTransaction(&trans);
788 CheckWasHttpResponse(&trans);
789 CheckResponsePort(&trans, port);
790 CheckResponseData(&trans, expected);
791 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47792 if (used_proxy) {
793 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
794 } else {
795 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
796 }
tbansalc3308d72016-08-27 10:25:04797 }
798
[email protected]aa9b14d2013-05-10 23:45:19799 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56800 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12801 }
802
bnc62a44f022015-04-02 15:59:41803 void SendRequestAndExpectQuicResponseFromProxyOnPort(
804 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46805 uint16_t port) {
bnc62a44f022015-04-02 15:59:41806 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19807 }
808
809 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27810 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19811 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46812 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21813 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12814 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21815 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44816 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19817 }
818
rchbe69cb902016-02-11 01:10:48819 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27820 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48821 const HostPortPair& alternative) {
822 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46823 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21824 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48825 alternative.port());
826 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21827 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44828 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48829 }
830
[email protected]aa9b14d2013-05-10 23:45:19831 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46832 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34833 const AlternativeServiceInfoVector alternative_service_info_vector =
834 http_server_properties_.GetAlternativeServiceInfos(server);
835 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07836 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54837 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19838 }
839
[email protected]4d590c9c2014-05-02 05:14:33840 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46841 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34842 const AlternativeServiceInfoVector alternative_service_info_vector =
843 http_server_properties_.GetAlternativeServiceInfos(server);
844 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54845 EXPECT_EQ(
846 kProtoQUIC,
847 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23848 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54849 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33850 }
851
[email protected]aa9b14d2013-05-10 23:45:19852 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42853 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30854 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30855 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30856 hanging_data->set_connect_data(hanging_connect);
857 hanging_data_.push_back(std::move(hanging_data));
858 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56859 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19860 }
861
Zhongyi Shia6b68d112018-09-24 07:49:03862 void SetUpTestForRetryConnectionOnAlternateNetwork() {
863 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
864 session_params_.quic_migrate_sessions_early_v2 = true;
865 session_params_.quic_retry_on_alternate_network_before_handshake = true;
866 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
867 MockNetworkChangeNotifier* mock_ncn =
868 scoped_mock_change_notifier_->mock_network_change_notifier();
869 mock_ncn->ForceNetworkHandlesSupported();
870 mock_ncn->SetConnectedNetworksList(
871 {kDefaultNetworkForTests, kNewNetworkForTests});
872 }
873
tbansalc3308d72016-08-27 10:25:04874 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
875 // alternative proxy. Verifies that if the alternative proxy job returns
876 // |error_code|, the request is fetched successfully by the main job.
877 void TestAlternativeProxy(int error_code) {
878 // Use a non-cryptographic scheme for the request URL since this request
879 // will be fetched via proxy with QUIC as the alternative service.
880 request_.url = GURL("http://example.org/");
881 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27882 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04883 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27884 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04885 };
886
Ryan Sleevib8d7ea02018-05-07 20:01:01887 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04888 socket_factory_.AddSocketDataProvider(&quic_data);
889
890 // Main job succeeds and the alternative job fails.
891 // Add data for two requests that will be read by the main job.
892 MockRead http_reads_1[] = {
893 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
894 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
895 MockRead(ASYNC, OK)};
896
897 MockRead http_reads_2[] = {
898 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
900 MockRead(ASYNC, OK)};
901
Ryan Sleevib8d7ea02018-05-07 20:01:01902 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
903 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04904 socket_factory_.AddSocketDataProvider(&http_data_1);
905 socket_factory_.AddSocketDataProvider(&http_data_2);
906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
907 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
908
909 TestProxyDelegate test_proxy_delegate;
910 // Proxy URL is different from the request URL.
911 test_proxy_delegate.set_alternative_proxy_server(
912 ProxyServer::FromPacString("QUIC myproxy.org:443"));
913
Lily Houghton8c2f97d2018-01-22 05:06:59914 proxy_resolution_service_ =
915 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49916 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52917 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04918
919 CreateSession();
920 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
921
922 // The first request should be fetched via the HTTPS proxy.
923 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
924
Reilly Grant89a7e512018-01-20 01:57:16925 // Since the main job succeeded only the alternative proxy server should be
926 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59927 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16928 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04929
930 // Verify that the second request completes successfully, and the
931 // alternative proxy server job is not started.
932 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
933 }
934
Fan Yang32c5a112018-12-10 20:06:33935 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
936 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36937 }
938
Fan Yang32c5a112018-12-10 20:06:33939 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
940 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36941 }
942
Bence Béky230ac612017-08-30 19:17:08943 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49944 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08945 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49946 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08947 }
948
Ryan Hamilton8d9ee76e2018-05-29 23:52:52949 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05950 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52951 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01952 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52953 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17954 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58955 QuicTestPacketMaker client_maker_;
956 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42957 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00958 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56959 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05960 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43961 MockHostResolver host_resolver_;
962 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11963 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42964 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23965 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38966 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07967 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59968 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42969 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07970 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41971 HttpNetworkSession::Params session_params_;
972 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19973 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51974 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42975 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56976 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03977 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12978
979 private:
980 void SendRequestAndExpectQuicResponseMaybeFromProxy(
981 const std::string& expected,
bnc62a44f022015-04-02 15:59:41982 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46983 uint16_t port) {
bnc691fda62016-08-12 00:43:16984 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09985 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16986 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09987 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
988 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16989 RunTransaction(&trans);
990 CheckWasQuicResponse(&trans);
991 CheckResponsePort(&trans, port);
992 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09993 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47994 if (used_proxy) {
995 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
996 } else {
997 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
998 }
tbansal7cec3812015-02-05 21:25:12999 }
[email protected]61a527782013-02-21 03:58:001000};
1001
Victor Costane635086f2019-01-27 05:20:301002INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231003 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051004 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521005 ::testing::Combine(
1006 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1007 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201008
Ryan Hamiltona64a5bcf2017-11-30 07:35:281009TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481010 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281011 base::HistogramTester histograms;
1012 session_params_.origins_to_force_quic_on.insert(
1013 HostPortPair::FromString("mail.example.org:443"));
1014 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271015 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281016
1017 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521018 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281019 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431020 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281021 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1022 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1023 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1024
1025 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1026
1027 CreateSession();
1028
1029 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1030 TestCompletionCallback callback;
1031 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1033 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1034
1035 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1036 -ERR_INTERNET_DISCONNECTED, 1);
1037 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1038 -ERR_INTERNET_DISCONNECTED, 1);
1039}
1040
1041TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481042 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281043 base::HistogramTester histograms;
1044 session_params_.origins_to_force_quic_on.insert(
1045 HostPortPair::FromString("mail.example.org:443"));
1046 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271047 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281048
1049 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521050 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281051 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431052 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281053 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1054 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1055 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1056
1057 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1058
1059 CreateSession();
1060
1061 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1062 TestCompletionCallback callback;
1063 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1064 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1065 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1066
1067 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1068 -ERR_INTERNET_DISCONNECTED, 1);
1069 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1070 -ERR_INTERNET_DISCONNECTED, 1);
1071}
1072
tbansal180587c2017-02-16 15:13:231073TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411074 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231075 HostPortPair::FromString("mail.example.org:443"));
1076
1077 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521078 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361079 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431080 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1081 mock_quic_data.AddWrite(
1082 SYNCHRONOUS,
1083 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331084 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431085 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431086 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331087 ASYNC, ConstructServerResponseHeadersPacket(
1088 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1089 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411090 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331091 mock_quic_data.AddRead(
1092 ASYNC, ConstructServerDataPacket(
1093 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411094 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431095 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231096 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1097
1098 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1099
1100 CreateSession();
1101 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1102
1103 EXPECT_FALSE(
1104 test_socket_performance_watcher_factory_.rtt_notification_received());
1105 SendRequestAndExpectQuicResponse("hello!");
1106 EXPECT_TRUE(
1107 test_socket_performance_watcher_factory_.rtt_notification_received());
1108}
1109
1110TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411111 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231112 HostPortPair::FromString("mail.example.org:443"));
1113
1114 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521115 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361116 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431117 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1118 mock_quic_data.AddWrite(
1119 SYNCHRONOUS,
1120 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331121 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431122 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431123 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331124 ASYNC, ConstructServerResponseHeadersPacket(
1125 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1126 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411127 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331128 mock_quic_data.AddRead(
1129 ASYNC, ConstructServerDataPacket(
1130 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411131 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431132 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231133 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1134
1135 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1136
1137 CreateSession();
1138 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1139
1140 EXPECT_FALSE(
1141 test_socket_performance_watcher_factory_.rtt_notification_received());
1142 SendRequestAndExpectQuicResponse("hello!");
1143 EXPECT_FALSE(
1144 test_socket_performance_watcher_factory_.rtt_notification_received());
1145}
1146
[email protected]1e960032013-12-20 19:00:201147TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411148 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571149 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471150
[email protected]1e960032013-12-20 19:00:201151 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521152 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361153 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431154 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1155 mock_quic_data.AddWrite(
1156 SYNCHRONOUS,
1157 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331158 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431159 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431160 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331161 ASYNC, ConstructServerResponseHeadersPacket(
1162 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1163 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411164 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331165 mock_quic_data.AddRead(
1166 ASYNC, ConstructServerDataPacket(
1167 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411168 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431169 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591170 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471171
rcha5399e02015-04-21 19:32:041172 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471173
[email protected]4dca587c2013-03-07 16:54:471174 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471175
[email protected]aa9b14d2013-05-10 23:45:191176 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471177
[email protected]98b20ce2013-05-10 05:55:261178 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461179 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191180 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261181 EXPECT_LT(0u, entries.size());
1182
1183 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291184 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001185 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1186 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261187 EXPECT_LT(0, pos);
1188
rchfd527212015-08-25 00:41:261189 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291190 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261191 entries, 0,
mikecirone8b85c432016-09-08 19:11:001192 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1193 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261194 EXPECT_LT(0, pos);
1195
Eric Romanaefc98c2018-12-18 21:38:011196 int packet_number;
1197 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1198 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261199
rchfd527212015-08-25 00:41:261200 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1201 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001202 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1203 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261204 EXPECT_LT(0, pos);
1205
[email protected]98b20ce2013-05-10 05:55:261206 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291207 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001208 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1209 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261210 EXPECT_LT(0, pos);
1211
1212 int log_stream_id;
1213 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381214 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1215 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471216}
1217
rchbd089ab2017-05-26 23:05:041218TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411219 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041220 HostPortPair::FromString("mail.example.org:443"));
1221
1222 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521223 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041224 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431225 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1226 mock_quic_data.AddWrite(
1227 SYNCHRONOUS,
1228 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331229 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431230 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131231 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041232 response_headers["key1"] = std::string(30000, 'A');
1233 response_headers["key2"] = std::string(30000, 'A');
1234 response_headers["key3"] = std::string(30000, 'A');
1235 response_headers["key4"] = std::string(30000, 'A');
1236 response_headers["key5"] = std::string(30000, 'A');
1237 response_headers["key6"] = std::string(30000, 'A');
1238 response_headers["key7"] = std::string(30000, 'A');
1239 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331240 spdy::SpdyHeadersIR headers_frame(
1241 GetNthClientInitiatedBidirectionalStreamId(0),
1242 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131243 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1244 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041245 response_framer.SerializeFrame(headers_frame);
1246
Fan Yangac867502019-01-28 21:10:231247 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041248 size_t chunk_size = 1200;
1249 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1250 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431251 mock_quic_data.AddRead(
1252 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091253 packet_number++,
1254 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521255 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041256 }
1257
Renjief49758b2019-01-11 23:32:411258 quic::QuicString header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041259 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331260 ASYNC, ConstructServerDataPacket(
1261 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411262 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041263 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431264 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1265 mock_quic_data.AddWrite(ASYNC,
1266 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041267
1268 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1269
1270 CreateSession();
1271
1272 SendRequestAndExpectQuicResponse("hello!");
1273}
1274
1275TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481276 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411277 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041278 HostPortPair::FromString("mail.example.org:443"));
1279
1280 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521281 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041282 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431283 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1284 mock_quic_data.AddWrite(
1285 SYNCHRONOUS,
1286 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331287 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431288 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131289 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041290 response_headers["key1"] = std::string(30000, 'A');
1291 response_headers["key2"] = std::string(30000, 'A');
1292 response_headers["key3"] = std::string(30000, 'A');
1293 response_headers["key4"] = std::string(30000, 'A');
1294 response_headers["key5"] = std::string(30000, 'A');
1295 response_headers["key6"] = std::string(30000, 'A');
1296 response_headers["key7"] = std::string(30000, 'A');
1297 response_headers["key8"] = std::string(30000, 'A');
1298 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331299 spdy::SpdyHeadersIR headers_frame(
1300 GetNthClientInitiatedBidirectionalStreamId(0),
1301 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131302 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1303 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041304 response_framer.SerializeFrame(headers_frame);
1305
Fan Yangac867502019-01-28 21:10:231306 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041307 size_t chunk_size = 1200;
1308 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1309 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431310 mock_quic_data.AddRead(
1311 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091312 packet_number++,
1313 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521314 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041315 }
1316
Renjief49758b2019-01-11 23:32:411317 quic::QuicString header = ConstructDataHeader(6);
1318
rchbd089ab2017-05-26 23:05:041319 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331320 ASYNC, ConstructServerDataPacket(
1321 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411322 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041323 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431324 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1325 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331326 ASYNC, ConstructClientAckAndRstPacket(
1327 4, GetNthClientInitiatedBidirectionalStreamId(0),
1328 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041329
1330 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1331
1332 CreateSession();
1333
1334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1335 TestCompletionCallback callback;
1336 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1337 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1338 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1339}
1340
rcha2bd44b2016-07-02 00:42:551341TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411342 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551343
Ryan Hamilton9835e662018-08-02 05:36:271344 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551345
1346 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521347 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361348 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431349 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1350 mock_quic_data.AddWrite(
1351 SYNCHRONOUS,
1352 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331353 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431354 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431355 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331356 ASYNC, ConstructServerResponseHeadersPacket(
1357 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1358 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411359 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331360 mock_quic_data.AddRead(
1361 ASYNC, ConstructServerDataPacket(
1362 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411363 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431364 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551365 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1366
1367 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1368
1369 CreateSession();
1370
1371 SendRequestAndExpectQuicResponse("hello!");
1372 EXPECT_TRUE(
1373 test_socket_performance_watcher_factory_.rtt_notification_received());
1374}
1375
[email protected]cf3e3cd62014-02-05 16:16:161376TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411377 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591378 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491379 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161380
[email protected]cf3e3cd62014-02-05 16:16:161381 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521382 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361383 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431384 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1385 mock_quic_data.AddWrite(
1386 SYNCHRONOUS,
1387 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331388 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431389 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431390 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331391 ASYNC, ConstructServerResponseHeadersPacket(
1392 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1393 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411394 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331395 mock_quic_data.AddRead(
1396 ASYNC, ConstructServerDataPacket(
1397 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411398 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431399 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501400 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591401 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161402
rcha5399e02015-04-21 19:32:041403 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161404
tbansal0f56a39a2016-04-07 22:03:381405 EXPECT_FALSE(
1406 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161407 // There is no need to set up an alternate protocol job, because
1408 // no attempt will be made to speak to the proxy over TCP.
1409
rch9ae5b3b2016-02-11 00:36:291410 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161411 CreateSession();
1412
bnc62a44f022015-04-02 15:59:411413 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381414 EXPECT_TRUE(
1415 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161416}
1417
bnc313ba9c2015-06-11 15:42:311418// Regression test for https://crbug.com/492458. Test that for an HTTP
1419// connection through a QUIC proxy, the certificate exhibited by the proxy is
1420// checked against the proxy hostname, not the origin hostname.
1421TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291422 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311423 const std::string proxy_host = "www.example.org";
1424
mmenke6ddfbea2017-05-31 21:48:411425 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591426 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491427 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311428
alyssar2adf3ac2016-05-03 17:12:581429 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311430 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521431 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361432 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431433 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1434 mock_quic_data.AddWrite(
1435 SYNCHRONOUS,
1436 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331437 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431438 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431439 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331440 ASYNC, ConstructServerResponseHeadersPacket(
1441 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1442 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411443 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331444 mock_quic_data.AddRead(
1445 ASYNC, ConstructServerDataPacket(
1446 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411447 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431448 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501449 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591450 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311451 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1452
1453 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291454 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311455 ASSERT_TRUE(cert.get());
1456 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241457 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1458 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311459 ProofVerifyDetailsChromium verify_details;
1460 verify_details.cert_verify_result.verified_cert = cert;
1461 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561462 ProofVerifyDetailsChromium verify_details2;
1463 verify_details2.cert_verify_result.verified_cert = cert;
1464 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311465
1466 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091467 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321468 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271469 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311470 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1471}
1472
rchbe69cb902016-02-11 01:10:481473TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341474 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481475 HostPortPair origin("www.example.org", 443);
1476 HostPortPair alternative("mail.example.org", 443);
1477
1478 base::FilePath certs_dir = GetTestCertsDirectory();
1479 scoped_refptr<X509Certificate> cert(
1480 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1481 ASSERT_TRUE(cert.get());
1482 // TODO(rch): the connection should be "to" the origin, so if the cert is
1483 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241484 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1485 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481486 ProofVerifyDetailsChromium verify_details;
1487 verify_details.cert_verify_result.verified_cert = cert;
1488 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1489
alyssar2adf3ac2016-05-03 17:12:581490 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481491 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521492 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361493 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431494 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1495 mock_quic_data.AddWrite(
1496 SYNCHRONOUS,
1497 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331498 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431499 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431500 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331501 ASYNC, ConstructServerResponseHeadersPacket(
1502 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1503 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411504 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331505 mock_quic_data.AddRead(
1506 ASYNC, ConstructServerDataPacket(
1507 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411508 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431509 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481510 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1511 mock_quic_data.AddRead(ASYNC, 0);
1512 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1513
1514 request_.url = GURL("https://" + origin.host());
1515 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271516 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091517 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321518 CreateSession();
rchbe69cb902016-02-11 01:10:481519
1520 SendRequestAndExpectQuicResponse("hello!");
1521}
1522
zhongyief3f4ce52017-07-05 23:53:281523TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521524 quic::QuicTransportVersion unsupported_version =
1525 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281526 // Add support for another QUIC version besides |version_|. Also find a
1527 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521528 for (const quic::QuicTransportVersion& version :
1529 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281530 if (version == version_)
1531 continue;
1532 if (supported_versions_.size() != 2) {
1533 supported_versions_.push_back(version);
1534 continue;
1535 }
1536 unsupported_version = version;
1537 break;
1538 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521539 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281540
1541 // Set up alternative service to use QUIC with a version that is not
1542 // supported.
1543 url::SchemeHostPort server(request_.url);
1544 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1545 443);
1546 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1547 http_server_properties_.SetQuicAlternativeService(
1548 server, alternative_service, expiration, {unsupported_version});
1549
1550 AlternativeServiceInfoVector alt_svc_info_vector =
1551 http_server_properties_.GetAlternativeServiceInfos(server);
1552 EXPECT_EQ(1u, alt_svc_info_vector.size());
1553 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1554 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1555 EXPECT_EQ(unsupported_version,
1556 alt_svc_info_vector[0].advertised_versions()[0]);
1557
1558 // First request should still be sent via TCP as the QUIC version advertised
1559 // in the stored AlternativeService is not supported by the client. However,
1560 // the response from the server will advertise new Alt-Svc with supported
1561 // versions.
1562 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521563 GenerateQuicVersionsListForAltSvcHeader(
1564 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281565 std::string altsvc_header =
1566 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1567 advertised_versions_list_str.c_str());
1568 MockRead http_reads[] = {
1569 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1570 MockRead("hello world"),
1571 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1572 MockRead(ASYNC, OK)};
1573
Ryan Sleevib8d7ea02018-05-07 20:01:011574 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281575 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081576 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281577 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1578
1579 // Second request should be sent via QUIC as a new list of verions supported
1580 // by the client has been advertised by the server.
1581 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521582 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281583 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431584 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1585 mock_quic_data.AddWrite(
1586 SYNCHRONOUS,
1587 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331588 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431589 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431590 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331591 ASYNC, ConstructServerResponseHeadersPacket(
1592 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1593 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411594 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331595 mock_quic_data.AddRead(
1596 ASYNC, ConstructServerDataPacket(
1597 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411598 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431599 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281600 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1601 mock_quic_data.AddRead(ASYNC, 0); // EOF
1602
1603 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1604
1605 AddHangingNonAlternateProtocolSocketData();
1606
1607 CreateSession(supported_versions_);
1608
1609 SendRequestAndExpectHttpResponse("hello world");
1610 SendRequestAndExpectQuicResponse("hello!");
1611
1612 // Check alternative service list is updated with new versions.
1613 alt_svc_info_vector =
1614 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1615 EXPECT_EQ(1u, alt_svc_info_vector.size());
1616 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1617 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1618 // Advertised versions will be lised in a sorted order.
1619 std::sort(supported_versions_.begin(), supported_versions_.end());
1620 EXPECT_EQ(supported_versions_[0],
1621 alt_svc_info_vector[0].advertised_versions()[0]);
1622 EXPECT_EQ(supported_versions_[1],
1623 alt_svc_info_vector[0].advertised_versions()[1]);
1624}
1625
bncaccd4962017-04-06 21:00:261626// Regression test for https://crbug.com/546991.
1627// The server might not be able to serve a request on an alternative connection,
1628// and might send a 421 Misdirected Request response status to indicate this.
1629// HttpNetworkTransaction should reset the request and retry without using
1630// alternative services.
1631TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1632 // Set up alternative service to use QUIC.
1633 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1634 // that overrides |enable_alternative_services|.
1635 url::SchemeHostPort server(request_.url);
1636 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1637 443);
1638 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211639 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441640 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261641
davidbena4449722017-05-05 23:30:531642 // First try: The alternative job uses QUIC and reports an HTTP 421
1643 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1644 // paused at Connect(), so it will never exit the socket pool. This ensures
1645 // that the alternate job always wins the race and keeps whether the
1646 // |http_data| exits the socket pool before the main job is aborted
1647 // deterministic. The first main job gets aborted without the socket pool ever
1648 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261649 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521650 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361651 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431652 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1653 mock_quic_data.AddWrite(
1654 SYNCHRONOUS,
1655 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331656 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431657 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331658 mock_quic_data.AddRead(
1659 ASYNC, ConstructServerResponseHeadersPacket(
1660 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1661 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261662 mock_quic_data.AddRead(ASYNC, OK);
1663 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1664
davidbena4449722017-05-05 23:30:531665 // Second try: The main job uses TCP, and there is no alternate job. Once the
1666 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1667 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261668 // Note that if there was an alternative QUIC Job created for the second try,
1669 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1670 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531671 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1672 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1673 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1674 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1675 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1676 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011677 reads, writes);
bncaccd4962017-04-06 21:00:261678 socket_factory_.AddSocketDataProvider(&http_data);
1679 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1680
bncaccd4962017-04-06 21:00:261681 CreateSession();
1682 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531683
1684 // Run until |mock_quic_data| has failed and |http_data| has paused.
1685 TestCompletionCallback callback;
1686 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1687 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1688 base::RunLoop().RunUntilIdle();
1689
1690 // |mock_quic_data| must have run to completion.
1691 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1692 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1693
1694 // Now that the QUIC data has been consumed, unblock |http_data|.
1695 http_data.socket()->OnConnectComplete(MockConnect());
1696
1697 // The retry logic must hide the 421 status. The transaction succeeds on
1698 // |http_data|.
1699 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261700 CheckWasHttpResponse(&trans);
1701 CheckResponsePort(&trans, 443);
1702 CheckResponseData(&trans, "hello!");
1703}
1704
[email protected]1e960032013-12-20 19:00:201705TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411706 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571707 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301708
tbansalfdf5665b2015-09-21 22:46:401709 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521710 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361711 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431712 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401713 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401714 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371715 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361716 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431717 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301718 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401719 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431720 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401721
1722 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1723 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301724
1725 CreateSession();
1726
tbansal0f56a39a2016-04-07 22:03:381727 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401728 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401730 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161731 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011732 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1733 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381734 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531735
1736 NetErrorDetails details;
1737 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521738 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401739 }
[email protected]cebe3282013-05-22 23:49:301740}
1741
tbansalc8a94ea2015-11-02 23:58:511742TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1743 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411744 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571745 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511746
1747 MockRead http_reads[] = {
1748 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1749 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1750 MockRead(ASYNC, OK)};
1751
Ryan Sleevib8d7ea02018-05-07 20:01:011752 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511753 socket_factory_.AddSocketDataProvider(&data);
1754 SSLSocketDataProvider ssl(ASYNC, OK);
1755 socket_factory_.AddSSLSocketDataProvider(&ssl);
1756
1757 CreateSession();
1758
1759 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381760 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511761}
1762
bncc958faa2015-07-31 18:14:521763TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521764 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561765 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1766 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521767 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1768 MockRead(ASYNC, OK)};
1769
Ryan Sleevib8d7ea02018-05-07 20:01:011770 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521771 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081772 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561773 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521774
1775 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521776 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361777 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431778 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1779 mock_quic_data.AddWrite(
1780 SYNCHRONOUS,
1781 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331782 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431783 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431784 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331785 ASYNC, ConstructServerResponseHeadersPacket(
1786 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1787 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411788 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331789 mock_quic_data.AddRead(
1790 ASYNC, ConstructServerDataPacket(
1791 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411792 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431793 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521794 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591795 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521796
1797 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1798
rtennetib8e80fb2016-05-16 00:12:091799 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321800 CreateSession();
bncc958faa2015-07-31 18:14:521801
1802 SendRequestAndExpectHttpResponse("hello world");
1803 SendRequestAndExpectQuicResponse("hello!");
1804}
1805
zhongyia00ca012017-07-06 23:36:391806TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1807 // Both server advertises and client supports two QUIC versions.
1808 // Only |version_| is advertised and supported.
1809 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1810 // PacketMakers are using |version_|.
1811
1812 // Add support for another QUIC version besides |version_| on the client side.
1813 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521814 quic::QuicTransportVersion advertised_version_2 =
1815 quic::QUIC_VERSION_UNSUPPORTED;
1816 for (const quic::QuicTransportVersion& version :
1817 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391818 if (version == version_)
1819 continue;
1820 if (supported_versions_.size() != 2) {
1821 supported_versions_.push_back(version);
1822 continue;
1823 }
1824 advertised_version_2 = version;
1825 break;
1826 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521827 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391828
1829 std::string QuicAltSvcWithVersionHeader =
1830 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1831 advertised_version_2, version_);
1832
1833 MockRead http_reads[] = {
1834 MockRead("HTTP/1.1 200 OK\r\n"),
1835 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1836 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1837 MockRead(ASYNC, OK)};
1838
Ryan Sleevib8d7ea02018-05-07 20:01:011839 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391840 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081841 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391842 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1843
1844 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521845 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391846 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431847 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1848 mock_quic_data.AddWrite(
1849 SYNCHRONOUS,
1850 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331851 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431852 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431853 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331854 ASYNC, ConstructServerResponseHeadersPacket(
1855 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1856 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411857 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331858 mock_quic_data.AddRead(
1859 ASYNC, ConstructServerDataPacket(
1860 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411861 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431862 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391863 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1864 mock_quic_data.AddRead(ASYNC, 0); // EOF
1865
1866 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1867
1868 AddHangingNonAlternateProtocolSocketData();
1869 CreateSession(supported_versions_);
1870
1871 SendRequestAndExpectHttpResponse("hello world");
1872 SendRequestAndExpectQuicResponse("hello!");
1873}
1874
1875TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1876 // Client and server mutually support more than one QUIC_VERSION.
1877 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1878 // which is verified as the PacketMakers are using |version_|.
1879
Ryan Hamilton8d9ee76e2018-05-29 23:52:521880 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1881 for (const quic::QuicTransportVersion& version :
1882 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391883 if (version == version_)
1884 continue;
1885 common_version_2 = version;
1886 break;
1887 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521888 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391889
1890 supported_versions_.push_back(
1891 common_version_2); // Supported but unpreferred.
1892
1893 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1894 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1895
1896 MockRead http_reads[] = {
1897 MockRead("HTTP/1.1 200 OK\r\n"),
1898 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1900 MockRead(ASYNC, OK)};
1901
Ryan Sleevib8d7ea02018-05-07 20:01:011902 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391903 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081904 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391905 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1906
1907 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521908 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391909 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431910 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1911 mock_quic_data.AddWrite(
1912 SYNCHRONOUS,
1913 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331914 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431915 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431916 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331917 ASYNC, ConstructServerResponseHeadersPacket(
1918 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1919 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411920 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331921 mock_quic_data.AddRead(
1922 ASYNC, ConstructServerDataPacket(
1923 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411924 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431925 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391926 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1927 mock_quic_data.AddRead(ASYNC, 0); // EOF
1928
1929 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1930
1931 AddHangingNonAlternateProtocolSocketData();
1932 CreateSession(supported_versions_);
1933
1934 SendRequestAndExpectHttpResponse("hello world");
1935 SendRequestAndExpectQuicResponse("hello!");
1936}
1937
rchf47265dc2016-03-21 21:33:121938TEST_P(QuicNetworkTransactionTest,
1939 UseAlternativeServiceWithProbabilityForQuic) {
1940 MockRead http_reads[] = {
1941 MockRead("HTTP/1.1 200 OK\r\n"),
1942 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1943 MockRead("hello world"),
1944 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1945 MockRead(ASYNC, OK)};
1946
Ryan Sleevib8d7ea02018-05-07 20:01:011947 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121948 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081949 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121950 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1951
1952 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521953 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361954 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431955 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1956 mock_quic_data.AddWrite(
1957 SYNCHRONOUS,
1958 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331959 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431960 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431961 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331962 ASYNC, ConstructServerResponseHeadersPacket(
1963 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1964 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411965 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331966 mock_quic_data.AddRead(
1967 ASYNC, ConstructServerDataPacket(
1968 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411969 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431970 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121971 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1972 mock_quic_data.AddRead(ASYNC, 0); // EOF
1973
1974 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1975
rtennetib8e80fb2016-05-16 00:12:091976 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121977 CreateSession();
1978
1979 SendRequestAndExpectHttpResponse("hello world");
1980 SendRequestAndExpectQuicResponse("hello!");
1981}
1982
zhongyi3d4a55e72016-04-22 20:36:461983TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1984 MockRead http_reads[] = {
1985 MockRead("HTTP/1.1 200 OK\r\n"),
1986 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1987 MockRead("hello world"),
1988 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1989 MockRead(ASYNC, OK)};
1990
Ryan Sleevib8d7ea02018-05-07 20:01:011991 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461992 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081993 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461994 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1995
1996 CreateSession();
bncb26024382016-06-29 02:39:451997 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461998 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451999 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462000 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402001 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462002 session_->http_server_properties();
2003 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2004 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2005 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462006 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342007 2u,
2008 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452009 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342010 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462011}
2012
2013TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2014 MockRead http_reads[] = {
2015 MockRead("HTTP/1.1 200 OK\r\n"),
2016 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2017 MockRead("hello world"),
2018 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2019 MockRead(ASYNC, OK)};
2020
Ryan Sleevib8d7ea02018-05-07 20:01:012021 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082022 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462023
2024 socket_factory_.AddSocketDataProvider(&http_data);
2025 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2026 socket_factory_.AddSocketDataProvider(&http_data);
2027 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2028
2029 CreateSession();
2030
2031 // Send https request and set alternative services if response header
2032 // advertises alternative service for mail.example.org.
2033 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402034 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462035 session_->http_server_properties();
2036
2037 const url::SchemeHostPort https_server(request_.url);
2038 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342039 EXPECT_EQ(
2040 2u,
2041 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462042
2043 // Send http request to the same origin but with diffrent scheme, should not
2044 // use QUIC.
2045 request_.url = GURL("http://mail.example.org:443");
2046 SendRequestAndExpectHttpResponse("hello world");
2047}
2048
zhongyie537a002017-06-27 16:48:212049TEST_P(QuicNetworkTransactionTest,
2050 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442051 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522052 for (const quic::QuicTransportVersion& version :
2053 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442054 if (version == version_)
2055 continue;
2056 supported_versions_.push_back(version);
2057 break;
2058 }
2059
zhongyie537a002017-06-27 16:48:212060 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522061 GenerateQuicVersionsListForAltSvcHeader(
2062 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212063 std::string altsvc_header =
2064 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2065 advertised_versions_list_str.c_str());
2066 MockRead http_reads[] = {
2067 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2068 MockRead("hello world"),
2069 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2070 MockRead(ASYNC, OK)};
2071
Ryan Sleevib8d7ea02018-05-07 20:01:012072 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212073 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082074 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212075 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2076
2077 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522078 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212079 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432080 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2081 mock_quic_data.AddWrite(
2082 SYNCHRONOUS,
2083 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332084 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432085 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432086 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332087 ASYNC, ConstructServerResponseHeadersPacket(
2088 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2089 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412090 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332091 mock_quic_data.AddRead(
2092 ASYNC, ConstructServerDataPacket(
2093 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412094 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432095 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212096 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2097 mock_quic_data.AddRead(ASYNC, 0); // EOF
2098
2099 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2100
2101 AddHangingNonAlternateProtocolSocketData();
2102
zhongyi86838d52017-06-30 01:19:442103 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212104
2105 SendRequestAndExpectHttpResponse("hello world");
2106 SendRequestAndExpectQuicResponse("hello!");
2107
2108 // Check alternative service is set with only mutually supported versions.
2109 const url::SchemeHostPort https_server(request_.url);
2110 const AlternativeServiceInfoVector alt_svc_info_vector =
2111 session_->http_server_properties()->GetAlternativeServiceInfos(
2112 https_server);
2113 EXPECT_EQ(1u, alt_svc_info_vector.size());
2114 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2115 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2116 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442117 std::sort(supported_versions_.begin(), supported_versions_.end());
2118 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212119 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442120 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212121 alt_svc_info_vector[0].advertised_versions()[1]);
2122}
2123
danzh3134c2562016-08-12 14:07:522124TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442125 std::string altsvc_header =
2126 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072127 MockRead http_reads[] = {
2128 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2129 MockRead("hello world"),
2130 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2131 MockRead(ASYNC, OK)};
2132
Ryan Sleevib8d7ea02018-05-07 20:01:012133 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072134 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082135 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072136 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2137
2138 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522139 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362140 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432141 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2142 mock_quic_data.AddWrite(
2143 SYNCHRONOUS,
2144 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332145 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432146 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432147 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332148 ASYNC, ConstructServerResponseHeadersPacket(
2149 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2150 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412151 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332152 mock_quic_data.AddRead(
2153 ASYNC, ConstructServerDataPacket(
2154 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412155 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432156 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072157 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592158 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072159
2160 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2161
rtennetib8e80fb2016-05-16 00:12:092162 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322163 CreateSession();
bnc8be55ebb2015-10-30 14:12:072164
2165 SendRequestAndExpectHttpResponse("hello world");
2166 SendRequestAndExpectQuicResponse("hello!");
2167}
2168
zhongyi6b5a3892016-03-12 04:46:202169TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092170 if (version_ == quic::QUIC_VERSION_99) {
2171 // Not available under version 99
2172 return;
2173 }
zhongyi6b5a3892016-03-12 04:46:202174 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522175 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362176 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432177 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2178 mock_quic_data.AddWrite(
2179 SYNCHRONOUS,
2180 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332181 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432182 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332183 mock_quic_data.AddRead(
2184 ASYNC, ConstructServerResponseHeadersPacket(
2185 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2186 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202187 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522188 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432189 mock_quic_data.AddRead(SYNCHRONOUS,
2190 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522191 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432192 "connection migration with port change only"));
2193 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:412194 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332195 mock_quic_data.AddRead(
2196 SYNCHRONOUS, ConstructServerDataPacket(
2197 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412198 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332199 mock_quic_data.AddWrite(SYNCHRONOUS,
2200 ConstructClientAckAndRstPacket(
2201 4, GetNthClientInitiatedBidirectionalStreamId(0),
2202 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202203 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2204 mock_quic_data.AddRead(ASYNC, 0); // EOF
2205
2206 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2207
2208 // The non-alternate protocol job needs to hang in order to guarantee that
2209 // the alternate-protocol job will "win".
2210 AddHangingNonAlternateProtocolSocketData();
2211
2212 // In order for a new QUIC session to be established via alternate-protocol
2213 // without racing an HTTP connection, we need the host resolution to happen
2214 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2215 // connection to the the server, in this test we require confirmation
2216 // before encrypting so the HTTP job will still start.
2217 host_resolver_.set_synchronous_mode(true);
2218 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2219 "");
zhongyi6b5a3892016-03-12 04:46:202220
2221 CreateSession();
2222 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272223 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202224
bnc691fda62016-08-12 00:43:162225 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202226 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362227 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202229
2230 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522231 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012232 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202233
2234 // Check whether this transaction is correctly marked as received a go-away
2235 // because of migrating port.
2236 NetErrorDetails details;
2237 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162238 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202239 EXPECT_TRUE(details.quic_port_migration_detected);
2240}
2241
Zhongyi Shia6b68d112018-09-24 07:49:032242// This test verifies that a new QUIC connection will be attempted on the
2243// alternate network if the original QUIC connection fails with idle timeout
2244// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2245// alternate network as well, QUIC is marked as broken and the brokenness will
2246// not expire when default network changes.
2247TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2248 SetUpTestForRetryConnectionOnAlternateNetwork();
2249
2250 std::string request_data;
2251 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2252 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2253
2254 // The request will initially go out over QUIC.
2255 MockQuicData quic_data;
2256 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2257 int packet_num = 1;
2258 quic_data.AddWrite(SYNCHRONOUS,
2259 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2260 // Retranmit the handshake messages.
2261 quic_data.AddWrite(SYNCHRONOUS,
2262 client_maker_.MakeDummyCHLOPacket(packet_num++));
2263 quic_data.AddWrite(SYNCHRONOUS,
2264 client_maker_.MakeDummyCHLOPacket(packet_num++));
2265 quic_data.AddWrite(SYNCHRONOUS,
2266 client_maker_.MakeDummyCHLOPacket(packet_num++));
2267 quic_data.AddWrite(SYNCHRONOUS,
2268 client_maker_.MakeDummyCHLOPacket(packet_num++));
2269 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2270 if (version_ <= quic::QUIC_VERSION_39) {
2271 quic_data.AddWrite(SYNCHRONOUS,
2272 client_maker_.MakeDummyCHLOPacket(packet_num++));
2273 }
2274 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2275 quic_data.AddWrite(SYNCHRONOUS,
2276 client_maker_.MakeConnectionClosePacket(
2277 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2278 "No recent network activity."));
2279 quic_data.AddSocketDataToFactory(&socket_factory_);
2280
2281 // Add successful TCP data so that TCP job will succeed.
2282 MockWrite http_writes[] = {
2283 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2284 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2285 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2286
2287 MockRead http_reads[] = {
2288 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2289 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2290 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2291 SequencedSocketData http_data(http_reads, http_writes);
2292 socket_factory_.AddSocketDataProvider(&http_data);
2293 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2294
2295 // Add data for the second QUIC connection to fail.
2296 MockQuicData quic_data2;
2297 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2298 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2299 quic_data2.AddSocketDataToFactory(&socket_factory_);
2300
2301 // Resolve the host resolution synchronously.
2302 host_resolver_.set_synchronous_mode(true);
2303 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2304 "");
Zhongyi Shia6b68d112018-09-24 07:49:032305
2306 CreateSession();
2307 session_->quic_stream_factory()->set_require_confirmation(true);
2308 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2309 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2310 QuicStreamFactoryPeer::SetAlarmFactory(
2311 session_->quic_stream_factory(),
2312 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2313 &clock_));
2314 // Add alternate protocol mapping to race QUIC and TCP.
2315 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2316 // peer.
2317 AddQuicAlternateProtocolMapping(
2318 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2319
2320 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2321 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362322 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032323 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2324
2325 // Pump the message loop to get the request started.
2326 // Request will be served with TCP job.
2327 base::RunLoop().RunUntilIdle();
2328 EXPECT_THAT(callback.WaitForResult(), IsOk());
2329 CheckResponseData(&trans, "TCP succeeds");
2330
2331 // Fire the retransmission alarm, from this point, connection will idle
2332 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062333 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182334 quic_fix_time_of_first_packet_sent_after_receiving)) {
2335 quic_task_runner_->RunNextTask();
2336 }
Zhongyi Shia6b68d112018-09-24 07:49:032337 // Fast forward to idle timeout the original connection. A new connection will
2338 // be kicked off on the alternate network.
2339 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2340 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2341 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2342
2343 // Run the message loop to execute posted tasks, which will report job status.
2344 base::RunLoop().RunUntilIdle();
2345
2346 // Verify that QUIC is marked as broken.
2347 ExpectBrokenAlternateProtocolMapping();
2348
2349 // Deliver a message to notify the new network becomes default, the brokenness
2350 // will not expire as QUIC is broken on both networks.
2351 scoped_mock_change_notifier_->mock_network_change_notifier()
2352 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2353 ExpectBrokenAlternateProtocolMapping();
2354
2355 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2356 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2357}
2358
2359// This test verifies that a new QUIC connection will be attempted on the
2360// alternate network if the original QUIC connection fails with idle timeout
2361// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2362// alternate network, QUIC is marked as broken. The brokenness will expire when
2363// the default network changes.
2364TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2365 SetUpTestForRetryConnectionOnAlternateNetwork();
2366
2367 std::string request_data;
2368 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2369 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2370
2371 // The request will initially go out over QUIC.
2372 MockQuicData quic_data;
2373 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2374 int packet_num = 1;
2375 quic_data.AddWrite(SYNCHRONOUS,
2376 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2377 // Retranmit the handshake messages.
2378 quic_data.AddWrite(SYNCHRONOUS,
2379 client_maker_.MakeDummyCHLOPacket(packet_num++));
2380 quic_data.AddWrite(SYNCHRONOUS,
2381 client_maker_.MakeDummyCHLOPacket(packet_num++));
2382 quic_data.AddWrite(SYNCHRONOUS,
2383 client_maker_.MakeDummyCHLOPacket(packet_num++));
2384 quic_data.AddWrite(SYNCHRONOUS,
2385 client_maker_.MakeDummyCHLOPacket(packet_num++));
2386 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2387 if (version_ <= quic::QUIC_VERSION_39) {
2388 quic_data.AddWrite(SYNCHRONOUS,
2389 client_maker_.MakeDummyCHLOPacket(packet_num++));
2390 }
2391 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2392 quic_data.AddWrite(SYNCHRONOUS,
2393 client_maker_.MakeConnectionClosePacket(
2394 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2395 "No recent network activity."));
2396 quic_data.AddSocketDataToFactory(&socket_factory_);
2397
2398 // Add successful TCP data so that TCP job will succeed.
2399 MockWrite http_writes[] = {
2400 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2401 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2402 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2403
2404 MockRead http_reads[] = {
2405 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2406 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2407 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2408 SequencedSocketData http_data(http_reads, http_writes);
2409 socket_factory_.AddSocketDataProvider(&http_data);
2410 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2411
2412 // Quic connection will be retried on the alternate network after the initial
2413 // one fails on the default network.
2414 MockQuicData quic_data2;
2415 quic::QuicStreamOffset header_stream_offset = 0;
2416 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2417 quic_data2.AddWrite(SYNCHRONOUS,
2418 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2419
2420 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2421 quic_data2.AddWrite(SYNCHRONOUS,
2422 ConstructInitialSettingsPacket(2, &header_stream_offset));
2423 quic_data2.AddSocketDataToFactory(&socket_factory_);
2424
2425 // Resolve the host resolution synchronously.
2426 host_resolver_.set_synchronous_mode(true);
2427 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2428 "");
Zhongyi Shia6b68d112018-09-24 07:49:032429
2430 CreateSession();
2431 session_->quic_stream_factory()->set_require_confirmation(true);
2432 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2433 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2434 QuicStreamFactoryPeer::SetAlarmFactory(
2435 session_->quic_stream_factory(),
2436 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2437 &clock_));
2438 // Add alternate protocol mapping to race QUIC and TCP.
2439 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2440 // peer.
2441 AddQuicAlternateProtocolMapping(
2442 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2443
2444 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2445 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362446 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2448
2449 // Pump the message loop to get the request started.
2450 // Request will be served with TCP job.
2451 base::RunLoop().RunUntilIdle();
2452 EXPECT_THAT(callback.WaitForResult(), IsOk());
2453 CheckResponseData(&trans, "TCP succeeds");
2454
2455 // Fire the retransmission alarm, after which connection will idle
2456 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062457 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182458 quic_fix_time_of_first_packet_sent_after_receiving)) {
2459 quic_task_runner_->RunNextTask();
2460 }
Zhongyi Shia6b68d112018-09-24 07:49:032461 // Fast forward to idle timeout the original connection. A new connection will
2462 // be kicked off on the alternate network.
2463 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2464 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2465 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2466
2467 // The second connection hasn't finish handshake, verify that QUIC is not
2468 // marked as broken.
2469 ExpectQuicAlternateProtocolMapping();
2470 // Explicitly confirm the handshake on the second connection.
2471 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2472 quic::QuicSession::HANDSHAKE_CONFIRMED);
2473 // Run message loop to execute posted tasks, which will notify JoController
2474 // about the orphaned job status.
2475 base::RunLoop().RunUntilIdle();
2476
2477 // Verify that QUIC is marked as broken.
2478 ExpectBrokenAlternateProtocolMapping();
2479
2480 // Deliver a message to notify the new network becomes default, the previous
2481 // brokenness will be clear as the brokenness is bond with old default
2482 // network.
2483 scoped_mock_change_notifier_->mock_network_change_notifier()
2484 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2485 ExpectQuicAlternateProtocolMapping();
2486
2487 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2488 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2489}
2490
2491// This test verifies that a new QUIC connection will be attempted on the
2492// alternate network if the original QUIC connection fails with idle timeout
2493// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2494// alternative network succeeds, QUIC is not marked as broken.
2495TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2496 SetUpTestForRetryConnectionOnAlternateNetwork();
2497
2498 std::string request_data;
2499 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2500 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2501
2502 // The request will initially go out over QUIC.
2503 MockQuicData quic_data;
2504 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2505 int packet_num = 1;
2506 quic_data.AddWrite(SYNCHRONOUS,
2507 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2508 // Retranmit the handshake messages.
2509 quic_data.AddWrite(SYNCHRONOUS,
2510 client_maker_.MakeDummyCHLOPacket(packet_num++));
2511 quic_data.AddWrite(SYNCHRONOUS,
2512 client_maker_.MakeDummyCHLOPacket(packet_num++));
2513 quic_data.AddWrite(SYNCHRONOUS,
2514 client_maker_.MakeDummyCHLOPacket(packet_num++));
2515 quic_data.AddWrite(SYNCHRONOUS,
2516 client_maker_.MakeDummyCHLOPacket(packet_num++));
2517 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2518 // quic_fix_has_pending_crypto_data is introduced and enabled.
2519 if (version_ <= quic::QUIC_VERSION_39) {
2520 quic_data.AddWrite(SYNCHRONOUS,
2521 client_maker_.MakeDummyCHLOPacket(packet_num++));
2522 }
2523 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2524 quic_data.AddWrite(SYNCHRONOUS,
2525 client_maker_.MakeConnectionClosePacket(
2526 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2527 "No recent network activity."));
2528 quic_data.AddSocketDataToFactory(&socket_factory_);
2529
2530 // Add hanging TCP data so that TCP job will never succeeded.
2531 AddHangingNonAlternateProtocolSocketData();
2532
2533 // Quic connection will then be retried on the alternate network.
2534 MockQuicData quic_data2;
2535 quic::QuicStreamOffset header_stream_offset = 0;
2536 quic_data2.AddWrite(SYNCHRONOUS,
2537 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2538
Renjief49758b2019-01-11 23:32:412539 const quic::QuicString body = "hello!";
2540 quic::QuicString header = ConstructDataHeader(body.length());
2541
Zhongyi Shia6b68d112018-09-24 07:49:032542 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2543 quic_data2.AddWrite(SYNCHRONOUS,
2544 ConstructInitialSettingsPacket(2, &header_stream_offset));
2545 quic_data2.AddWrite(
2546 SYNCHRONOUS,
2547 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332548 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032549 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032550 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332551 ASYNC, ConstructServerResponseHeadersPacket(
2552 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2553 GetResponseHeaders("200 OK")));
2554 quic_data2.AddRead(
2555 ASYNC, ConstructServerDataPacket(
2556 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412557 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032558 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2559 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2560 quic_data2.AddSocketDataToFactory(&socket_factory_);
2561
2562 // Resolve the host resolution synchronously.
2563 host_resolver_.set_synchronous_mode(true);
2564 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2565 "");
Zhongyi Shia6b68d112018-09-24 07:49:032566
2567 CreateSession();
2568 session_->quic_stream_factory()->set_require_confirmation(true);
2569 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2570 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2571 QuicStreamFactoryPeer::SetAlarmFactory(
2572 session_->quic_stream_factory(),
2573 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2574 &clock_));
2575 // Add alternate protocol mapping to race QUIC and TCP.
2576 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2577 // peer.
2578 AddQuicAlternateProtocolMapping(
2579 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2580
2581 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2582 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362583 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032584 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2585
2586 // Pump the message loop to get the request started.
2587 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062588 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182589 quic_fix_time_of_first_packet_sent_after_receiving)) {
2590 quic_task_runner_->RunNextTask();
2591 }
Zhongyi Shia6b68d112018-09-24 07:49:032592
2593 // Fast forward to idle timeout the original connection. A new connection will
2594 // be kicked off on the alternate network.
2595 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2596 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2597 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2598
2599 // Verify that QUIC is not marked as broken.
2600 ExpectQuicAlternateProtocolMapping();
2601 // Explicitly confirm the handshake on the second connection.
2602 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2603 quic::QuicSession::HANDSHAKE_CONFIRMED);
2604
2605 // Read the response.
2606 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412607 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032608 // Verify that QUIC is not marked as broken.
2609 ExpectQuicAlternateProtocolMapping();
2610
2611 // Deliver a message to notify the new network becomes default.
2612 scoped_mock_change_notifier_->mock_network_change_notifier()
2613 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2614 ExpectQuicAlternateProtocolMapping();
2615 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2616 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2617}
2618
rch9ecde09b2017-04-08 00:18:232619// Verify that if a QUIC connection times out, the QuicHttpStream will
2620// return QUIC_PROTOCOL_ERROR.
2621TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482622 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412623 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232624
2625 // The request will initially go out over QUIC.
2626 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522627 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132628 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232629 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2630
2631 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522632 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2633 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432634 quic_data.AddWrite(SYNCHRONOUS,
2635 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332636 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2637 true, priority, GetRequestHeaders("GET", "https", "/"),
2638 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232639
2640 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522641 quic::QuicStreamOffset settings_offset = header_stream_offset;
2642 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432643 quic_data.AddWrite(SYNCHRONOUS,
2644 client_maker_.MakeInitialSettingsPacketAndSaveData(
2645 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232646 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092647 quic_data.AddWrite(SYNCHRONOUS,
2648 client_maker_.MakeDataPacket(
2649 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2650 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232651 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092652 quic_data.AddWrite(SYNCHRONOUS,
2653 client_maker_.MakeDataPacket(
2654 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2655 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232656 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092657 quic_data.AddWrite(SYNCHRONOUS,
2658 client_maker_.MakeDataPacket(
2659 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2660 false, 0, request_data));
2661 quic_data.AddWrite(SYNCHRONOUS,
2662 client_maker_.MakeDataPacket(
2663 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2664 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232665 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092666 quic_data.AddWrite(SYNCHRONOUS,
2667 client_maker_.MakeDataPacket(
2668 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2669 false, 0, request_data));
2670 quic_data.AddWrite(SYNCHRONOUS,
2671 client_maker_.MakeDataPacket(
2672 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2673 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232674 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092675 quic_data.AddWrite(SYNCHRONOUS,
2676 client_maker_.MakeDataPacket(
2677 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2678 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522679 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092680 SYNCHRONOUS, client_maker_.MakeDataPacket(
2681 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2682 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232683
Zhongyi Shi32f2fd02018-04-16 18:23:432684 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522685 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432686 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222687
rch9ecde09b2017-04-08 00:18:232688 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2689 quic_data.AddRead(ASYNC, OK);
2690 quic_data.AddSocketDataToFactory(&socket_factory_);
2691
2692 // In order for a new QUIC session to be established via alternate-protocol
2693 // without racing an HTTP connection, we need the host resolution to happen
2694 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2695 // connection to the the server, in this test we require confirmation
2696 // before encrypting so the HTTP job will still start.
2697 host_resolver_.set_synchronous_mode(true);
2698 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2699 "");
rch9ecde09b2017-04-08 00:18:232700
2701 CreateSession();
2702 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552703 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232704 QuicStreamFactoryPeer::SetAlarmFactory(
2705 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192706 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552707 &clock_));
rch9ecde09b2017-04-08 00:18:232708
Ryan Hamilton9835e662018-08-02 05:36:272709 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232710
2711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2712 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362713 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2715
2716 // Pump the message loop to get the request started.
2717 base::RunLoop().RunUntilIdle();
2718 // Explicitly confirm the handshake.
2719 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522720 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232721
2722 // Run the QUIC session to completion.
2723 quic_task_runner_->RunUntilIdle();
2724
2725 ExpectQuicAlternateProtocolMapping();
2726 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2727 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2728}
2729
2730// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2731// return QUIC_PROTOCOL_ERROR.
2732TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482733 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522734 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232735
2736 // The request will initially go out over QUIC.
2737 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522738 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132739 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232740 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2741
2742 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522743 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2744 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432745 quic_data.AddWrite(SYNCHRONOUS,
2746 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332747 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2748 true, priority, GetRequestHeaders("GET", "https", "/"),
2749 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232750
2751 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522752 quic::QuicStreamOffset settings_offset = header_stream_offset;
2753 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432754 quic_data.AddWrite(SYNCHRONOUS,
2755 client_maker_.MakeInitialSettingsPacketAndSaveData(
2756 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232757 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092758 quic_data.AddWrite(SYNCHRONOUS,
2759 client_maker_.MakeDataPacket(
2760 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2761 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232762 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092763 quic_data.AddWrite(SYNCHRONOUS,
2764 client_maker_.MakeDataPacket(
2765 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2766 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232767 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092768 quic_data.AddWrite(SYNCHRONOUS,
2769 client_maker_.MakeDataPacket(
2770 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2771 false, 0, request_data));
2772 quic_data.AddWrite(SYNCHRONOUS,
2773 client_maker_.MakeDataPacket(
2774 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2775 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232776 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092777 quic_data.AddWrite(SYNCHRONOUS,
2778 client_maker_.MakeDataPacket(
2779 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2780 false, 0, request_data));
2781 quic_data.AddWrite(SYNCHRONOUS,
2782 client_maker_.MakeDataPacket(
2783 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2784 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232785 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092786 quic_data.AddWrite(SYNCHRONOUS,
2787 client_maker_.MakeDataPacket(
2788 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2789 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522790 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092791 SYNCHRONOUS, client_maker_.MakeDataPacket(
2792 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2793 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232794 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522795 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092796 SYNCHRONOUS, client_maker_.MakeDataPacket(
2797 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2798 false, 0, request_data));
2799 quic_data.AddWrite(
2800 SYNCHRONOUS, client_maker_.MakeDataPacket(
2801 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2802 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232803 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432804 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522805 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432806 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232807
2808 quic_data.AddRead(ASYNC, OK);
2809 quic_data.AddSocketDataToFactory(&socket_factory_);
2810
2811 // In order for a new QUIC session to be established via alternate-protocol
2812 // without racing an HTTP connection, we need the host resolution to happen
2813 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2814 // connection to the the server, in this test we require confirmation
2815 // before encrypting so the HTTP job will still start.
2816 host_resolver_.set_synchronous_mode(true);
2817 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2818 "");
rch9ecde09b2017-04-08 00:18:232819
2820 CreateSession();
2821 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552822 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232823 QuicStreamFactoryPeer::SetAlarmFactory(
2824 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192825 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552826 &clock_));
rch9ecde09b2017-04-08 00:18:232827
Ryan Hamilton9835e662018-08-02 05:36:272828 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232829
2830 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2831 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362832 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232833 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2834
2835 // Pump the message loop to get the request started.
2836 base::RunLoop().RunUntilIdle();
2837 // Explicitly confirm the handshake.
2838 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522839 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232840
2841 // Run the QUIC session to completion.
2842 quic_task_runner_->RunUntilIdle();
2843
2844 ExpectQuicAlternateProtocolMapping();
2845 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2846 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2847}
2848
2849// Verify that if a QUIC connection RTOs, while there are no active streams
2850// QUIC will not be marked as broken.
2851TEST_P(QuicNetworkTransactionTest,
2852 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522853 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232854
2855 // The request will initially go out over QUIC.
2856 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522857 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132858 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232859 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2860
2861 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522862 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2863 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432864 quic_data.AddWrite(SYNCHRONOUS,
2865 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332866 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2867 true, priority, GetRequestHeaders("GET", "https", "/"),
2868 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232869
2870 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522871 quic::QuicStreamOffset settings_offset = header_stream_offset;
2872 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432873 quic_data.AddWrite(SYNCHRONOUS,
2874 client_maker_.MakeInitialSettingsPacketAndSaveData(
2875 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232876
Fan Yang32c5a112018-12-10 20:06:332877 quic_data.AddWrite(SYNCHRONOUS,
2878 client_maker_.MakeRstPacket(
2879 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2880 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232881 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092882 quic_data.AddWrite(SYNCHRONOUS,
2883 client_maker_.MakeDataPacket(
2884 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2885 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232886 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092887 quic_data.AddWrite(SYNCHRONOUS,
2888 client_maker_.MakeDataPacket(
2889 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2890 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232891 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332892 quic_data.AddWrite(SYNCHRONOUS,
2893 client_maker_.MakeRstPacket(
2894 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2895 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092896 quic_data.AddWrite(SYNCHRONOUS,
2897 client_maker_.MakeDataPacket(
2898 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2899 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232900 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092901 quic_data.AddWrite(SYNCHRONOUS,
2902 client_maker_.MakeDataPacket(
2903 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2904 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332905 quic_data.AddWrite(SYNCHRONOUS,
2906 client_maker_.MakeRstPacket(
2907 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2908 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232909 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522910 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092911 SYNCHRONOUS, client_maker_.MakeDataPacket(
2912 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2913 false, 0, request_data));
2914 quic_data.AddWrite(
2915 SYNCHRONOUS, client_maker_.MakeDataPacket(
2916 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2917 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232918 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432919 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332920 SYNCHRONOUS, client_maker_.MakeRstPacket(
2921 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2922 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522923 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092924 SYNCHRONOUS, client_maker_.MakeDataPacket(
2925 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2926 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232927 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432928 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522929 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432930 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232931
2932 quic_data.AddRead(ASYNC, OK);
2933 quic_data.AddSocketDataToFactory(&socket_factory_);
2934
2935 // In order for a new QUIC session to be established via alternate-protocol
2936 // without racing an HTTP connection, we need the host resolution to happen
2937 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2938 // connection to the the server, in this test we require confirmation
2939 // before encrypting so the HTTP job will still start.
2940 host_resolver_.set_synchronous_mode(true);
2941 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2942 "");
rch9ecde09b2017-04-08 00:18:232943
2944 CreateSession();
2945 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552946 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232947 QuicStreamFactoryPeer::SetAlarmFactory(
2948 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192949 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552950 &clock_));
rch9ecde09b2017-04-08 00:18:232951
Ryan Hamilton9835e662018-08-02 05:36:272952 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232953
Jeremy Roman0579ed62017-08-29 15:56:192954 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232955 session_.get());
2956 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362957 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2959
2960 // Pump the message loop to get the request started.
2961 base::RunLoop().RunUntilIdle();
2962 // Explicitly confirm the handshake.
2963 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522964 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232965
2966 // Now cancel the request.
2967 trans.reset();
2968
2969 // Run the QUIC session to completion.
2970 quic_task_runner_->RunUntilIdle();
2971
2972 ExpectQuicAlternateProtocolMapping();
2973
2974 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2975}
2976
rch2f2991c2017-04-13 19:28:172977// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2978// the request fails with QUIC_PROTOCOL_ERROR.
2979TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482980 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172981 // The request will initially go out over QUIC.
2982 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522983 quic::QuicStreamOffset header_stream_offset = 0;
2984 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2985 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432986 quic_data.AddWrite(
2987 SYNCHRONOUS,
2988 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332989 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432990 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522991 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432992 quic_data.AddWrite(SYNCHRONOUS,
2993 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:172994 // Peer sending data from an non-existing stream causes this end to raise
2995 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:332996 quic_data.AddRead(
2997 ASYNC, ConstructServerRstPacket(
2998 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
2999 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173000 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433001 quic_data.AddWrite(SYNCHRONOUS,
3002 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523003 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3004 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173005 quic_data.AddSocketDataToFactory(&socket_factory_);
3006
3007 // In order for a new QUIC session to be established via alternate-protocol
3008 // without racing an HTTP connection, we need the host resolution to happen
3009 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3010 // connection to the the server, in this test we require confirmation
3011 // before encrypting so the HTTP job will still start.
3012 host_resolver_.set_synchronous_mode(true);
3013 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3014 "");
rch2f2991c2017-04-13 19:28:173015
3016 CreateSession();
3017
Ryan Hamilton9835e662018-08-02 05:36:273018 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173019
3020 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3021 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363022 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3024
3025 // Pump the message loop to get the request started.
3026 base::RunLoop().RunUntilIdle();
3027 // Explicitly confirm the handshake.
3028 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523029 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173030
3031 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3032
3033 // Run the QUIC session to completion.
3034 base::RunLoop().RunUntilIdle();
3035 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3036 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3037
3038 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3039 ExpectQuicAlternateProtocolMapping();
3040 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3041}
3042
rch9ecde09b2017-04-08 00:18:233043// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3044// connection times out, then QUIC will be marked as broken and the request
3045// retried over TCP.
3046TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413047 session_params_.mark_quic_broken_when_network_blackholes = true;
3048 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233049
3050 // The request will initially go out over QUIC.
3051 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523052 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133053 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233054 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3055
3056 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523057 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3058 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433059 quic_data.AddWrite(SYNCHRONOUS,
3060 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333061 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3062 true, priority, GetRequestHeaders("GET", "https", "/"),
3063 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233064
3065 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523066 quic::QuicStreamOffset settings_offset = header_stream_offset;
3067 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433068 quic_data.AddWrite(SYNCHRONOUS,
3069 client_maker_.MakeInitialSettingsPacketAndSaveData(
3070 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233071 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093072 quic_data.AddWrite(SYNCHRONOUS,
3073 client_maker_.MakeDataPacket(
3074 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3075 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233076 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093077 quic_data.AddWrite(SYNCHRONOUS,
3078 client_maker_.MakeDataPacket(
3079 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3080 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233081 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093082 quic_data.AddWrite(SYNCHRONOUS,
3083 client_maker_.MakeDataPacket(
3084 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3085 false, 0, request_data));
3086 quic_data.AddWrite(SYNCHRONOUS,
3087 client_maker_.MakeDataPacket(
3088 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3089 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233090 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093091 quic_data.AddWrite(SYNCHRONOUS,
3092 client_maker_.MakeDataPacket(
3093 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3094 false, 0, request_data));
3095 quic_data.AddWrite(SYNCHRONOUS,
3096 client_maker_.MakeDataPacket(
3097 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3098 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233099 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093100 quic_data.AddWrite(SYNCHRONOUS,
3101 client_maker_.MakeDataPacket(
3102 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3103 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523104 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093105 SYNCHRONOUS, client_maker_.MakeDataPacket(
3106 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3107 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233108
Zhongyi Shi32f2fd02018-04-16 18:23:433109 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523110 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433111 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223112
rch9ecde09b2017-04-08 00:18:233113 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3114 quic_data.AddRead(ASYNC, OK);
3115 quic_data.AddSocketDataToFactory(&socket_factory_);
3116
3117 // After that fails, it will be resent via TCP.
3118 MockWrite http_writes[] = {
3119 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3120 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3121 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3122
3123 MockRead http_reads[] = {
3124 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3125 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3126 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013127 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233128 socket_factory_.AddSocketDataProvider(&http_data);
3129 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3130
3131 // In order for a new QUIC session to be established via alternate-protocol
3132 // without racing an HTTP connection, we need the host resolution to happen
3133 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3134 // connection to the the server, in this test we require confirmation
3135 // before encrypting so the HTTP job will still start.
3136 host_resolver_.set_synchronous_mode(true);
3137 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3138 "");
rch9ecde09b2017-04-08 00:18:233139
3140 CreateSession();
3141 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553142 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233143 QuicStreamFactoryPeer::SetAlarmFactory(
3144 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193145 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553146 &clock_));
rch9ecde09b2017-04-08 00:18:233147
Ryan Hamilton9835e662018-08-02 05:36:273148 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233149
3150 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3151 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363152 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3154
3155 // Pump the message loop to get the request started.
3156 base::RunLoop().RunUntilIdle();
3157 // Explicitly confirm the handshake.
3158 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523159 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233160
3161 // Run the QUIC session to completion.
3162 quic_task_runner_->RunUntilIdle();
3163 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3164
3165 // Let the transaction proceed which will result in QUIC being marked
3166 // as broken and the request falling back to TCP.
3167 EXPECT_THAT(callback.WaitForResult(), IsOk());
3168
3169 ExpectBrokenAlternateProtocolMapping();
3170 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3171 ASSERT_FALSE(http_data.AllReadDataConsumed());
3172
3173 // Read the response body over TCP.
3174 CheckResponseData(&trans, "hello world");
3175 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3176 ASSERT_TRUE(http_data.AllReadDataConsumed());
3177}
3178
rch2f2991c2017-04-13 19:28:173179// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3180// connection times out, then QUIC will be marked as broken and the request
3181// retried over TCP.
3182TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413183 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173184
3185 // The request will initially go out over QUIC.
3186 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523187 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133188 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173189 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3190
3191 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523192 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3193 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433194 quic_data.AddWrite(SYNCHRONOUS,
3195 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333196 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3197 true, priority, GetRequestHeaders("GET", "https", "/"),
3198 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173199
3200 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523201 quic::QuicStreamOffset settings_offset = header_stream_offset;
3202 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433203 quic_data.AddWrite(SYNCHRONOUS,
3204 client_maker_.MakeInitialSettingsPacketAndSaveData(
3205 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173206 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093207 quic_data.AddWrite(SYNCHRONOUS,
3208 client_maker_.MakeDataPacket(
3209 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3210 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173211 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093212 quic_data.AddWrite(SYNCHRONOUS,
3213 client_maker_.MakeDataPacket(
3214 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3215 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173216 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093217 quic_data.AddWrite(SYNCHRONOUS,
3218 client_maker_.MakeDataPacket(
3219 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3220 false, 0, request_data));
3221 quic_data.AddWrite(SYNCHRONOUS,
3222 client_maker_.MakeDataPacket(
3223 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3224 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173225 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093226 quic_data.AddWrite(SYNCHRONOUS,
3227 client_maker_.MakeDataPacket(
3228 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3229 false, 0, request_data));
3230 quic_data.AddWrite(SYNCHRONOUS,
3231 client_maker_.MakeDataPacket(
3232 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3233 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173234 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093235 quic_data.AddWrite(SYNCHRONOUS,
3236 client_maker_.MakeDataPacket(
3237 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3238 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523239 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093240 SYNCHRONOUS, client_maker_.MakeDataPacket(
3241 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3242 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173243
Zhongyi Shi32f2fd02018-04-16 18:23:433244 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523245 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433246 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223247
rch2f2991c2017-04-13 19:28:173248 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3249 quic_data.AddRead(ASYNC, OK);
3250 quic_data.AddSocketDataToFactory(&socket_factory_);
3251
3252 // After that fails, it will be resent via TCP.
3253 MockWrite http_writes[] = {
3254 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3255 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3256 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3257
3258 MockRead http_reads[] = {
3259 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3260 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3261 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013262 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173263 socket_factory_.AddSocketDataProvider(&http_data);
3264 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3265
3266 // In order for a new QUIC session to be established via alternate-protocol
3267 // without racing an HTTP connection, we need the host resolution to happen
3268 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3269 // connection to the the server, in this test we require confirmation
3270 // before encrypting so the HTTP job will still start.
3271 host_resolver_.set_synchronous_mode(true);
3272 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3273 "");
rch2f2991c2017-04-13 19:28:173274
3275 CreateSession();
3276 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553277 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173278 QuicStreamFactoryPeer::SetAlarmFactory(
3279 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193280 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553281 &clock_));
rch2f2991c2017-04-13 19:28:173282
Ryan Hamilton9835e662018-08-02 05:36:273283 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173284
3285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3286 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363287 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3289
3290 // Pump the message loop to get the request started.
3291 base::RunLoop().RunUntilIdle();
3292 // Explicitly confirm the handshake.
3293 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523294 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173295
3296 // Run the QUIC session to completion.
3297 quic_task_runner_->RunUntilIdle();
3298 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3299
3300 ExpectQuicAlternateProtocolMapping();
3301
3302 // Let the transaction proceed which will result in QUIC being marked
3303 // as broken and the request falling back to TCP.
3304 EXPECT_THAT(callback.WaitForResult(), IsOk());
3305
3306 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3307 ASSERT_FALSE(http_data.AllReadDataConsumed());
3308
3309 // Read the response body over TCP.
3310 CheckResponseData(&trans, "hello world");
3311 ExpectBrokenAlternateProtocolMapping();
3312 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3313 ASSERT_TRUE(http_data.AllReadDataConsumed());
3314}
3315
rch9ecde09b2017-04-08 00:18:233316// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3317// connection times out, then QUIC will be marked as broken but the request
3318// will not be retried over TCP.
3319TEST_P(QuicNetworkTransactionTest,
3320 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413321 session_params_.mark_quic_broken_when_network_blackholes = true;
3322 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233323
3324 // The request will initially go out over QUIC.
3325 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523326 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133327 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233328 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3329
3330 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523331 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3332 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433333 quic_data.AddWrite(SYNCHRONOUS,
3334 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333335 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3336 true, priority, GetRequestHeaders("GET", "https", "/"),
3337 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233338
3339 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523340 quic::QuicStreamOffset settings_offset = header_stream_offset;
3341 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433342 quic_data.AddWrite(SYNCHRONOUS,
3343 client_maker_.MakeInitialSettingsPacketAndSaveData(
3344 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233345
Zhongyi Shi32f2fd02018-04-16 18:23:433346 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333347 1, GetNthClientInitiatedBidirectionalStreamId(0),
3348 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433349 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523350 quic_data.AddWrite(
3351 SYNCHRONOUS,
3352 ConstructClientAckPacket(3, 1, 1, 1,
3353 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233354
3355 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523356 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093357 SYNCHRONOUS, client_maker_.MakeDataPacket(
3358 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3359 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233360 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093361 quic_data.AddWrite(
3362 SYNCHRONOUS, client_maker_.MakeDataPacket(
3363 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3364 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233365 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523366 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093367 SYNCHRONOUS, client_maker_.MakeDataPacket(
3368 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3369 false, 0, request_data));
3370 quic_data.AddWrite(
3371 SYNCHRONOUS, client_maker_.MakeDataPacket(
3372 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3373 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233374 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523375 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093376 SYNCHRONOUS, client_maker_.MakeDataPacket(
3377 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3378 false, 0, request_data));
3379 quic_data.AddWrite(
3380 SYNCHRONOUS, client_maker_.MakeDataPacket(
3381 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3382 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233383 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523384 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093385 SYNCHRONOUS, client_maker_.MakeDataPacket(
3386 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3387 false, 0, request_data));
3388 quic_data.AddWrite(
3389 SYNCHRONOUS, client_maker_.MakeDataPacket(
3390 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3391 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233392
Michael Warres112212822018-12-26 17:51:063393 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183394 quic_fix_time_of_first_packet_sent_after_receiving)) {
3395 quic_data.AddWrite(
3396 SYNCHRONOUS,
3397 client_maker_.MakeAckAndConnectionClosePacket(
3398 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3399 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3400
3401 } else {
3402 quic_data.AddWrite(
3403 SYNCHRONOUS,
3404 client_maker_.MakeAckAndConnectionClosePacket(
3405 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3406 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3407 }
Fan Yang928f1632017-12-14 18:55:223408
rch9ecde09b2017-04-08 00:18:233409 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3410 quic_data.AddRead(ASYNC, OK);
3411 quic_data.AddSocketDataToFactory(&socket_factory_);
3412
3413 // In order for a new QUIC session to be established via alternate-protocol
3414 // without racing an HTTP connection, we need the host resolution to happen
3415 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3416 // connection to the the server, in this test we require confirmation
3417 // before encrypting so the HTTP job will still start.
3418 host_resolver_.set_synchronous_mode(true);
3419 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3420 "");
rch9ecde09b2017-04-08 00:18:233421
3422 CreateSession();
3423 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553424 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233425 QuicStreamFactoryPeer::SetAlarmFactory(
3426 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193427 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553428 &clock_));
rch9ecde09b2017-04-08 00:18:233429
Ryan Hamilton9835e662018-08-02 05:36:273430 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233431
3432 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3433 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363434 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3436
3437 // Pump the message loop to get the request started.
3438 base::RunLoop().RunUntilIdle();
3439 // Explicitly confirm the handshake.
3440 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523441 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233442
3443 // Pump the message loop to get the request started.
3444 base::RunLoop().RunUntilIdle();
3445
3446 // Run the QUIC session to completion.
3447 quic_task_runner_->RunUntilIdle();
3448 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3449
3450 // Let the transaction proceed which will result in QUIC being marked
3451 // as broken and the request falling back to TCP.
3452 EXPECT_THAT(callback.WaitForResult(), IsOk());
3453
3454 ExpectBrokenAlternateProtocolMapping();
3455 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3456
3457 std::string response_data;
3458 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3459 IsError(ERR_QUIC_PROTOCOL_ERROR));
3460}
3461
3462// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3463// connection RTOs, then QUIC will be marked as broken and the request retried
3464// over TCP.
3465TEST_P(QuicNetworkTransactionTest,
3466 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413467 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523468 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233469
3470 // The request will initially go out over QUIC.
3471 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523472 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133473 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233474 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3475
3476 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523477 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3478 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433479 quic_data.AddWrite(SYNCHRONOUS,
3480 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333481 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3482 true, priority, GetRequestHeaders("GET", "https", "/"),
3483 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233484
3485 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523486 quic::QuicStreamOffset settings_offset = header_stream_offset;
3487 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433488 quic_data.AddWrite(SYNCHRONOUS,
3489 client_maker_.MakeInitialSettingsPacketAndSaveData(
3490 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233491 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093492 quic_data.AddWrite(SYNCHRONOUS,
3493 client_maker_.MakeDataPacket(
3494 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3495 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233496 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093497 quic_data.AddWrite(SYNCHRONOUS,
3498 client_maker_.MakeDataPacket(
3499 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3500 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233501 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093502 quic_data.AddWrite(SYNCHRONOUS,
3503 client_maker_.MakeDataPacket(
3504 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3505 false, 0, request_data));
3506 quic_data.AddWrite(SYNCHRONOUS,
3507 client_maker_.MakeDataPacket(
3508 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3509 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233510 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093511 quic_data.AddWrite(SYNCHRONOUS,
3512 client_maker_.MakeDataPacket(
3513 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3514 false, 0, request_data));
3515 quic_data.AddWrite(SYNCHRONOUS,
3516 client_maker_.MakeDataPacket(
3517 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3518 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233519 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093520 quic_data.AddWrite(SYNCHRONOUS,
3521 client_maker_.MakeDataPacket(
3522 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3523 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523524 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093525 SYNCHRONOUS, client_maker_.MakeDataPacket(
3526 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3527 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233528 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523529 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093530 SYNCHRONOUS, client_maker_.MakeDataPacket(
3531 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3532 false, 0, request_data));
3533 quic_data.AddWrite(
3534 SYNCHRONOUS, client_maker_.MakeDataPacket(
3535 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3536 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233537
Zhongyi Shi32f2fd02018-04-16 18:23:433538 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523539 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433540 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233541
3542 quic_data.AddRead(ASYNC, OK);
3543 quic_data.AddSocketDataToFactory(&socket_factory_);
3544
3545 // After that fails, it will be resent via TCP.
3546 MockWrite http_writes[] = {
3547 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3548 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3549 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3550
3551 MockRead http_reads[] = {
3552 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3553 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3554 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013555 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233556 socket_factory_.AddSocketDataProvider(&http_data);
3557 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3558
3559 // In order for a new QUIC session to be established via alternate-protocol
3560 // without racing an HTTP connection, we need the host resolution to happen
3561 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3562 // connection to the the server, in this test we require confirmation
3563 // before encrypting so the HTTP job will still start.
3564 host_resolver_.set_synchronous_mode(true);
3565 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3566 "");
rch9ecde09b2017-04-08 00:18:233567
3568 CreateSession();
3569 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553570 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233571 QuicStreamFactoryPeer::SetAlarmFactory(
3572 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193573 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553574 &clock_));
rch9ecde09b2017-04-08 00:18:233575
Ryan Hamilton9835e662018-08-02 05:36:273576 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233577
3578 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3579 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363580 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3582
3583 // Pump the message loop to get the request started.
3584 base::RunLoop().RunUntilIdle();
3585 // Explicitly confirm the handshake.
3586 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523587 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233588
3589 // Run the QUIC session to completion.
3590 quic_task_runner_->RunUntilIdle();
3591 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3592
3593 // Let the transaction proceed which will result in QUIC being marked
3594 // as broken and the request falling back to TCP.
3595 EXPECT_THAT(callback.WaitForResult(), IsOk());
3596
3597 ExpectBrokenAlternateProtocolMapping();
3598 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3599 ASSERT_FALSE(http_data.AllReadDataConsumed());
3600
3601 // Read the response body over TCP.
3602 CheckResponseData(&trans, "hello world");
3603 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3604 ASSERT_TRUE(http_data.AllReadDataConsumed());
3605}
3606
3607// Verify that if a QUIC connection RTOs, while there are no active streams
3608// QUIC will be marked as broken.
3609TEST_P(QuicNetworkTransactionTest,
3610 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413611 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523612 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233613
3614 // The request will initially go out over QUIC.
3615 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523616 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133617 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233618 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3619
3620 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523621 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3622 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433623 quic_data.AddWrite(SYNCHRONOUS,
3624 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333625 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3626 true, priority, GetRequestHeaders("GET", "https", "/"),
3627 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233628
3629 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523630 quic::QuicStreamOffset settings_offset = header_stream_offset;
3631 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433632 quic_data.AddWrite(SYNCHRONOUS,
3633 client_maker_.MakeInitialSettingsPacketAndSaveData(
3634 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233635
Fan Yang32c5a112018-12-10 20:06:333636 quic_data.AddWrite(SYNCHRONOUS,
3637 client_maker_.MakeRstPacket(
3638 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3639 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233640 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093641 quic_data.AddWrite(SYNCHRONOUS,
3642 client_maker_.MakeDataPacket(
3643 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3644 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233645 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093646 quic_data.AddWrite(SYNCHRONOUS,
3647 client_maker_.MakeDataPacket(
3648 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3649 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233650 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333651 quic_data.AddWrite(SYNCHRONOUS,
3652 client_maker_.MakeRstPacket(
3653 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3654 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093655 quic_data.AddWrite(SYNCHRONOUS,
3656 client_maker_.MakeDataPacket(
3657 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3658 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233659 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093660 quic_data.AddWrite(SYNCHRONOUS,
3661 client_maker_.MakeDataPacket(
3662 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3663 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333664 quic_data.AddWrite(SYNCHRONOUS,
3665 client_maker_.MakeRstPacket(
3666 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3667 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233668 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523669 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093670 SYNCHRONOUS, client_maker_.MakeDataPacket(
3671 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3672 false, 0, request_data));
3673 quic_data.AddWrite(
3674 SYNCHRONOUS, client_maker_.MakeDataPacket(
3675 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3676 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233677 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433678 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333679 SYNCHRONOUS, client_maker_.MakeRstPacket(
3680 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3681 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523682 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093683 SYNCHRONOUS, client_maker_.MakeDataPacket(
3684 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3685 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233686 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433687 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523688 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433689 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233690
3691 quic_data.AddRead(ASYNC, OK);
3692 quic_data.AddSocketDataToFactory(&socket_factory_);
3693
3694 // In order for a new QUIC session to be established via alternate-protocol
3695 // without racing an HTTP connection, we need the host resolution to happen
3696 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3697 // connection to the the server, in this test we require confirmation
3698 // before encrypting so the HTTP job will still start.
3699 host_resolver_.set_synchronous_mode(true);
3700 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3701 "");
rch9ecde09b2017-04-08 00:18:233702
3703 CreateSession();
3704 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553705 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233706 QuicStreamFactoryPeer::SetAlarmFactory(
3707 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193708 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553709 &clock_));
rch9ecde09b2017-04-08 00:18:233710
Ryan Hamilton9835e662018-08-02 05:36:273711 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233712
Jeremy Roman0579ed62017-08-29 15:56:193713 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233714 session_.get());
3715 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363716 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3718
3719 // Pump the message loop to get the request started.
3720 base::RunLoop().RunUntilIdle();
3721 // Explicitly confirm the handshake.
3722 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523723 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233724
3725 // Now cancel the request.
3726 trans.reset();
3727
3728 // Run the QUIC session to completion.
3729 quic_task_runner_->RunUntilIdle();
3730
3731 ExpectBrokenAlternateProtocolMapping();
3732
3733 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3734}
3735
rch2f2991c2017-04-13 19:28:173736// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3737// protocol error occurs after the handshake is confirmed, the request
3738// retried over TCP and the QUIC will be marked as broken.
3739TEST_P(QuicNetworkTransactionTest,
3740 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413741 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173742
3743 // The request will initially go out over QUIC.
3744 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523745 quic::QuicStreamOffset header_stream_offset = 0;
3746 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3747 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433748 quic_data.AddWrite(
3749 SYNCHRONOUS,
3750 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333751 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433752 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523753 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433754 quic_data.AddWrite(SYNCHRONOUS,
3755 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173756 // Peer sending data from an non-existing stream causes this end to raise
3757 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333758 quic_data.AddRead(
3759 ASYNC, ConstructServerRstPacket(
3760 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3761 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173762 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433763 quic_data.AddWrite(SYNCHRONOUS,
3764 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523765 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3766 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173767 quic_data.AddSocketDataToFactory(&socket_factory_);
3768
3769 // After that fails, it will be resent via TCP.
3770 MockWrite http_writes[] = {
3771 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3772 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3773 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3774
3775 MockRead http_reads[] = {
3776 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3777 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3778 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013779 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173780 socket_factory_.AddSocketDataProvider(&http_data);
3781 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3782
3783 // In order for a new QUIC session to be established via alternate-protocol
3784 // without racing an HTTP connection, we need the host resolution to happen
3785 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3786 // connection to the the server, in this test we require confirmation
3787 // before encrypting so the HTTP job will still start.
3788 host_resolver_.set_synchronous_mode(true);
3789 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3790 "");
rch2f2991c2017-04-13 19:28:173791
3792 CreateSession();
3793
Ryan Hamilton9835e662018-08-02 05:36:273794 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173795
3796 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3797 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363798 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3800
3801 // Pump the message loop to get the request started.
3802 base::RunLoop().RunUntilIdle();
3803 // Explicitly confirm the handshake.
3804 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523805 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173806
3807 // Run the QUIC session to completion.
3808 base::RunLoop().RunUntilIdle();
3809 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3810
3811 ExpectQuicAlternateProtocolMapping();
3812
3813 // Let the transaction proceed which will result in QUIC being marked
3814 // as broken and the request falling back to TCP.
3815 EXPECT_THAT(callback.WaitForResult(), IsOk());
3816
3817 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3818 ASSERT_FALSE(http_data.AllReadDataConsumed());
3819
3820 // Read the response body over TCP.
3821 CheckResponseData(&trans, "hello world");
3822 ExpectBrokenAlternateProtocolMapping();
3823 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3824 ASSERT_TRUE(http_data.AllReadDataConsumed());
3825}
3826
rch30943ee2017-06-12 21:28:443827// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3828// request is reset from, then QUIC will be marked as broken and the request
3829// retried over TCP.
3830TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443831 // The request will initially go out over QUIC.
3832 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523833 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133834 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443835 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3836
3837 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523838 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3839 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433840 quic_data.AddWrite(SYNCHRONOUS,
3841 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333842 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3843 true, priority, GetRequestHeaders("GET", "https", "/"),
3844 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443845
3846 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523847 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3848 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433849 quic_data.AddWrite(SYNCHRONOUS,
3850 client_maker_.MakeInitialSettingsPacketAndSaveData(
3851 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443852
Fan Yang32c5a112018-12-10 20:06:333853 quic_data.AddRead(ASYNC,
3854 ConstructServerRstPacket(
3855 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3856 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443857
3858 quic_data.AddRead(ASYNC, OK);
3859 quic_data.AddSocketDataToFactory(&socket_factory_);
3860
3861 // After that fails, it will be resent via TCP.
3862 MockWrite http_writes[] = {
3863 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3864 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3865 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3866
3867 MockRead http_reads[] = {
3868 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3869 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3870 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013871 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443872 socket_factory_.AddSocketDataProvider(&http_data);
3873 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3874
3875 // In order for a new QUIC session to be established via alternate-protocol
3876 // without racing an HTTP connection, we need the host resolution to happen
3877 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3878 // connection to the the server, in this test we require confirmation
3879 // before encrypting so the HTTP job will still start.
3880 host_resolver_.set_synchronous_mode(true);
3881 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3882 "");
rch30943ee2017-06-12 21:28:443883
3884 CreateSession();
3885
Ryan Hamilton9835e662018-08-02 05:36:273886 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443887
3888 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3889 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363890 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3892
3893 // Pump the message loop to get the request started.
3894 base::RunLoop().RunUntilIdle();
3895 // Explicitly confirm the handshake.
3896 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523897 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443898
3899 // Run the QUIC session to completion.
3900 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3901
3902 ExpectQuicAlternateProtocolMapping();
3903
3904 // Let the transaction proceed which will result in QUIC being marked
3905 // as broken and the request falling back to TCP.
3906 EXPECT_THAT(callback.WaitForResult(), IsOk());
3907
3908 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3909 ASSERT_FALSE(http_data.AllReadDataConsumed());
3910
3911 // Read the response body over TCP.
3912 CheckResponseData(&trans, "hello world");
3913 ExpectBrokenAlternateProtocolMapping();
3914 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3915 ASSERT_TRUE(http_data.AllReadDataConsumed());
3916}
3917
Ryan Hamilton6c2a2a82017-12-15 02:06:283918// Verify that when an origin has two alt-svc advertisements, one local and one
3919// remote, that when the local is broken the request will go over QUIC via
3920// the remote Alt-Svc.
3921// This is a regression test for crbug/825646.
3922TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3923 session_params_.quic_allow_remote_alt_svc = true;
3924
3925 GURL origin1 = request_.url; // mail.example.org
3926 GURL origin2("https://www.example.org/");
3927 ASSERT_NE(origin1.host(), origin2.host());
3928
3929 scoped_refptr<X509Certificate> cert(
3930 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243931 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3932 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283933
3934 ProofVerifyDetailsChromium verify_details;
3935 verify_details.cert_verify_result.verified_cert = cert;
3936 verify_details.cert_verify_result.is_issued_by_known_root = true;
3937 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3938
3939 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523940 quic::QuicStreamOffset request_header_offset(0);
3941 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283942 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433943 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3944 mock_quic_data.AddWrite(
3945 SYNCHRONOUS,
3946 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333947 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433948 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3949 mock_quic_data.AddRead(
3950 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333951 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433952 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:413953 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433954 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333955 ASYNC, ConstructServerDataPacket(
3956 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:413957 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433958 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283959 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3960 mock_quic_data.AddRead(ASYNC, 0); // EOF
3961
3962 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3963 MockQuicData mock_quic_data2;
3964 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3965 AddHangingNonAlternateProtocolSocketData();
3966
3967 CreateSession();
3968
3969 // Set up alternative service for |origin1|.
3970 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3971 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3972 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3973 AlternativeServiceInfoVector alternative_services;
3974 alternative_services.push_back(
3975 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3976 local_alternative, expiration,
3977 session_->params().quic_supported_versions));
3978 alternative_services.push_back(
3979 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3980 remote_alternative, expiration,
3981 session_->params().quic_supported_versions));
3982 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3983 alternative_services);
3984
3985 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3986
3987 SendRequestAndExpectQuicResponse("hello!");
3988}
3989
rch30943ee2017-06-12 21:28:443990// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3991// request is reset from, then QUIC will be marked as broken and the request
3992// retried over TCP. Then, subsequent requests will go over a new QUIC
3993// connection instead of going back to the broken QUIC connection.
3994// This is a regression tests for crbug/731303.
3995TEST_P(QuicNetworkTransactionTest,
3996 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:343997 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443998
3999 GURL origin1 = request_.url;
4000 GURL origin2("https://www.example.org/");
4001 ASSERT_NE(origin1.host(), origin2.host());
4002
4003 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524004 quic::QuicStreamOffset request_header_offset(0);
4005 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444006
4007 scoped_refptr<X509Certificate> cert(
4008 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244009 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4010 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444011
4012 ProofVerifyDetailsChromium verify_details;
4013 verify_details.cert_verify_result.verified_cert = cert;
4014 verify_details.cert_verify_result.is_issued_by_known_root = true;
4015 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4016
4017 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434018 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444019 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434020 mock_quic_data.AddWrite(
4021 SYNCHRONOUS,
4022 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334023 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434024 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4025 mock_quic_data.AddRead(
4026 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334027 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434028 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414029 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434030 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334031 ASYNC, ConstructServerDataPacket(
4032 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414033 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434034 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444035
4036 // Second request will go over the pooled QUIC connection, but will be
4037 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054038 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174039 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4040 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054041 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174042 QuicTestPacketMaker server_maker2(
4043 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4044 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434045 mock_quic_data.AddWrite(
4046 SYNCHRONOUS,
4047 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334048 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434049 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334050 GetNthClientInitiatedBidirectionalStreamId(0),
4051 &request_header_offset));
4052 mock_quic_data.AddRead(
4053 ASYNC, ConstructServerRstPacket(
4054 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4055 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444056 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4057 mock_quic_data.AddRead(ASYNC, 0); // EOF
4058
4059 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4060
4061 // After that fails, it will be resent via TCP.
4062 MockWrite http_writes[] = {
4063 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4064 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4065 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4066
4067 MockRead http_reads[] = {
4068 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4069 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4070 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014071 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444072 socket_factory_.AddSocketDataProvider(&http_data);
4073 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4074
Ryan Hamilton6c2a2a82017-12-15 02:06:284075 // Then the next request to the second origin will be sent over TCP.
4076 socket_factory_.AddSocketDataProvider(&http_data);
4077 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444078
4079 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564080 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4081 QuicStreamFactoryPeer::SetAlarmFactory(
4082 session_->quic_stream_factory(),
4083 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4084 &clock_));
rch30943ee2017-06-12 21:28:444085
4086 // Set up alternative service for |origin1|.
4087 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244088 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214089 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244090 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444091 supported_versions_);
rch30943ee2017-06-12 21:28:444092
4093 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244094 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214095 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244096 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444097 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344098
rch30943ee2017-06-12 21:28:444099 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524100 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444101 SendRequestAndExpectQuicResponse("hello!");
4102
4103 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524104 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444105 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4106 request_.url = origin2;
4107 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284108 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244109 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284110 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244111 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444112
4113 // The third request should use a new QUIC connection, not the broken
4114 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284115 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444116}
4117
bnc8be55ebb2015-10-30 14:12:074118TEST_P(QuicNetworkTransactionTest,
4119 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4120 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444121 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074122 MockRead http_reads[] = {
4123 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4124 MockRead("hello world"),
4125 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4126 MockRead(ASYNC, OK)};
4127
Ryan Sleevib8d7ea02018-05-07 20:01:014128 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074129 socket_factory_.AddSocketDataProvider(&http_data);
4130 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4131 socket_factory_.AddSocketDataProvider(&http_data);
4132 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4133
rch3f4b8452016-02-23 16:59:324134 CreateSession();
bnc8be55ebb2015-10-30 14:12:074135
4136 SendRequestAndExpectHttpResponse("hello world");
4137 SendRequestAndExpectHttpResponse("hello world");
4138}
4139
Xida Chen9bfe0b62018-04-24 19:52:214140// When multiple alternative services are advertised, HttpStreamFactory should
4141// select the alternative service which uses existing QUIC session if available.
4142// If no existing QUIC session can be used, use the first alternative service
4143// from the list.
zhongyi32569c62016-01-08 02:54:304144TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344145 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524146 MockRead http_reads[] = {
4147 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294148 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524149 MockRead("hello world"),
4150 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4151 MockRead(ASYNC, OK)};
4152
Ryan Sleevib8d7ea02018-05-07 20:01:014153 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524154 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084155 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564156 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524157
Ryan Hamilton8d9ee76e2018-05-29 23:52:524158 quic::QuicStreamOffset request_header_offset = 0;
4159 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304160 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294161 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304162 // alternative service list.
bncc958faa2015-07-31 18:14:524163 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364164 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434165 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4166 mock_quic_data.AddWrite(
4167 SYNCHRONOUS,
4168 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334169 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434170 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304171
4172 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294173 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4174 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434175 mock_quic_data.AddRead(
4176 ASYNC,
4177 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334178 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434179 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414180 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434181 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334182 ASYNC, ConstructServerDataPacket(
4183 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414184 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434185 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304186
4187 // Second QUIC request data.
4188 // Connection pooling, using existing session, no need to include version
4189 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584190 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334191 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4192 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4193 true, GetRequestHeaders("GET", "https", "/"),
4194 GetNthClientInitiatedBidirectionalStreamId(0),
4195 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434196 mock_quic_data.AddRead(
4197 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334198 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434199 GetResponseHeaders("200 OK"), &response_header_offset));
4200 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334201 ASYNC, ConstructServerDataPacket(
4202 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414203 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434204 mock_quic_data.AddWrite(
4205 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524206 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594207 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524208
4209 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4210
rtennetib8e80fb2016-05-16 00:12:094211 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324212 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564213 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4214 QuicStreamFactoryPeer::SetAlarmFactory(
4215 session_->quic_stream_factory(),
4216 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4217 &clock_));
bncc958faa2015-07-31 18:14:524218
4219 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304220
bnc359ed2a2016-04-29 20:43:454221 SendRequestAndExpectQuicResponse("hello!");
4222 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304223}
4224
tbansal6490783c2016-09-20 17:55:274225// Check that an existing QUIC connection to an alternative proxy server is
4226// used.
4227TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4228 base::HistogramTester histogram_tester;
4229
Ryan Hamilton8d9ee76e2018-05-29 23:52:524230 quic::QuicStreamOffset request_header_offset = 0;
4231 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274232 // First QUIC request data.
4233 // Open a session to foo.example.org:443 using the first entry of the
4234 // alternative service list.
4235 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364236 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434237 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4238 mock_quic_data.AddWrite(
4239 SYNCHRONOUS,
4240 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334241 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434242 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274243
4244 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434245 mock_quic_data.AddRead(
4246 ASYNC,
4247 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334248 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434249 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414250 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434251 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334252 ASYNC, ConstructServerDataPacket(
4253 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414254 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434255 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274256
4257 // Second QUIC request data.
4258 // Connection pooling, using existing session, no need to include version
4259 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274260 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334261 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4262 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4263 true, GetRequestHeaders("GET", "http", "/"),
4264 GetNthClientInitiatedBidirectionalStreamId(0),
4265 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434266 mock_quic_data.AddRead(
4267 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334268 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434269 GetResponseHeaders("200 OK"), &response_header_offset));
4270 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334271 ASYNC, ConstructServerDataPacket(
4272 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414273 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434274 mock_quic_data.AddWrite(
4275 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274276 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4277 mock_quic_data.AddRead(ASYNC, 0); // EOF
4278
4279 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4280
4281 AddHangingNonAlternateProtocolSocketData();
4282
4283 TestProxyDelegate test_proxy_delegate;
4284
Lily Houghton8c2f97d2018-01-22 05:06:594285 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494286 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274287
4288 test_proxy_delegate.set_alternative_proxy_server(
4289 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524290 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274291
4292 request_.url = GURL("http://mail.example.org/");
4293
4294 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564295 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4296 QuicStreamFactoryPeer::SetAlarmFactory(
4297 session_->quic_stream_factory(),
4298 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4299 &clock_));
tbansal6490783c2016-09-20 17:55:274300
4301 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4302 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4303 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4304 1);
4305
4306 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4307 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4308 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4309 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4310 1);
4311}
4312
Ryan Hamilton8d9ee76e2018-05-29 23:52:524313// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454314// even if alternative service destination is different.
4315TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344316 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304317 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524318 quic::QuicStreamOffset request_header_offset(0);
4319 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454320
rch5cb522462017-04-25 20:18:364321 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434322 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454323 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434324 mock_quic_data.AddWrite(
4325 SYNCHRONOUS,
4326 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334327 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434328 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4329 mock_quic_data.AddRead(
4330 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334331 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434332 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414333 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434334 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334335 ASYNC, ConstructServerDataPacket(
4336 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414337 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434338 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304339
bnc359ed2a2016-04-29 20:43:454340 // Second request.
alyssar2adf3ac2016-05-03 17:12:584341 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334342 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4343 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4344 true, GetRequestHeaders("GET", "https", "/"),
4345 GetNthClientInitiatedBidirectionalStreamId(0),
4346 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434347 mock_quic_data.AddRead(
4348 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334349 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434350 GetResponseHeaders("200 OK"), &response_header_offset));
4351 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334352 ASYNC, ConstructServerDataPacket(
4353 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414354 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434355 mock_quic_data.AddWrite(
4356 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304357 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4358 mock_quic_data.AddRead(ASYNC, 0); // EOF
4359
4360 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454361
4362 AddHangingNonAlternateProtocolSocketData();
4363 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304364
rch3f4b8452016-02-23 16:59:324365 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564366 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4367 QuicStreamFactoryPeer::SetAlarmFactory(
4368 session_->quic_stream_factory(),
4369 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4370 &clock_));
zhongyi32569c62016-01-08 02:54:304371
bnc359ed2a2016-04-29 20:43:454372 const char destination1[] = "first.example.com";
4373 const char destination2[] = "second.example.com";
4374
4375 // Set up alternative service entry to destination1.
4376 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214377 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454378 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214379 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444380 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454381 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524382 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454383 SendRequestAndExpectQuicResponse("hello!");
4384
4385 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214386 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214387 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444388 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524389 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454390 // even though alternative service destination is different.
4391 SendRequestAndExpectQuicResponse("hello!");
4392}
4393
4394// Pool to existing session with matching destination and matching certificate
4395// even if origin is different, and even if the alternative service with
4396// matching destination is not the first one on the list.
4397TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344398 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454399 GURL origin1 = request_.url;
4400 GURL origin2("https://www.example.org/");
4401 ASSERT_NE(origin1.host(), origin2.host());
4402
4403 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524404 quic::QuicStreamOffset request_header_offset(0);
4405 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454406
rch5cb522462017-04-25 20:18:364407 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434408 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454409 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434410 mock_quic_data.AddWrite(
4411 SYNCHRONOUS,
4412 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334413 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434414 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4415 mock_quic_data.AddRead(
4416 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334417 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434418 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414419 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434420 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334421 ASYNC, ConstructServerDataPacket(
4422 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414423 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434424 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454425
4426 // Second request.
Yixin Wang079ad542018-01-11 04:06:054427 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174428 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4429 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054430 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174431 QuicTestPacketMaker server_maker2(
4432 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4433 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584434 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434435 SYNCHRONOUS,
4436 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334437 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434438 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334439 GetNthClientInitiatedBidirectionalStreamId(0),
4440 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434441 mock_quic_data.AddRead(
4442 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334443 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434444 GetResponseHeaders("200 OK"), &response_header_offset));
4445 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334446 ASYNC, ConstructServerDataPacket(
4447 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414448 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434449 mock_quic_data.AddWrite(
4450 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454451 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4452 mock_quic_data.AddRead(ASYNC, 0); // EOF
4453
4454 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4455
4456 AddHangingNonAlternateProtocolSocketData();
4457 AddHangingNonAlternateProtocolSocketData();
4458
4459 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564460 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4461 QuicStreamFactoryPeer::SetAlarmFactory(
4462 session_->quic_stream_factory(),
4463 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4464 &clock_));
bnc359ed2a2016-04-29 20:43:454465
4466 const char destination1[] = "first.example.com";
4467 const char destination2[] = "second.example.com";
4468
4469 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214470 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454471 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214472 http_server_properties_.SetQuicAlternativeService(
4473 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444474 supported_versions_);
bnc359ed2a2016-04-29 20:43:454475
4476 // Set up multiple alternative service entries for |origin2|,
4477 // the first one with a different destination as for |origin1|,
4478 // the second one with the same. The second one should be used,
4479 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214480 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454481 AlternativeServiceInfoVector alternative_services;
4482 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214483 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4484 alternative_service2, expiration,
4485 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454486 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214487 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4488 alternative_service1, expiration,
4489 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454490 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4491 alternative_services);
bnc359ed2a2016-04-29 20:43:454492 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524493 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454494 SendRequestAndExpectQuicResponse("hello!");
4495
4496 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524497 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454498 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584499
bnc359ed2a2016-04-29 20:43:454500 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304501}
4502
4503// Multiple origins have listed the same alternative services. When there's a
4504// existing QUIC session opened by a request to other origin,
4505// if the cert is valid, should select this QUIC session to make the request
4506// if this is also the first existing QUIC session.
4507TEST_P(QuicNetworkTransactionTest,
4508 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344509 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294510 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304511
rch9ae5b3b2016-02-11 00:36:294512 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304513 MockRead http_reads[] = {
4514 MockRead("HTTP/1.1 200 OK\r\n"),
4515 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294516 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304517 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4518 MockRead(ASYNC, OK)};
4519
Ryan Sleevib8d7ea02018-05-07 20:01:014520 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304521 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084522 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304523 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4524
4525 // HTTP data for request to mail.example.org.
4526 MockRead http_reads2[] = {
4527 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294528 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304529 MockRead("hello world from mail.example.org"),
4530 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4531 MockRead(ASYNC, OK)};
4532
Ryan Sleevib8d7ea02018-05-07 20:01:014533 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304534 socket_factory_.AddSocketDataProvider(&http_data2);
4535 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4536
Ryan Hamilton8d9ee76e2018-05-29 23:52:524537 quic::QuicStreamOffset request_header_offset = 0;
4538 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304539
Yixin Wang079ad542018-01-11 04:06:054540 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174541 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4542 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054543 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584544 server_maker_.set_hostname("www.example.org");
4545 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304546 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364547 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434548 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304549 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584550 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434551 SYNCHRONOUS,
4552 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334553 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434554 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4555
4556 mock_quic_data.AddRead(
4557 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334558 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434559 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414560 quic::QuicString header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334561 mock_quic_data.AddRead(
4562 ASYNC, ConstructServerDataPacket(
4563 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414564 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434565 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4566 // Second QUIC request data.
4567 mock_quic_data.AddWrite(
4568 SYNCHRONOUS,
4569 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334570 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434571 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334572 GetNthClientInitiatedBidirectionalStreamId(0),
4573 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434574 mock_quic_data.AddRead(
4575 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334576 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434577 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334578 mock_quic_data.AddRead(
4579 ASYNC, ConstructServerDataPacket(
4580 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414581 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434582 mock_quic_data.AddWrite(
4583 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304584 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4585 mock_quic_data.AddRead(ASYNC, 0); // EOF
4586
4587 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304588
rtennetib8e80fb2016-05-16 00:12:094589 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324590 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564591 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4592 QuicStreamFactoryPeer::SetAlarmFactory(
4593 session_->quic_stream_factory(),
4594 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4595 &clock_));
zhongyi32569c62016-01-08 02:54:304596
4597 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294598 request_.url = GURL("https://www.example.org/");
4599 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304600 request_.url = GURL("https://mail.example.org/");
4601 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4602
rch9ae5b3b2016-02-11 00:36:294603 // Open a QUIC session to mail.example.org:443 when making request
4604 // to mail.example.org.
4605 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454606 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304607
rch9ae5b3b2016-02-11 00:36:294608 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304609 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454610 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524611}
4612
4613TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524614 MockRead http_reads[] = {
4615 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564616 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524617 MockRead("hello world"),
4618 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4619 MockRead(ASYNC, OK)};
4620
Ryan Sleevib8d7ea02018-05-07 20:01:014621 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524622 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084623 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564624 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524625
rtennetib8e80fb2016-05-16 00:12:094626 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324627 CreateSession();
bncc958faa2015-07-31 18:14:524628
4629 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454630
4631 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344632 AlternativeServiceInfoVector alternative_service_info_vector =
4633 http_server_properties_.GetAlternativeServiceInfos(http_server);
4634 ASSERT_EQ(1u, alternative_service_info_vector.size());
4635 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544636 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344637 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4638 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4639 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524640}
4641
4642TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524643 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564644 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4645 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524646 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4647 MockRead(ASYNC, OK)};
4648
Ryan Sleevib8d7ea02018-05-07 20:01:014649 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524650 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084651 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564652 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524653
4654 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524655 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364656 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434657 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4658 mock_quic_data.AddWrite(
4659 SYNCHRONOUS,
4660 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334661 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434662 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434663 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334664 ASYNC, ConstructServerResponseHeadersPacket(
4665 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4666 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414667 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334668 mock_quic_data.AddRead(
4669 ASYNC, ConstructServerDataPacket(
4670 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414671 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434672 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524673 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4674 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524675
4676 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4677
rtennetib8e80fb2016-05-16 00:12:094678 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324679 CreateSession();
bncc958faa2015-07-31 18:14:524680
bnc3472afd2016-11-17 15:27:214681 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524682 HostPortPair::FromURL(request_.url));
4683 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4684 alternative_service);
4685 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4686 alternative_service));
4687
4688 SendRequestAndExpectHttpResponse("hello world");
4689 SendRequestAndExpectQuicResponse("hello!");
4690
mmenkee24011922015-12-17 22:12:594691 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524692
4693 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4694 alternative_service));
rchac7f35e2017-03-15 20:42:304695 EXPECT_NE(nullptr,
4696 http_server_properties_.GetServerNetworkStats(
4697 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524698}
4699
bncc958faa2015-07-31 18:14:524700TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524701 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564702 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4703 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524704 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4705 MockRead(ASYNC, OK)};
4706
Ryan Sleevib8d7ea02018-05-07 20:01:014707 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524708 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564709 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524710
4711 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524712 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364713 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434714 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4715 mock_quic_data.AddWrite(
4716 SYNCHRONOUS,
4717 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334718 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434719 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434720 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334721 ASYNC, ConstructServerResponseHeadersPacket(
4722 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4723 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414724 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334725 mock_quic_data.AddRead(
4726 ASYNC, ConstructServerDataPacket(
4727 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414728 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434729 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524730 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4731
4732 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4733
4734 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324735 CreateSession();
bncc958faa2015-07-31 18:14:524736
4737 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4738 SendRequestAndExpectHttpResponse("hello world");
4739}
4740
tbansalc3308d72016-08-27 10:25:044741// Tests that the connection to an HTTPS proxy is raced with an available
4742// alternative proxy server.
4743TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274744 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594745 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494746 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044747
4748 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524749 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364750 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434751 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4752 mock_quic_data.AddWrite(
4753 SYNCHRONOUS,
4754 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334755 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434756 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434757 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334758 ASYNC, ConstructServerResponseHeadersPacket(
4759 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4760 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414761 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334762 mock_quic_data.AddRead(
4763 ASYNC, ConstructServerDataPacket(
4764 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414765 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434766 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044767 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4768 mock_quic_data.AddRead(ASYNC, 0); // EOF
4769
4770 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4771
4772 // There is no need to set up main job, because no attempt will be made to
4773 // speak to the proxy over TCP.
4774 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044775 TestProxyDelegate test_proxy_delegate;
4776 const HostPortPair host_port_pair("mail.example.org", 443);
4777
4778 test_proxy_delegate.set_alternative_proxy_server(
4779 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524780 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044781 CreateSession();
4782 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4783
4784 // The main job needs to hang in order to guarantee that the alternative
4785 // proxy server job will "win".
4786 AddHangingNonAlternateProtocolSocketData();
4787
4788 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4789
4790 // Verify that the alternative proxy server is not marked as broken.
4791 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4792
4793 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594794 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274795
4796 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4797 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4798 1);
tbansalc3308d72016-08-27 10:25:044799}
4800
bnc1c196c6e2016-05-28 13:51:484801TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304802 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274803 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304804
4805 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564806 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294807 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564808 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304809
4810 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564811 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484812 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564813 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304814
Ryan Sleevib8d7ea02018-05-07 20:01:014815 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504816 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084817 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504818 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304819
4820 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454821 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304822 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454823 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304824 };
Ryan Sleevib8d7ea02018-05-07 20:01:014825 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504826 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304827
4828 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014829 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504830 socket_factory_.AddSocketDataProvider(&http_data2);
4831 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304832
bnc912a04b2016-04-20 14:19:504833 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304834
4835 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304836 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174837 ASSERT_TRUE(http_data.AllReadDataConsumed());
4838 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304839
4840 // Now run the second request in which the QUIC socket hangs,
4841 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304842 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454843 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304844
rch37de576c2015-05-17 20:28:174845 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4846 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454847 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304848}
4849
[email protected]1e960032013-12-20 19:00:204850TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204851 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524852 quic::QuicStreamOffset header_stream_offset = 0;
4853 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4854 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434855 mock_quic_data.AddWrite(
4856 SYNCHRONOUS,
4857 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334858 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434859 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434860 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334861 ASYNC, ConstructServerResponseHeadersPacket(
4862 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4863 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414864 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334865 mock_quic_data.AddRead(
4866 ASYNC, ConstructServerDataPacket(
4867 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414868 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434869 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504870 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594871 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484872
rcha5399e02015-04-21 19:32:044873 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484874
rtennetib8e80fb2016-05-16 00:12:094875 // The non-alternate protocol job needs to hang in order to guarantee that
4876 // the alternate-protocol job will "win".
4877 AddHangingNonAlternateProtocolSocketData();
4878
rch3f4b8452016-02-23 16:59:324879 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274880 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194881 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304882
4883 EXPECT_EQ(nullptr,
4884 http_server_properties_.GetServerNetworkStats(
4885 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484886}
4887
[email protected]1e960032013-12-20 19:00:204888TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204889 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524890 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4891 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334892 mock_quic_data.AddWrite(
4893 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4894 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4895 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434896 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334897 ASYNC, ConstructServerResponseHeadersPacket(
4898 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4899 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414900 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334901 mock_quic_data.AddRead(
4902 ASYNC, ConstructServerDataPacket(
4903 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414904 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434905 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504906 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594907 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044908 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274909
4910 // In order for a new QUIC session to be established via alternate-protocol
4911 // without racing an HTTP connection, we need the host resolution to happen
4912 // synchronously.
4913 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294914 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564915 "");
[email protected]3a120a6b2013-06-25 01:08:274916
rtennetib8e80fb2016-05-16 00:12:094917 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324918 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274919 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274920 SendRequestAndExpectQuicResponse("hello!");
4921}
4922
[email protected]0fc924b2014-03-31 04:34:154923TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494924 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4925 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154926
4927 // Since we are using a proxy, the QUIC job will not succeed.
4928 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294929 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4930 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564931 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154932
4933 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564934 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484935 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564936 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154937
Ryan Sleevib8d7ea02018-05-07 20:01:014938 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154939 socket_factory_.AddSocketDataProvider(&http_data);
4940
4941 // In order for a new QUIC session to be established via alternate-protocol
4942 // without racing an HTTP connection, we need the host resolution to happen
4943 // synchronously.
4944 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294945 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564946 "");
[email protected]0fc924b2014-03-31 04:34:154947
rch9ae5b3b2016-02-11 00:36:294948 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324949 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274950 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154951 SendRequestAndExpectHttpResponse("hello world");
4952}
4953
[email protected]1e960032013-12-20 19:00:204954TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[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;
rch5cb522462017-04-25 20:18:364957 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434958 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4959 mock_quic_data.AddWrite(
4960 SYNCHRONOUS,
4961 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334962 2, 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(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594974 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044975 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124976
rtennetib8e80fb2016-05-16 00:12:094977 // The non-alternate protocol job needs to hang in order to guarantee that
4978 // the alternate-protocol job will "win".
4979 AddHangingNonAlternateProtocolSocketData();
4980
[email protected]11c05872013-08-20 02:04:124981 // In order for a new QUIC session to be established via alternate-protocol
4982 // without racing an HTTP connection, we need the host resolution to happen
4983 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4984 // connection to the the server, in this test we require confirmation
4985 // before encrypting so the HTTP job will still start.
4986 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294987 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564988 "");
[email protected]11c05872013-08-20 02:04:124989
rch3f4b8452016-02-23 16:59:324990 CreateSession();
[email protected]11c05872013-08-20 02:04:124991 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274992 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124993
bnc691fda62016-08-12 00:43:164994 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124995 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364996 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124998
4999 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525000 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015001 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505002
bnc691fda62016-08-12 00:43:165003 CheckWasQuicResponse(&trans);
5004 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125005}
5006
Steven Valdez58097ec32018-07-16 18:29:045007TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5008 MockQuicData mock_quic_data;
5009 quic::QuicStreamOffset client_header_stream_offset = 0;
5010 quic::QuicStreamOffset server_header_stream_offset = 0;
5011 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5012 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045013 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335014 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5015 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5016 true, GetRequestHeaders("GET", "https", "/"),
5017 &client_header_stream_offset));
5018 mock_quic_data.AddRead(
5019 ASYNC,
5020 ConstructServerResponseHeadersPacket(
5021 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5022 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5023 mock_quic_data.AddWrite(SYNCHRONOUS,
5024 ConstructClientAckAndRstPacket(
5025 2, GetNthClientInitiatedBidirectionalStreamId(0),
5026 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045027
5028 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5029
5030 spdy::SpdySettingsIR settings_frame;
5031 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5032 quic::kDefaultMaxUncompressedHeaderSize);
5033 spdy::SpdySerializedFrame spdy_frame(
5034 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5035 mock_quic_data.AddWrite(
5036 SYNCHRONOUS,
5037 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385038 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5039 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045040 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5041 client_header_stream_offset += spdy_frame.size();
5042
5043 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335044 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5045 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5046 true, GetRequestHeaders("GET", "https", "/"),
5047 GetNthClientInitiatedBidirectionalStreamId(0),
5048 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045049 mock_quic_data.AddRead(
5050 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335051 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045052 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:415053 quic::QuicString header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045054 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335055 ASYNC, ConstructServerDataPacket(
5056 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415057 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045058 mock_quic_data.AddWrite(
5059 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5060 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5061 mock_quic_data.AddRead(ASYNC, 0); // EOF
5062
5063 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5064
5065 // In order for a new QUIC session to be established via alternate-protocol
5066 // without racing an HTTP connection, we need the host resolution to happen
5067 // synchronously.
5068 host_resolver_.set_synchronous_mode(true);
5069 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5070 "");
Steven Valdez58097ec32018-07-16 18:29:045071
5072 AddHangingNonAlternateProtocolSocketData();
5073 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275074 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565075 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5076 QuicStreamFactoryPeer::SetAlarmFactory(
5077 session_->quic_stream_factory(),
5078 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5079 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045080
5081 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5082 TestCompletionCallback callback;
5083 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5085
5086 // Confirm the handshake after the 425 Too Early.
5087 base::RunLoop().RunUntilIdle();
5088
5089 // The handshake hasn't been confirmed yet, so the retry should not have
5090 // succeeded.
5091 EXPECT_FALSE(callback.have_result());
5092
5093 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5094 quic::QuicSession::HANDSHAKE_CONFIRMED);
5095
5096 EXPECT_THAT(callback.WaitForResult(), IsOk());
5097 CheckWasQuicResponse(&trans);
5098 CheckResponseData(&trans, "hello!");
5099}
5100
5101TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5102 MockQuicData mock_quic_data;
5103 quic::QuicStreamOffset client_header_stream_offset = 0;
5104 quic::QuicStreamOffset server_header_stream_offset = 0;
5105 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5106 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045107 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335108 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5109 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5110 true, GetRequestHeaders("GET", "https", "/"),
5111 &client_header_stream_offset));
5112 mock_quic_data.AddRead(
5113 ASYNC,
5114 ConstructServerResponseHeadersPacket(
5115 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5116 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5117 mock_quic_data.AddWrite(SYNCHRONOUS,
5118 ConstructClientAckAndRstPacket(
5119 2, GetNthClientInitiatedBidirectionalStreamId(0),
5120 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045121
5122 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5123
5124 spdy::SpdySettingsIR settings_frame;
5125 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5126 quic::kDefaultMaxUncompressedHeaderSize);
5127 spdy::SpdySerializedFrame spdy_frame(
5128 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5129 mock_quic_data.AddWrite(
5130 SYNCHRONOUS,
5131 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385132 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5133 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045134 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5135 client_header_stream_offset += spdy_frame.size();
5136
5137 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335138 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5139 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5140 true, GetRequestHeaders("GET", "https", "/"),
5141 GetNthClientInitiatedBidirectionalStreamId(0),
5142 &client_header_stream_offset));
5143 mock_quic_data.AddRead(
5144 ASYNC,
5145 ConstructServerResponseHeadersPacket(
5146 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5147 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5148 mock_quic_data.AddWrite(SYNCHRONOUS,
5149 ConstructClientAckAndRstPacket(
5150 5, GetNthClientInitiatedBidirectionalStreamId(1),
5151 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045152 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5153 mock_quic_data.AddRead(ASYNC, 0); // EOF
5154
5155 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5156
5157 // In order for a new QUIC session to be established via alternate-protocol
5158 // without racing an HTTP connection, we need the host resolution to happen
5159 // synchronously.
5160 host_resolver_.set_synchronous_mode(true);
5161 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5162 "");
Steven Valdez58097ec32018-07-16 18:29:045163
5164 AddHangingNonAlternateProtocolSocketData();
5165 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275166 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565167 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5168 QuicStreamFactoryPeer::SetAlarmFactory(
5169 session_->quic_stream_factory(),
5170 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5171 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045172
5173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5174 TestCompletionCallback callback;
5175 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5177
5178 // Confirm the handshake after the 425 Too Early.
5179 base::RunLoop().RunUntilIdle();
5180
5181 // The handshake hasn't been confirmed yet, so the retry should not have
5182 // succeeded.
5183 EXPECT_FALSE(callback.have_result());
5184
5185 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5186 quic::QuicSession::HANDSHAKE_CONFIRMED);
5187
5188 EXPECT_THAT(callback.WaitForResult(), IsOk());
5189 const HttpResponseInfo* response = trans.GetResponseInfo();
5190 ASSERT_TRUE(response != nullptr);
5191 ASSERT_TRUE(response->headers.get() != nullptr);
5192 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5193 EXPECT_TRUE(response->was_fetched_via_spdy);
5194 EXPECT_TRUE(response->was_alpn_negotiated);
5195 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5196 response->connection_info);
5197}
5198
zhongyica364fbb2015-12-12 03:39:125199TEST_P(QuicNetworkTransactionTest,
5200 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485201 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125202 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525203 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365204 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435205 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5206 mock_quic_data.AddWrite(
5207 SYNCHRONOUS,
5208 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335209 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435210 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125211 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525212 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435213 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125214 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5215
5216 // The non-alternate protocol job needs to hang in order to guarantee that
5217 // the alternate-protocol job will "win".
5218 AddHangingNonAlternateProtocolSocketData();
5219
5220 // In order for a new QUIC session to be established via alternate-protocol
5221 // without racing an HTTP connection, we need the host resolution to happen
5222 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5223 // connection to the the server, in this test we require confirmation
5224 // before encrypting so the HTTP job will still start.
5225 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295226 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125227 "");
zhongyica364fbb2015-12-12 03:39:125228
rch3f4b8452016-02-23 16:59:325229 CreateSession();
zhongyica364fbb2015-12-12 03:39:125230 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275231 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125232
bnc691fda62016-08-12 00:43:165233 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125234 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365235 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015236 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125237
5238 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525239 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015240 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125241
5242 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525243 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125244
bnc691fda62016-08-12 00:43:165245 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125246 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525247 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5248 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125249}
5250
5251TEST_P(QuicNetworkTransactionTest,
5252 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485253 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125254 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525255 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365256 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435257 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5258 mock_quic_data.AddWrite(
5259 SYNCHRONOUS,
5260 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335261 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435262 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215263 // Peer sending data from an non-existing stream causes this end to raise
5264 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335265 mock_quic_data.AddRead(
5266 ASYNC, ConstructServerRstPacket(
5267 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5268 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215269 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525270 mock_quic_data.AddWrite(
5271 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5272 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5273 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125274 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5275
5276 // The non-alternate protocol job needs to hang in order to guarantee that
5277 // the alternate-protocol job will "win".
5278 AddHangingNonAlternateProtocolSocketData();
5279
5280 // In order for a new QUIC session to be established via alternate-protocol
5281 // without racing an HTTP connection, we need the host resolution to happen
5282 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5283 // connection to the the server, in this test we require confirmation
5284 // before encrypting so the HTTP job will still start.
5285 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295286 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125287 "");
zhongyica364fbb2015-12-12 03:39:125288
rch3f4b8452016-02-23 16:59:325289 CreateSession();
zhongyica364fbb2015-12-12 03:39:125290 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275291 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125292
bnc691fda62016-08-12 00:43:165293 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125294 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365295 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015296 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125297
5298 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525299 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015300 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125301 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525302 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125303
bnc691fda62016-08-12 00:43:165304 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525305 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125306}
5307
rchcd5f1c62016-06-23 02:43:485308TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5309 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525310 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365311 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435312 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5313 mock_quic_data.AddWrite(
5314 SYNCHRONOUS,
5315 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335316 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435317 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485318 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335319 mock_quic_data.AddRead(
5320 ASYNC, ConstructServerResponseHeadersPacket(
5321 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5322 GetResponseHeaders("200 OK")));
5323 mock_quic_data.AddRead(
5324 ASYNC, ConstructServerRstPacket(
5325 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5326 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435327 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485328 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5329 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5330
5331 // The non-alternate protocol job needs to hang in order to guarantee that
5332 // the alternate-protocol job will "win".
5333 AddHangingNonAlternateProtocolSocketData();
5334
5335 // In order for a new QUIC session to be established via alternate-protocol
5336 // without racing an HTTP connection, we need the host resolution to happen
5337 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5338 // connection to the the server, in this test we require confirmation
5339 // before encrypting so the HTTP job will still start.
5340 host_resolver_.set_synchronous_mode(true);
5341 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5342 "");
rchcd5f1c62016-06-23 02:43:485343
5344 CreateSession();
5345 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275346 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485347
bnc691fda62016-08-12 00:43:165348 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485349 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365350 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485352
5353 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525354 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485355 // Read the headers.
robpercival214763f2016-07-01 23:27:015356 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485357
bnc691fda62016-08-12 00:43:165358 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485359 ASSERT_TRUE(response != nullptr);
5360 ASSERT_TRUE(response->headers.get() != nullptr);
5361 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5362 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525363 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445364 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5365 response->connection_info);
rchcd5f1c62016-06-23 02:43:485366
5367 std::string response_data;
bnc691fda62016-08-12 00:43:165368 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485369}
5370
5371TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485372 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485373 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525374 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365375 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435376 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5377 mock_quic_data.AddWrite(
5378 SYNCHRONOUS,
5379 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335380 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435381 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335382 mock_quic_data.AddRead(
5383 ASYNC, ConstructServerRstPacket(
5384 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5385 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485386 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5387 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5388
5389 // The non-alternate protocol job needs to hang in order to guarantee that
5390 // the alternate-protocol job will "win".
5391 AddHangingNonAlternateProtocolSocketData();
5392
5393 // In order for a new QUIC session to be established via alternate-protocol
5394 // without racing an HTTP connection, we need the host resolution to happen
5395 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5396 // connection to the the server, in this test we require confirmation
5397 // before encrypting so the HTTP job will still start.
5398 host_resolver_.set_synchronous_mode(true);
5399 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5400 "");
rchcd5f1c62016-06-23 02:43:485401
5402 CreateSession();
5403 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275404 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485405
bnc691fda62016-08-12 00:43:165406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485407 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365408 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485410
5411 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525412 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485413 // Read the headers.
robpercival214763f2016-07-01 23:27:015414 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485415}
5416
[email protected]1e960032013-12-20 19:00:205417TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305418 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525419 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585420 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305421 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505422 MockRead(ASYNC, close->data(), close->length()),
5423 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5424 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305425 };
Ryan Sleevib8d7ea02018-05-07 20:01:015426 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305427 socket_factory_.AddSocketDataProvider(&quic_data);
5428
5429 // Main job which will succeed even though the alternate job fails.
5430 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025431 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5432 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5433 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305434
Ryan Sleevib8d7ea02018-05-07 20:01:015435 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305436 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565437 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305438
rch3f4b8452016-02-23 16:59:325439 CreateSession();
David Schinazic8281052019-01-24 06:14:175440 AddQuicAlternateProtocolMapping(
5441 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195442 SendRequestAndExpectHttpResponse("hello from http");
5443 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305444}
5445
[email protected]1e960032013-12-20 19:00:205446TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595447 // Alternate-protocol job
5448 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025449 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595450 };
Ryan Sleevib8d7ea02018-05-07 20:01:015451 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595452 socket_factory_.AddSocketDataProvider(&quic_data);
5453
5454 // Main job which will succeed even though the alternate job fails.
5455 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025456 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5457 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5458 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595459
Ryan Sleevib8d7ea02018-05-07 20:01:015460 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595461 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565462 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595463
rch3f4b8452016-02-23 16:59:325464 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595465
Ryan Hamilton9835e662018-08-02 05:36:275466 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195467 SendRequestAndExpectHttpResponse("hello from http");
5468 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595469}
5470
[email protected]00c159f2014-05-21 22:38:165471TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535472 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165473 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025474 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165475 };
Ryan Sleevib8d7ea02018-05-07 20:01:015476 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165477 socket_factory_.AddSocketDataProvider(&quic_data);
5478
[email protected]eb71ab62014-05-23 07:57:535479 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165480 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025481 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165482 };
5483
Ryan Sleevib8d7ea02018-05-07 20:01:015484 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165485 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5486 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565487 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165488
rtennetib8e80fb2016-05-16 00:12:095489 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325490 CreateSession();
[email protected]00c159f2014-05-21 22:38:165491
Ryan Hamilton9835e662018-08-02 05:36:275492 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165494 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165495 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015496 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5497 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165498 ExpectQuicAlternateProtocolMapping();
5499}
5500
Zhongyi Shia0cef1082017-08-25 01:49:505501TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5502 // Tests that TCP job is delayed and QUIC job does not require confirmation
5503 // if QUIC was recently supported on the same IP on start.
5504
5505 // Set QUIC support on the last IP address, which is same with the local IP
5506 // address. Require confirmation mode will be turned off immediately when
5507 // local IP address is sorted out after we configure the UDP socket.
5508 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5509
5510 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525511 quic::QuicStreamOffset header_stream_offset = 0;
5512 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5513 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435514 mock_quic_data.AddWrite(
5515 SYNCHRONOUS,
5516 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335517 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435518 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435519 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335520 ASYNC, ConstructServerResponseHeadersPacket(
5521 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5522 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415523 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335524 mock_quic_data.AddRead(
5525 ASYNC, ConstructServerDataPacket(
5526 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415527 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435528 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505529 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5530 mock_quic_data.AddRead(ASYNC, 0); // EOF
5531
5532 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5533 // No HTTP data is mocked as TCP job never starts in this case.
5534
5535 CreateSession();
5536 // QuicStreamFactory by default requires confirmation on construction.
5537 session_->quic_stream_factory()->set_require_confirmation(true);
5538
Ryan Hamilton9835e662018-08-02 05:36:275539 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505540
5541 // Stall host resolution so that QUIC job will not succeed synchronously.
5542 // Socket will not be configured immediately and QUIC support is not sorted
5543 // out, TCP job will still be delayed as server properties indicates QUIC
5544 // support on last IP address.
5545 host_resolver_.set_synchronous_mode(false);
5546
5547 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5548 TestCompletionCallback callback;
5549 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5550 IsError(ERR_IO_PENDING));
5551 // Complete host resolution in next message loop so that QUIC job could
5552 // proceed.
5553 base::RunLoop().RunUntilIdle();
5554 EXPECT_THAT(callback.WaitForResult(), IsOk());
5555
5556 CheckWasQuicResponse(&trans);
5557 CheckResponseData(&trans, "hello!");
5558}
5559
5560TEST_P(QuicNetworkTransactionTest,
5561 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5562 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5563 // was recently supported on a different IP address on start.
5564
5565 // Set QUIC support on the last IP address, which is different with the local
5566 // IP address. Require confirmation mode will remain when local IP address is
5567 // sorted out after we configure the UDP socket.
5568 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5569
5570 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525571 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505572 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435573 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5574 mock_quic_data.AddWrite(
5575 SYNCHRONOUS,
5576 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335577 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435578 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435579 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335580 ASYNC, ConstructServerResponseHeadersPacket(
5581 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5582 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415583 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335584 mock_quic_data.AddRead(
5585 ASYNC, ConstructServerDataPacket(
5586 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415587 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435588 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505589 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5590 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5591 // No HTTP data is mocked as TCP job will be delayed and never starts.
5592
5593 CreateSession();
5594 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275595 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505596
5597 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5598 // Socket will not be configured immediately and QUIC support is not sorted
5599 // out, TCP job will still be delayed as server properties indicates QUIC
5600 // support on last IP address.
5601 host_resolver_.set_synchronous_mode(false);
5602
5603 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5604 TestCompletionCallback callback;
5605 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5606 IsError(ERR_IO_PENDING));
5607
5608 // Complete host resolution in next message loop so that QUIC job could
5609 // proceed.
5610 base::RunLoop().RunUntilIdle();
5611 // Explicitly confirm the handshake so that QUIC job could succeed.
5612 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525613 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505614 EXPECT_THAT(callback.WaitForResult(), IsOk());
5615
5616 CheckWasQuicResponse(&trans);
5617 CheckResponseData(&trans, "hello!");
5618}
5619
Ryan Hamilton75f197262017-08-17 14:00:075620TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5621 // Test that NetErrorDetails is correctly populated, even if the
5622 // handshake has not yet been confirmed and no stream has been created.
5623
5624 // QUIC job will pause. When resumed, it will fail.
5625 MockQuicData mock_quic_data;
5626 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5627 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5628 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5629
5630 // Main job will also fail.
5631 MockRead http_reads[] = {
5632 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5633 };
5634
Ryan Sleevib8d7ea02018-05-07 20:01:015635 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075636 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5637 socket_factory_.AddSocketDataProvider(&http_data);
5638 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5639
5640 AddHangingNonAlternateProtocolSocketData();
5641 CreateSession();
5642 // Require handshake confirmation to ensure that no QUIC streams are
5643 // created, and to ensure that the TCP job does not wait for the QUIC
5644 // job to fail before it starts.
5645 session_->quic_stream_factory()->set_require_confirmation(true);
5646
Ryan Hamilton9835e662018-08-02 05:36:275647 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075648 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5649 TestCompletionCallback callback;
5650 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5652 // Allow the TCP job to fail.
5653 base::RunLoop().RunUntilIdle();
5654 // Now let the QUIC job fail.
5655 mock_quic_data.Resume();
5656 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5657 ExpectQuicAlternateProtocolMapping();
5658 NetErrorDetails details;
5659 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525660 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075661}
5662
[email protected]1e960032013-12-20 19:00:205663TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455664 // Alternate-protocol job
5665 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025666 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455667 };
Ryan Sleevib8d7ea02018-05-07 20:01:015668 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455669 socket_factory_.AddSocketDataProvider(&quic_data);
5670
[email protected]c92c1b52014-05-31 04:16:065671 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015672 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065673 socket_factory_.AddSocketDataProvider(&quic_data2);
5674
[email protected]4d283b32013-10-17 12:57:275675 // Final job that will proceed when the QUIC job fails.
5676 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025677 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5678 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5679 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275680
Ryan Sleevib8d7ea02018-05-07 20:01:015681 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275682 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565683 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275684
rtennetiafccbc062016-05-16 18:21:145685 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325686 CreateSession();
[email protected]77c6c162013-08-17 02:57:455687
Ryan Hamilton9835e662018-08-02 05:36:275688 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455689
[email protected]4d283b32013-10-17 12:57:275690 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455691
5692 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275693
rch37de576c2015-05-17 20:28:175694 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5695 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455696}
5697
[email protected]93b31772014-06-19 08:03:355698TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035699 // Alternate-protocol job
5700 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595701 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035702 };
Ryan Sleevib8d7ea02018-05-07 20:01:015703 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035704 socket_factory_.AddSocketDataProvider(&quic_data);
5705
5706 // Main job that will proceed when the QUIC job fails.
5707 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025708 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5709 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5710 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035711
Ryan Sleevib8d7ea02018-05-07 20:01:015712 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035713 socket_factory_.AddSocketDataProvider(&http_data);
5714
rtennetib8e80fb2016-05-16 00:12:095715 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325716 CreateSession();
[email protected]65768442014-06-06 23:37:035717
Ryan Hamilton9835e662018-08-02 05:36:275718 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035719
5720 SendRequestAndExpectHttpResponse("hello from http");
5721}
5722
[email protected]eb71ab62014-05-23 07:57:535723TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335724 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015725 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495726 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335727 socket_factory_.AddSocketDataProvider(&quic_data);
5728
5729 // Main job which will succeed even though the alternate job fails.
5730 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025731 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5732 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5733 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335734
Ryan Sleevib8d7ea02018-05-07 20:01:015735 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335736 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565737 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335738
rch3f4b8452016-02-23 16:59:325739 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275740 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335741 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535742
5743 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335744}
5745
[email protected]4fee9672014-01-08 14:47:155746TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155747 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175748 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5749 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045750 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155751
5752 // When the QUIC connection fails, we will try the request again over HTTP.
5753 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485754 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565755 MockRead("hello world"),
5756 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5757 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155758
Ryan Sleevib8d7ea02018-05-07 20:01:015759 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155760 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565761 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155762
5763 // In order for a new QUIC session to be established via alternate-protocol
5764 // without racing an HTTP connection, we need the host resolution to happen
5765 // synchronously.
5766 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295767 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565768 "");
[email protected]4fee9672014-01-08 14:47:155769
rch3f4b8452016-02-23 16:59:325770 CreateSession();
David Schinazic8281052019-01-24 06:14:175771 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5772 AddQuicAlternateProtocolMapping(
5773 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155774 SendRequestAndExpectHttpResponse("hello world");
5775}
5776
tbansalc3308d72016-08-27 10:25:045777// For an alternative proxy that supports QUIC, test that the request is
5778// successfully fetched by the main job when the alternate proxy job encounters
5779// an error.
5780TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5781 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5782}
5783TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5784 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5785}
5786TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5787 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5788}
5789TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5790 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5791}
5792TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5793 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5794}
5795TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5796 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5797}
5798TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5799 TestAlternativeProxy(ERR_IO_PENDING);
5800}
5801TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5802 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5803}
5804
5805TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5806 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175807 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5808 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335809 mock_quic_data.AddWrite(
5810 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5811 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5812 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435813 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045814 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5815
5816 // When the QUIC connection fails, we will try the request again over HTTP.
5817 MockRead http_reads[] = {
5818 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5819 MockRead("hello world"),
5820 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5821 MockRead(ASYNC, OK)};
5822
Ryan Sleevib8d7ea02018-05-07 20:01:015823 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045824 socket_factory_.AddSocketDataProvider(&http_data);
5825 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5826
5827 TestProxyDelegate test_proxy_delegate;
5828 const HostPortPair host_port_pair("myproxy.org", 443);
5829 test_proxy_delegate.set_alternative_proxy_server(
5830 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5831 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5832
Ramin Halavatica8d5252018-03-12 05:33:495833 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5834 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525835 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045836 request_.url = GURL("http://mail.example.org/");
5837
5838 // In order for a new QUIC session to be established via alternate-protocol
5839 // without racing an HTTP connection, we need the host resolution to happen
5840 // synchronously.
5841 host_resolver_.set_synchronous_mode(true);
5842 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045843
5844 CreateSession();
David Schinazic8281052019-01-24 06:14:175845 crypto_client_stream_factory_.set_handshake_mode(
5846 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045847 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595848 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165849 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045850}
5851
bnc508835902015-05-12 20:10:295852TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585853 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385854 EXPECT_FALSE(
5855 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295856 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525857 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365858 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435859 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5860 mock_quic_data.AddWrite(
5861 SYNCHRONOUS,
5862 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335863 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435864 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435865 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335866 ASYNC, ConstructServerResponseHeadersPacket(
5867 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5868 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415869 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335870 mock_quic_data.AddRead(
5871 ASYNC, ConstructServerDataPacket(
5872 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415873 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435874 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505875 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295876 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5877
bncb07c05532015-05-14 19:07:205878 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095879 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325880 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275881 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295882 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385883 EXPECT_TRUE(
5884 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295885}
5886
zhongyi363c91c2017-03-23 23:16:085887// TODO(zhongyi): disabled this broken test as it was not testing the correct
5888// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5889TEST_P(QuicNetworkTransactionTest,
5890 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275891 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595892 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495893 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045894
5895 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045896
5897 test_proxy_delegate.set_alternative_proxy_server(
5898 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525899 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045900
5901 request_.url = GURL("http://mail.example.org/");
5902
5903 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5904 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015905 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045906 socket_factory_.AddSocketDataProvider(&socket_data);
5907
5908 // The non-alternate protocol job needs to hang in order to guarantee that
5909 // the alternate-protocol job will "win".
5910 AddHangingNonAlternateProtocolSocketData();
5911
5912 CreateSession();
5913 request_.method = "POST";
5914 ChunkedUploadDataStream upload_data(0);
5915 upload_data.AppendData("1", 1, true);
5916
5917 request_.upload_data_stream = &upload_data;
5918
5919 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5920 TestCompletionCallback callback;
5921 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5922 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5923 EXPECT_NE(OK, callback.WaitForResult());
5924
5925 // Verify that the alternative proxy server is not marked as broken.
5926 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5927
5928 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595929 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275930
5931 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5932 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5933 1);
tbansalc3308d72016-08-27 10:25:045934}
5935
rtenneti56977812016-01-15 19:26:565936TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415937 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575938 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565939
5940 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5941 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015942 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565943 socket_factory_.AddSocketDataProvider(&socket_data);
5944
rtennetib8e80fb2016-05-16 00:12:095945 // The non-alternate protocol job needs to hang in order to guarantee that
5946 // the alternate-protocol job will "win".
5947 AddHangingNonAlternateProtocolSocketData();
5948
rtenneti56977812016-01-15 19:26:565949 CreateSession();
5950 request_.method = "POST";
5951 ChunkedUploadDataStream upload_data(0);
5952 upload_data.AppendData("1", 1, true);
5953
5954 request_.upload_data_stream = &upload_data;
5955
bnc691fda62016-08-12 00:43:165956 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565957 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165958 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565960 EXPECT_NE(OK, callback.WaitForResult());
5961}
5962
rche11300ef2016-09-02 01:44:285963TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485964 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285965 ScopedMockNetworkChangeNotifier network_change_notifier;
5966 MockNetworkChangeNotifier* mock_ncn =
5967 network_change_notifier.mock_network_change_notifier();
5968 mock_ncn->ForceNetworkHandlesSupported();
5969 mock_ncn->SetConnectedNetworksList(
5970 {kDefaultNetworkForTests, kNewNetworkForTests});
5971
mmenke6ddfbea2017-05-31 21:48:415972 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285973 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315974 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285975
5976 MockQuicData socket_data;
5977 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525978 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435979 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:335980 socket_data.AddWrite(
5981 SYNCHRONOUS,
5982 ConstructClientRequestHeadersPacket(
5983 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
5984 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:285985 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5986 socket_data.AddSocketDataToFactory(&socket_factory_);
5987
5988 MockQuicData socket_data2;
5989 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5990 socket_data2.AddSocketDataToFactory(&socket_factory_);
5991
5992 // The non-alternate protocol job needs to hang in order to guarantee that
5993 // the alternate-protocol job will "win".
5994 AddHangingNonAlternateProtocolSocketData();
5995
5996 CreateSession();
5997 request_.method = "POST";
5998 ChunkedUploadDataStream upload_data(0);
5999
6000 request_.upload_data_stream = &upload_data;
6001
rdsmith1d343be52016-10-21 20:37:506002 std::unique_ptr<HttpNetworkTransaction> trans(
6003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286004 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506005 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286006 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6007
6008 base::RunLoop().RunUntilIdle();
6009 upload_data.AppendData("1", 1, true);
6010 base::RunLoop().RunUntilIdle();
6011
6012 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506013 trans.reset();
rche11300ef2016-09-02 01:44:286014 session_.reset();
6015}
6016
Ryan Hamilton4b3574532017-10-30 20:17:256017TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6018 session_params_.origins_to_force_quic_on.insert(
6019 HostPortPair::FromString("mail.example.org:443"));
6020
6021 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526022 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436023 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256024 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336025 socket_data.AddWrite(
6026 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6027 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6028 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436029 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336030 ASYNC, ConstructServerResponseHeadersPacket(
6031 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6032 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416033 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336034 socket_data.AddRead(
6035 ASYNC, ConstructServerDataPacket(
6036 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416037 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436038 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256039 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166040 socket_data.AddWrite(
6041 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6042 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6043 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256044
6045 socket_data.AddSocketDataToFactory(&socket_factory_);
6046
6047 CreateSession();
6048
6049 SendRequestAndExpectQuicResponse("hello!");
6050 session_.reset();
6051}
6052
6053TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6054 session_params_.origins_to_force_quic_on.insert(
6055 HostPortPair::FromString("mail.example.org:443"));
6056
6057 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526058 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436059 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256060 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336061 socket_data.AddWrite(
6062 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6063 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6064 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436065 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336066 ASYNC, ConstructServerResponseHeadersPacket(
6067 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6068 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416069 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336070 socket_data.AddRead(
6071 ASYNC, ConstructServerDataPacket(
6072 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416073 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436074 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256075 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166076 socket_data.AddWrite(
6077 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6078 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6079 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256080
6081 socket_data.AddSocketDataToFactory(&socket_factory_);
6082
6083 CreateSession();
6084
6085 SendRequestAndExpectQuicResponse("hello!");
6086 session_.reset();
6087}
6088
Ryan Hamilton9edcf1a2017-11-22 05:55:176089TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486090 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256091 session_params_.origins_to_force_quic_on.insert(
6092 HostPortPair::FromString("mail.example.org:443"));
6093
6094 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526095 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256096 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436097 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176098 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256099 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6100 }
6101 socket_data.AddSocketDataToFactory(&socket_factory_);
6102
6103 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176104 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6105 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6106 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6107 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256108
Ryan Hamilton8d9ee76e2018-05-29 23:52:526109 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256110 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6111 TestCompletionCallback callback;
6112 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176114 while (!callback.have_result()) {
6115 base::RunLoop().RunUntilIdle();
6116 quic_task_runner_->RunUntilIdle();
6117 }
6118 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256119 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176120 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6121 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6122 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526123 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6124 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256125}
6126
Ryan Hamilton9edcf1a2017-11-22 05:55:176127TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486128 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256129 session_params_.origins_to_force_quic_on.insert(
6130 HostPortPair::FromString("mail.example.org:443"));
6131
6132 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526133 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256134 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436135 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176136 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256137 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6138 }
6139 socket_data.AddSocketDataToFactory(&socket_factory_);
6140
6141 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176142 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6143 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6144 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6145 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256146
Ryan Hamilton8d9ee76e2018-05-29 23:52:526147 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256148 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6149 TestCompletionCallback callback;
6150 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6151 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176152 while (!callback.have_result()) {
6153 base::RunLoop().RunUntilIdle();
6154 quic_task_runner_->RunUntilIdle();
6155 }
6156 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256157 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176158 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6159 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6160 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526161 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6162 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256163}
6164
Cherie Shi7596de632018-02-22 07:28:186165TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486166 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186167 session_params_.origins_to_force_quic_on.insert(
6168 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526169 const quic::QuicString error_details =
6170 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6171 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186172
6173 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526174 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186175 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436176 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186177 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6178 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526179 socket_data.AddWrite(
6180 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6181 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186182 socket_data.AddSocketDataToFactory(&socket_factory_);
6183
6184 CreateSession();
6185
6186 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6187 TestCompletionCallback callback;
6188 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6190 base::RunLoop().RunUntilIdle();
6191 ASSERT_TRUE(callback.have_result());
6192 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6193 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6194 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6195}
6196
ckrasic769733c2016-06-30 00:42:136197// Adds coverage to catch regression such as https://crbug.com/622043
6198TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416199 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136200 HostPortPair::FromString("mail.example.org:443"));
6201
6202 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526203 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236204 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436205 mock_quic_data.AddWrite(
6206 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6207 &header_stream_offset));
6208 mock_quic_data.AddWrite(
6209 SYNCHRONOUS,
6210 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336211 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6212 true, true, GetRequestHeaders("GET", "https", "/"),
6213 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526214 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436215 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336216 ASYNC, ConstructServerPushPromisePacket(
6217 1, GetNthClientInitiatedBidirectionalStreamId(0),
6218 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6219 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6220 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576221 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266222 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336223 mock_quic_data.AddWrite(SYNCHRONOUS,
6224 ConstructClientPriorityPacket(
6225 client_packet_number++, false,
6226 GetNthServerInitiatedUnidirectionalStreamId(0),
6227 GetNthClientInitiatedBidirectionalStreamId(0),
6228 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576229 }
Zhongyi Shi32f2fd02018-04-16 18:23:436230 mock_quic_data.AddRead(
6231 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336232 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436233 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576234 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436235 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6236 mock_quic_data.AddRead(
6237 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336238 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6239 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416240 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436241 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336242 ASYNC, ConstructServerDataPacket(
6243 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416244 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576245 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436246 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416247 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436248 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336249 ASYNC, ConstructServerDataPacket(
6250 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416251 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336252 mock_quic_data.AddWrite(SYNCHRONOUS,
6253 ConstructClientAckAndRstPacket(
6254 client_packet_number++,
6255 GetNthServerInitiatedUnidirectionalStreamId(0),
6256 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136257 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6258 mock_quic_data.AddRead(ASYNC, 0); // EOF
6259 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6260
6261 // The non-alternate protocol job needs to hang in order to guarantee that
6262 // the alternate-protocol job will "win".
6263 AddHangingNonAlternateProtocolSocketData();
6264
6265 CreateSession();
6266
6267 // PUSH_PROMISE handling in the http layer gets exercised here.
6268 SendRequestAndExpectQuicResponse("hello!");
6269
6270 request_.url = GURL("https://mail.example.org/pushed.jpg");
6271 SendRequestAndExpectQuicResponse("and hello!");
6272
6273 // Check that the NetLog was filled reasonably.
6274 TestNetLogEntry::List entries;
6275 net_log_.GetEntries(&entries);
6276 EXPECT_LT(0u, entries.size());
6277
6278 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6279 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006280 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6281 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136282 EXPECT_LT(0, pos);
6283}
6284
rch56ec40a2017-06-23 14:48:446285// Regression test for http://crbug.com/719461 in which a promised stream
6286// is closed before the pushed headers arrive, but after the connection
6287// is closed and before the callbacks are executed.
6288TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486289 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446290 session_params_.origins_to_force_quic_on.insert(
6291 HostPortPair::FromString("mail.example.org:443"));
6292
6293 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526294 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236295 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446296 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436297 mock_quic_data.AddWrite(
6298 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6299 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446300 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436301 mock_quic_data.AddWrite(
6302 SYNCHRONOUS,
6303 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336304 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6305 true, true, GetRequestHeaders("GET", "https", "/"),
6306 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526307 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446308 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436309 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336310 ASYNC, ConstructServerPushPromisePacket(
6311 1, GetNthClientInitiatedBidirectionalStreamId(0),
6312 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6313 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6314 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576315 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266316 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336317 mock_quic_data.AddWrite(SYNCHRONOUS,
6318 ConstructClientPriorityPacket(
6319 client_packet_number++, false,
6320 GetNthServerInitiatedUnidirectionalStreamId(0),
6321 GetNthClientInitiatedBidirectionalStreamId(0),
6322 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576323 }
rch56ec40a2017-06-23 14:48:446324 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436325 mock_quic_data.AddRead(
6326 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336327 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436328 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446329 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576330 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436331 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446332 // Response body for first request.
Renjief49758b2019-01-11 23:32:416333 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436334 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336335 ASYNC, ConstructServerDataPacket(
6336 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416337 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446338 // Write error for the third request.
6339 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6340 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6341 mock_quic_data.AddRead(ASYNC, 0); // EOF
6342 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6343
6344 CreateSession();
6345
6346 // Send a request which triggers a push promise from the server.
6347 SendRequestAndExpectQuicResponse("hello!");
6348
6349 // Start a push transaction that will be cancelled after the connection
6350 // is closed, but before the callback is executed.
6351 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196352 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446353 session_.get());
6354 TestCompletionCallback callback2;
6355 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6356 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6357 base::RunLoop().RunUntilIdle();
6358
6359 // Cause the connection to close on a write error.
6360 HttpRequestInfo request3;
6361 request3.method = "GET";
6362 request3.url = GURL("https://mail.example.org/");
6363 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106364 request3.traffic_annotation =
6365 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446366 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6367 TestCompletionCallback callback3;
6368 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6369 IsError(ERR_IO_PENDING));
6370
6371 base::RunLoop().RunUntilIdle();
6372
6373 // When |trans2| is destroyed, the underlying stream will be closed.
6374 EXPECT_FALSE(callback2.have_result());
6375 trans2 = nullptr;
6376
6377 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6378}
6379
ckrasicda193a82016-07-09 00:39:366380TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416381 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366382 HostPortPair::FromString("mail.example.org:443"));
6383
6384 MockQuicData mock_quic_data;
6385
Ryan Hamilton8d9ee76e2018-05-29 23:52:526386 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416387 int write_packet_index = 1;
6388 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6389 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366390
Renjief49758b2019-01-11 23:32:416391 quic::QuicString header = ConstructDataHeader(1);
6392 if (version_ != quic::QUIC_VERSION_99) {
6393 mock_quic_data.AddWrite(
6394 SYNCHRONOUS,
6395 ConstructClientRequestHeadersAndDataFramesPacket(
6396 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6397 true, true, DEFAULT_PRIORITY,
6398 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6399 {"1"}));
6400 } else {
6401 mock_quic_data.AddWrite(
6402 SYNCHRONOUS,
6403 ConstructClientRequestHeadersAndDataFramesPacket(
6404 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6405 true, true, DEFAULT_PRIORITY,
6406 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6407 {header, "1"}));
6408 }
ckrasicda193a82016-07-09 00:39:366409
Zhongyi Shi32f2fd02018-04-16 18:23:436410 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336411 ASYNC, ConstructServerResponseHeadersPacket(
6412 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6413 GetResponseHeaders("200 OK")));
6414
Renjief49758b2019-01-11 23:32:416415 quic::QuicString header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336416 mock_quic_data.AddRead(
6417 ASYNC, ConstructServerDataPacket(
6418 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416419 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366420
Renjief49758b2019-01-11 23:32:416421 mock_quic_data.AddWrite(
6422 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366423
6424 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6425 mock_quic_data.AddRead(ASYNC, 0); // EOF
6426 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6427
6428 // The non-alternate protocol job needs to hang in order to guarantee that
6429 // the alternate-protocol job will "win".
6430 AddHangingNonAlternateProtocolSocketData();
6431
6432 CreateSession();
6433 request_.method = "POST";
6434 ChunkedUploadDataStream upload_data(0);
6435 upload_data.AppendData("1", 1, true);
6436
6437 request_.upload_data_stream = &upload_data;
6438
6439 SendRequestAndExpectQuicResponse("hello!");
6440}
6441
allada71b2efb2016-09-09 04:57:486442class QuicURLRequestContext : public URLRequestContext {
6443 public:
6444 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6445 MockClientSocketFactory* socket_factory)
6446 : storage_(this) {
6447 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076448 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046449 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486450 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046451 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596452 storage_.set_proxy_resolution_service(
6453 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076454 storage_.set_ssl_config_service(
6455 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486456 storage_.set_http_auth_handler_factory(
6457 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6458 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076459 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046460 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486461 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046462 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6463 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6464 false));
allada71b2efb2016-09-09 04:57:486465 }
6466
6467 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6468
6469 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6470
6471 private:
6472 MockClientSocketFactory* socket_factory_;
6473 URLRequestContextStorage storage_;
6474};
6475
6476TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416477 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486478 HostPortPair::FromString("mail.example.org:443"));
6479
6480 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526481 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366482 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436483 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136484 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486485 headers["user-agent"] = "";
6486 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336487 mock_quic_data.AddWrite(
6488 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6489 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6490 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486491
Ryan Hamilton8d9ee76e2018-05-29 23:52:526492 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336493 mock_quic_data.AddRead(
6494 ASYNC,
6495 ConstructServerResponseHeadersPacket(
6496 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6497 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486498
Renjief49758b2019-01-11 23:32:416499 quic::QuicString header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366500 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336501 ASYNC, ConstructServerDataPacket(
6502 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6503 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436504 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486505
6506 mock_quic_data.AddRead(ASYNC, 0); // EOF
6507
6508 CreateSession();
6509
6510 TestDelegate delegate;
6511 QuicURLRequestContext quic_url_request_context(std::move(session_),
6512 &socket_factory_);
6513
6514 mock_quic_data.AddSocketDataToFactory(
6515 &quic_url_request_context.socket_factory());
6516 TestNetworkDelegate network_delegate;
6517 quic_url_request_context.set_network_delegate(&network_delegate);
6518
6519 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296520 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6521 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486522 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6523 &ssl_data_);
6524
6525 request->Start();
Wez2a31b222018-06-07 22:07:156526 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486527
6528 EXPECT_LT(0, request->GetTotalSentBytes());
6529 EXPECT_LT(0, request->GetTotalReceivedBytes());
6530 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6531 request->GetTotalSentBytes());
6532 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6533 request->GetTotalReceivedBytes());
6534 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6535 request->raw_header_size());
Wez0e717112018-06-18 23:09:226536
6537 // Pump the message loop to allow all data to be consumed.
6538 base::RunLoop().RunUntilIdle();
6539
allada71b2efb2016-09-09 04:57:486540 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6541 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6542}
6543
6544TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416545 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486546 HostPortPair::FromString("mail.example.org:443"));
6547
6548 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526549 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236550 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436551 mock_quic_data.AddWrite(
6552 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6553 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136554 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486555 headers["user-agent"] = "";
6556 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436557 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336558 SYNCHRONOUS,
6559 ConstructClientRequestHeadersPacket(
6560 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6561 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486562
Ryan Hamilton8d9ee76e2018-05-29 23:52:526563 quic::QuicStreamOffset server_header_offset = 0;
6564 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486565
Zhongyi Shi32f2fd02018-04-16 18:23:436566 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336567 ASYNC, ConstructServerPushPromisePacket(
6568 1, GetNthClientInitiatedBidirectionalStreamId(0),
6569 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6570 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6571 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486572
Yixin Wangb470bc882018-02-15 18:43:576573 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266574 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336575 mock_quic_data.AddWrite(SYNCHRONOUS,
6576 ConstructClientPriorityPacket(
6577 client_packet_number++, false,
6578 GetNthServerInitiatedUnidirectionalStreamId(0),
6579 GetNthClientInitiatedBidirectionalStreamId(0),
6580 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576581 }
6582
allada71b2efb2016-09-09 04:57:486583 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436584 mock_quic_data.AddRead(
6585 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336586 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436587 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486588 expected_raw_header_response_size =
6589 server_header_offset - expected_raw_header_response_size;
6590
Yixin Wangb470bc882018-02-15 18:43:576591 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436592 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486593
ckrasicbf2f59c2017-05-04 23:54:366594 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436595 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336596 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6597 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416598 quic::QuicString header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436599 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336600 ASYNC, ConstructServerDataPacket(
6601 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416602 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486603
Yixin Wangb470bc882018-02-15 18:43:576604 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436605 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416606 quic::QuicString header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366607 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336608 ASYNC, ConstructServerDataPacket(
6609 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416610 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486611
Zhongyi Shi32f2fd02018-04-16 18:23:436612 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486613
6614 CreateSession();
6615
6616 TestDelegate delegate;
6617 QuicURLRequestContext quic_url_request_context(std::move(session_),
6618 &socket_factory_);
6619
6620 mock_quic_data.AddSocketDataToFactory(
6621 &quic_url_request_context.socket_factory());
6622 TestNetworkDelegate network_delegate;
6623 quic_url_request_context.set_network_delegate(&network_delegate);
6624
6625 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296626 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6627 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486628 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6629 &ssl_data_);
6630
6631 request->Start();
Wez2a31b222018-06-07 22:07:156632 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486633
6634 EXPECT_LT(0, request->GetTotalSentBytes());
6635 EXPECT_LT(0, request->GetTotalReceivedBytes());
6636 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6637 request->GetTotalSentBytes());
6638 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6639 request->GetTotalReceivedBytes());
6640 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6641 request->raw_header_size());
Wez0e717112018-06-18 23:09:226642
6643 // Pump the message loop to allow all data to be consumed.
6644 base::RunLoop().RunUntilIdle();
6645
allada71b2efb2016-09-09 04:57:486646 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6647 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6648}
6649
Yixin Wang10f477ed2017-11-21 04:20:206650TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6651 session_params_.quic_host_whitelist.insert("mail.example.org");
6652
6653 MockRead http_reads[] = {
6654 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6655 MockRead("hello world"),
6656 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6657 MockRead(ASYNC, OK)};
6658
Ryan Sleevib8d7ea02018-05-07 20:01:016659 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206660 socket_factory_.AddSocketDataProvider(&http_data);
6661 AddCertificate(&ssl_data_);
6662 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6663
6664 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526665 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206666 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436667 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6668 mock_quic_data.AddWrite(
6669 SYNCHRONOUS,
6670 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336671 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436672 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436673 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336674 ASYNC, ConstructServerResponseHeadersPacket(
6675 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6676 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416677 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336678 mock_quic_data.AddRead(
6679 ASYNC, ConstructServerDataPacket(
6680 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416681 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436682 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206683 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6684 mock_quic_data.AddRead(ASYNC, 0); // EOF
6685
6686 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6687
6688 AddHangingNonAlternateProtocolSocketData();
6689 CreateSession();
6690
6691 SendRequestAndExpectHttpResponse("hello world");
6692 SendRequestAndExpectQuicResponse("hello!");
6693}
6694
6695TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6696 session_params_.quic_host_whitelist.insert("mail.example.com");
6697
6698 MockRead http_reads[] = {
6699 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6700 MockRead("hello world"),
6701 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6702 MockRead(ASYNC, OK)};
6703
Ryan Sleevib8d7ea02018-05-07 20:01:016704 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206705 socket_factory_.AddSocketDataProvider(&http_data);
6706 AddCertificate(&ssl_data_);
6707 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6708 socket_factory_.AddSocketDataProvider(&http_data);
6709 AddCertificate(&ssl_data_);
6710 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6711
6712 AddHangingNonAlternateProtocolSocketData();
6713 CreateSession();
6714
6715 SendRequestAndExpectHttpResponse("hello world");
6716 SendRequestAndExpectHttpResponse("hello world");
6717}
6718
bnc359ed2a2016-04-29 20:43:456719class QuicNetworkTransactionWithDestinationTest
6720 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016721 public ::testing::WithParamInterface<PoolingTestParams>,
6722 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456723 protected:
6724 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556725 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056726 client_headers_include_h2_stream_dependency_(
6727 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526728 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456729 destination_type_(GetParam().destination_type),
6730 cert_transparency_verifier_(new MultiLogCTVerifier()),
6731 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596732 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456733 auth_handler_factory_(
6734 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6735 random_generator_(0),
6736 ssl_data_(ASYNC, OK) {}
6737
6738 void SetUp() override {
6739 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556740 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456741
mmenke6ddfbea2017-05-31 21:48:416742 HttpNetworkSession::Params session_params;
6743 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346744 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446745 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056746 session_params.quic_headers_include_h2_stream_dependency =
6747 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416748
6749 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456750
Ryan Hamilton8d9ee76e2018-05-29 23:52:526751 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416752 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456753
6754 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276755 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416756 session_context.quic_crypto_client_stream_factory =
6757 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456758
mmenke6ddfbea2017-05-31 21:48:416759 session_context.quic_random = &random_generator_;
6760 session_context.client_socket_factory = &socket_factory_;
6761 session_context.host_resolver = &host_resolver_;
6762 session_context.cert_verifier = &cert_verifier_;
6763 session_context.transport_security_state = &transport_security_state_;
6764 session_context.cert_transparency_verifier =
6765 cert_transparency_verifier_.get();
6766 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6767 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456768 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416769 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596770 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416771 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6772 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456773
mmenke6ddfbea2017-05-31 21:48:416774 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456775 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456776 }
6777
6778 void TearDown() override {
6779 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6780 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556781 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456782 PlatformTest::TearDown();
6783 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556784 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406785 session_.reset();
bnc359ed2a2016-04-29 20:43:456786 }
6787
zhongyie537a002017-06-27 16:48:216788 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456789 HostPortPair destination;
6790 switch (destination_type_) {
6791 case SAME_AS_FIRST:
6792 destination = HostPortPair(origin1_, 443);
6793 break;
6794 case SAME_AS_SECOND:
6795 destination = HostPortPair(origin2_, 443);
6796 break;
6797 case DIFFERENT:
6798 destination = HostPortPair(kDifferentHostname, 443);
6799 break;
6800 }
bnc3472afd2016-11-17 15:27:216801 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456802 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216803 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456804 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446805 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456806 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526807 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236808 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526809 quic::QuicStreamId stream_id,
6810 bool should_include_version,
6811 quic::QuicStreamOffset* offset,
6812 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486813 return ConstructClientRequestHeadersPacket(
6814 packet_number, stream_id, should_include_version, 0, offset, maker);
6815 }
bnc359ed2a2016-04-29 20:43:456816
Ryan Hamilton8d9ee76e2018-05-29 23:52:526817 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236818 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526819 quic::QuicStreamId stream_id,
6820 bool should_include_version,
6821 quic::QuicStreamId parent_stream_id,
6822 quic::QuicStreamOffset* offset,
6823 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136824 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456825 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136826 spdy::SpdyHeaderBlock headers(
6827 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456828 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6829 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486830 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456831 }
6832
Ryan Hamilton8d9ee76e2018-05-29 23:52:526833 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236834 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526835 quic::QuicStreamId stream_id,
6836 bool should_include_version,
6837 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586838 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456839 packet_number, stream_id, should_include_version, nullptr, maker);
6840 }
6841
Ryan Hamilton8d9ee76e2018-05-29 23:52:526842 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236843 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526844 quic::QuicStreamId stream_id,
6845 quic::QuicStreamOffset* offset,
6846 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136847 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456848 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266849 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456850 }
6851
Ryan Hamilton8d9ee76e2018-05-29 23:52:526852 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236853 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526854 quic::QuicStreamId stream_id,
6855 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586856 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6857 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456858 }
6859
Ryan Hamilton8d9ee76e2018-05-29 23:52:526860 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236861 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526862 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456863 QuicTestPacketMaker* maker) {
Renjief49758b2019-01-11 23:32:416864 quic::QuicString header = "";
6865 if (version_ == quic::QUIC_VERSION_99) {
6866 quic::HttpEncoder encoder;
6867 std::unique_ptr<char[]> buffer;
6868 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
6869 header = quic::QuicString(buffer.get(), header_length);
6870 }
bnc359ed2a2016-04-29 20:43:456871 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416872 header + "hello");
bnc359ed2a2016-04-29 20:43:456873 }
6874
Ryan Hamilton8d9ee76e2018-05-29 23:52:526875 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236876 uint64_t packet_number,
6877 uint64_t largest_received,
6878 uint64_t smallest_received,
6879 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456880 QuicTestPacketMaker* maker) {
6881 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496882 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456883 }
6884
Ryan Hamilton8d9ee76e2018-05-29 23:52:526885 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236886 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526887 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376888 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366889 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376890 }
6891
bnc359ed2a2016-04-29 20:43:456892 void AddRefusedSocketData() {
6893 std::unique_ptr<StaticSocketDataProvider> refused_data(
6894 new StaticSocketDataProvider());
6895 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6896 refused_data->set_connect_data(refused_connect);
6897 socket_factory_.AddSocketDataProvider(refused_data.get());
6898 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6899 }
6900
6901 void AddHangingSocketData() {
6902 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6903 new StaticSocketDataProvider());
6904 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6905 hanging_data->set_connect_data(hanging_connect);
6906 socket_factory_.AddSocketDataProvider(hanging_data.get());
6907 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6909 }
6910
6911 bool AllDataConsumed() {
6912 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6913 if (!socket_data_ptr->AllReadDataConsumed() ||
6914 !socket_data_ptr->AllWriteDataConsumed()) {
6915 return false;
6916 }
6917 }
6918 return true;
6919 }
6920
6921 void SendRequestAndExpectQuicResponse(const std::string& host) {
6922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6923 HttpRequestInfo request;
6924 std::string url("https://");
6925 url.append(host);
6926 request.url = GURL(url);
6927 request.load_flags = 0;
6928 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106929 request.traffic_annotation =
6930 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456931 TestCompletionCallback callback;
6932 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016933 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456934
6935 std::string response_data;
robpercival214763f2016-07-01 23:27:016936 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456937 EXPECT_EQ("hello", response_data);
6938
6939 const HttpResponseInfo* response = trans.GetResponseInfo();
6940 ASSERT_TRUE(response != nullptr);
6941 ASSERT_TRUE(response->headers.get() != nullptr);
6942 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6943 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526944 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446945 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456946 response->connection_info);
6947 EXPECT_EQ(443, response->socket_address.port());
6948 }
6949
Fan Yang32c5a112018-12-10 20:06:336950 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
6951 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366952 }
6953
Ryan Hamilton8d9ee76e2018-05-29 23:52:526954 quic::MockClock clock_;
6955 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056956 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526957 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456958 DestinationType destination_type_;
6959 std::string origin1_;
6960 std::string origin2_;
6961 std::unique_ptr<HttpNetworkSession> session_;
6962 MockClientSocketFactory socket_factory_;
6963 MockHostResolver host_resolver_;
6964 MockCertVerifier cert_verifier_;
6965 TransportSecurityState transport_security_state_;
6966 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236967 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456968 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076969 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596970 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456971 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526972 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456973 HttpServerPropertiesImpl http_server_properties_;
6974 BoundTestNetLog net_log_;
6975 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6976 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6977 static_socket_data_provider_vector_;
6978 SSLSocketDataProvider ssl_data_;
6979};
6980
Victor Costane635086f2019-01-27 05:20:306981INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6982 QuicNetworkTransactionWithDestinationTest,
6983 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:456984
6985// A single QUIC request fails because the certificate does not match the origin
6986// hostname, regardless of whether it matches the alternative service hostname.
6987TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6988 if (destination_type_ == DIFFERENT)
6989 return;
6990
6991 GURL url("https://mail.example.com/");
6992 origin1_ = url.host();
6993
6994 // Not used for requests, but this provides a test case where the certificate
6995 // is valid for the hostname of the alternative service.
6996 origin2_ = "mail.example.org";
6997
zhongyie537a002017-06-27 16:48:216998 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456999
7000 scoped_refptr<X509Certificate> cert(
7001 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247002 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7003 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457004
7005 ProofVerifyDetailsChromium verify_details;
7006 verify_details.cert_verify_result.verified_cert = cert;
7007 verify_details.cert_verify_result.is_issued_by_known_root = true;
7008 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7009
7010 MockQuicData mock_quic_data;
7011 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7012 mock_quic_data.AddRead(ASYNC, 0);
7013
7014 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7015
7016 AddRefusedSocketData();
7017
7018 HttpRequestInfo request;
7019 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107020 request.traffic_annotation =
7021 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457022
7023 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7024 TestCompletionCallback callback;
7025 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017026 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457027
7028 EXPECT_TRUE(AllDataConsumed());
7029}
7030
7031// First request opens QUIC session to alternative service. Second request
7032// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527033// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457034TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7035 origin1_ = "mail.example.org";
7036 origin2_ = "news.example.org";
7037
zhongyie537a002017-06-27 16:48:217038 SetQuicAlternativeService(origin1_);
7039 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457040
7041 scoped_refptr<X509Certificate> cert(
7042 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247043 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7044 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7045 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457046
7047 ProofVerifyDetailsChromium verify_details;
7048 verify_details.cert_verify_result.verified_cert = cert;
7049 verify_details.cert_verify_result.is_issued_by_known_root = true;
7050 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7051
Yixin Wang079ad542018-01-11 04:06:057052 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177053 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7054 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057055 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177056 QuicTestPacketMaker server_maker(
7057 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7058 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457059
Ryan Hamilton8d9ee76e2018-05-29 23:52:527060 quic::QuicStreamOffset request_header_offset(0);
7061 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457062
7063 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057064 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437065 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057066 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337067 mock_quic_data.AddWrite(
7068 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7069 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7070 &request_header_offset, &client_maker));
7071 mock_quic_data.AddRead(ASYNC,
7072 ConstructServerResponseHeadersPacket(
7073 1, GetNthClientInitiatedBidirectionalStreamId(0),
7074 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437075 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337076 ASYNC,
7077 ConstructServerDataPacket(
7078 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437079 mock_quic_data.AddWrite(SYNCHRONOUS,
7080 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457081
Yixin Wang079ad542018-01-11 04:06:057082 client_maker.set_hostname(origin2_);
7083 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457084
Zhongyi Shi32f2fd02018-04-16 18:23:437085 mock_quic_data.AddWrite(
7086 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337087 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7088 GetNthClientInitiatedBidirectionalStreamId(0),
7089 &request_header_offset, &client_maker));
7090 mock_quic_data.AddRead(ASYNC,
7091 ConstructServerResponseHeadersPacket(
7092 3, GetNthClientInitiatedBidirectionalStreamId(1),
7093 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437094 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337095 ASYNC,
7096 ConstructServerDataPacket(
7097 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437098 mock_quic_data.AddWrite(SYNCHRONOUS,
7099 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457100 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7101 mock_quic_data.AddRead(ASYNC, 0); // EOF
7102
7103 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7104
7105 AddHangingSocketData();
7106 AddHangingSocketData();
7107
Fan Yangc9e00dc2018-10-09 14:17:567108 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7109 QuicStreamFactoryPeer::SetAlarmFactory(
7110 session_->quic_stream_factory(),
7111 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7112 &clock_));
7113
bnc359ed2a2016-04-29 20:43:457114 SendRequestAndExpectQuicResponse(origin1_);
7115 SendRequestAndExpectQuicResponse(origin2_);
7116
7117 EXPECT_TRUE(AllDataConsumed());
7118}
7119
7120// First request opens QUIC session to alternative service. Second request does
7121// not pool to it, even though destination matches, because certificate is not
7122// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527123// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457124TEST_P(QuicNetworkTransactionWithDestinationTest,
7125 DoNotPoolIfCertificateInvalid) {
7126 origin1_ = "news.example.org";
7127 origin2_ = "mail.example.com";
7128
zhongyie537a002017-06-27 16:48:217129 SetQuicAlternativeService(origin1_);
7130 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457131
7132 scoped_refptr<X509Certificate> cert1(
7133 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247134 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7135 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7136 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457137
7138 scoped_refptr<X509Certificate> cert2(
7139 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247140 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7141 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457142
7143 ProofVerifyDetailsChromium verify_details1;
7144 verify_details1.cert_verify_result.verified_cert = cert1;
7145 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7146 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7147
7148 ProofVerifyDetailsChromium verify_details2;
7149 verify_details2.cert_verify_result.verified_cert = cert2;
7150 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7151 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7152
Yixin Wang079ad542018-01-11 04:06:057153 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177154 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7155 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057156 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177157 QuicTestPacketMaker server_maker1(
7158 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7159 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457160
7161 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527162 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457163 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437164 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7165 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337166 mock_quic_data1.AddWrite(
7167 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7168 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7169 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437170 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337171 ASYNC,
7172 ConstructServerResponseHeadersPacket(
7173 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437174 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337175 ASYNC,
7176 ConstructServerDataPacket(
7177 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437178 mock_quic_data1.AddWrite(
7179 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457180 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7181 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7182
7183 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7184
Yixin Wang079ad542018-01-11 04:06:057185 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177186 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7187 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057188 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177189 QuicTestPacketMaker server_maker2(
7190 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7191 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457192
7193 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527194 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457195 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437196 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7197 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337198 mock_quic_data2.AddWrite(
7199 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7200 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7201 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437202 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337203 ASYNC,
7204 ConstructServerResponseHeadersPacket(
7205 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437206 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337207 ASYNC,
7208 ConstructServerDataPacket(
7209 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437210 mock_quic_data2.AddWrite(
7211 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457212 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7213 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7214
7215 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7216
bnc359ed2a2016-04-29 20:43:457217 SendRequestAndExpectQuicResponse(origin1_);
7218 SendRequestAndExpectQuicResponse(origin2_);
7219
7220 EXPECT_TRUE(AllDataConsumed());
7221}
7222
ckrasicdee37572017-04-06 22:42:277223// crbug.com/705109 - this confirms that matching request with a body
7224// triggers a crash (pre-fix).
7225TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417226 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277227 HostPortPair::FromString("mail.example.org:443"));
7228
7229 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527230 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237231 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437232 mock_quic_data.AddWrite(
7233 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7234 &header_stream_offset));
7235 mock_quic_data.AddWrite(
7236 SYNCHRONOUS,
7237 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337238 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7239 true, true, GetRequestHeaders("GET", "https", "/"),
7240 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527241 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437242 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337243 ASYNC, ConstructServerPushPromisePacket(
7244 1, GetNthClientInitiatedBidirectionalStreamId(0),
7245 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7246 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7247 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577248 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267249 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337250 mock_quic_data.AddWrite(SYNCHRONOUS,
7251 ConstructClientPriorityPacket(
7252 client_packet_number++, false,
7253 GetNthServerInitiatedUnidirectionalStreamId(0),
7254 GetNthClientInitiatedBidirectionalStreamId(0),
7255 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577256 }
Zhongyi Shi32f2fd02018-04-16 18:23:437257 mock_quic_data.AddRead(
7258 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337259 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437260 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577261 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437262 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7263 mock_quic_data.AddRead(
7264 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337265 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7266 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417267 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437268 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337269 ASYNC, ConstructServerDataPacket(
7270 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417271 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577272 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437273 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417274
7275 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437276 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337277 ASYNC, ConstructServerDataPacket(
7278 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417279 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277280
7281 // Because the matching request has a body, we will see the push
7282 // stream get cancelled, and the matching request go out on the
7283 // wire.
Fan Yang32c5a112018-12-10 20:06:337284 mock_quic_data.AddWrite(SYNCHRONOUS,
7285 ConstructClientAckAndRstPacket(
7286 client_packet_number++,
7287 GetNthServerInitiatedUnidirectionalStreamId(0),
7288 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277289 const char kBody[] = "1";
Renjief49758b2019-01-11 23:32:417290 quic::QuicString header3 = ConstructDataHeader(1);
7291 if (version_ != quic::QUIC_VERSION_99) {
7292 mock_quic_data.AddWrite(
7293 SYNCHRONOUS,
7294 ConstructClientRequestHeadersAndDataFramesPacket(
7295 client_packet_number++,
7296 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7297 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7298 GetNthServerInitiatedUnidirectionalStreamId(0),
7299 &header_stream_offset, nullptr, {kBody}));
7300 } else {
7301 mock_quic_data.AddWrite(
7302 SYNCHRONOUS,
7303 ConstructClientRequestHeadersAndDataFramesPacket(
7304 client_packet_number++,
7305 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7306 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7307 GetNthServerInitiatedUnidirectionalStreamId(0),
7308 &header_stream_offset, nullptr, {header3, kBody}));
7309 }
ckrasicdee37572017-04-06 22:42:277310
7311 // We see the same response as for the earlier pushed and cancelled
7312 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437313 mock_quic_data.AddRead(
7314 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337315 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437316 GetResponseHeaders("200 OK"), &server_header_offset));
7317 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337318 ASYNC, ConstructServerDataPacket(
7319 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417320 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277321
Yixin Wangb470bc882018-02-15 18:43:577322 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437323 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277324 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7325 mock_quic_data.AddRead(ASYNC, 0); // EOF
7326 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7327
7328 // The non-alternate protocol job needs to hang in order to guarantee that
7329 // the alternate-protocol job will "win".
7330 AddHangingNonAlternateProtocolSocketData();
7331
7332 CreateSession();
7333
7334 // PUSH_PROMISE handling in the http layer gets exercised here.
7335 SendRequestAndExpectQuicResponse("hello!");
7336
7337 request_.url = GURL("https://mail.example.org/pushed.jpg");
7338 ChunkedUploadDataStream upload_data(0);
7339 upload_data.AppendData("1", 1, true);
7340 request_.upload_data_stream = &upload_data;
7341 SendRequestAndExpectQuicResponse("and hello!");
7342}
7343
Bence Béky7538a952018-02-01 16:59:527344// Regression test for https://crbug.com/797825: If pushed headers describe a
7345// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7346// not be called (otherwise a DCHECK fails).
7347TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137348 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527349 pushed_request_headers[":authority"] = "";
7350 pushed_request_headers[":method"] = "GET";
7351 pushed_request_headers[":path"] = "/";
7352 pushed_request_headers[":scheme"] = "nosuchscheme";
7353
7354 session_params_.origins_to_force_quic_on.insert(
7355 HostPortPair::FromString("mail.example.org:443"));
7356
7357 MockQuicData mock_quic_data;
7358
Ryan Hamilton8d9ee76e2018-05-29 23:52:527359 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527360 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437361 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7362 mock_quic_data.AddWrite(
7363 SYNCHRONOUS,
7364 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337365 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437366 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527367
Ryan Hamilton8d9ee76e2018-05-29 23:52:527368 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337369 mock_quic_data.AddRead(
7370 ASYNC, ConstructServerPushPromisePacket(
7371 1, GetNthClientInitiatedBidirectionalStreamId(0),
7372 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7373 std::move(pushed_request_headers), &server_header_offset,
7374 &server_maker_));
7375 mock_quic_data.AddWrite(SYNCHRONOUS,
7376 ConstructClientRstPacket(
7377 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7378 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527379
Zhongyi Shi32f2fd02018-04-16 18:23:437380 mock_quic_data.AddRead(
7381 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337382 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437383 GetResponseHeaders("200 OK"), &server_header_offset));
7384 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527385
Zhongyi Shi32f2fd02018-04-16 18:23:437386 mock_quic_data.AddRead(
7387 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337388 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7389 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417390 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437391 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337392 ASYNC, ConstructServerDataPacket(
7393 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417394 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437395 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527396
7397 mock_quic_data.AddRead(ASYNC, 0);
7398 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7399
7400 // The non-alternate protocol job needs to hang in order to guarantee that
7401 // the alternate-protocol job will "win".
7402 AddHangingNonAlternateProtocolSocketData();
7403
7404 CreateSession();
7405
7406 // PUSH_PROMISE handling in the http layer gets exercised here.
7407 SendRequestAndExpectQuicResponse("hello!");
7408
7409 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7410 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7411}
7412
Yixin Wang46a273ec302018-01-23 17:59:567413// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147414TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567415 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147416 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567417 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497418 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567419
7420 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527421 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567422 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357423 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337424 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357425 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7426 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7427 false, ConnectRequestHeaders("mail.example.org:443"),
7428 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337429 mock_quic_data.AddRead(
7430 ASYNC, ConstructServerResponseHeadersPacket(
7431 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7432 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567433
7434 const char get_request[] =
7435 "GET / HTTP/1.1\r\n"
7436 "Host: mail.example.org\r\n"
7437 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417438 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7439 if (version_ != quic::QUIC_VERSION_99) {
7440 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357441 SYNCHRONOUS,
7442 ConstructClientAckAndDataPacket(
7443 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7444 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417445 } else {
7446 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417447 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357448 ConstructClientAckAndMultipleDataFramesPacket(
7449 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7450 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417451 }
7452
Yixin Wang46a273ec302018-01-23 17:59:567453 const char get_response[] =
7454 "HTTP/1.1 200 OK\r\n"
7455 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417456 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437457 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337458 ASYNC, ConstructServerDataPacket(
7459 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417460 0, header2 + quic::QuicString(get_response)));
7461 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337462 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417463 SYNCHRONOUS, ConstructServerDataPacket(
7464 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7465 false, strlen(get_response) + header2.length(),
7466 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357467 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567468 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7469
7470 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417471 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357472 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7473 quic::QUIC_STREAM_CANCELLED,
7474 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567475
7476 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7477
7478 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7479
7480 CreateSession();
7481
7482 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097483 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567484 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7485 HeadersHandler headers_handler;
7486 trans.SetBeforeHeadersSentCallback(
7487 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7488 base::Unretained(&headers_handler)));
7489 RunTransaction(&trans);
7490 CheckWasHttpResponse(&trans);
7491 CheckResponsePort(&trans, 70);
7492 CheckResponseData(&trans, "0123456789");
7493 EXPECT_TRUE(headers_handler.was_proxied());
7494 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7495
7496 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7497 // proxy socket to disconnect.
7498 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7499
7500 base::RunLoop().RunUntilIdle();
7501 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7502 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7503}
7504
7505// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147506TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567507 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147508 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567509 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497510 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567511
7512 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527513 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567514 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357515 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337516 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357517 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7518 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7519 false, ConnectRequestHeaders("mail.example.org:443"),
7520 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337521 mock_quic_data.AddRead(
7522 ASYNC, ConstructServerResponseHeadersPacket(
7523 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7524 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567525
7526 SpdyTestUtil spdy_util;
7527
Ryan Hamilton0239aac2018-05-19 00:03:137528 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567529 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417530 quic::QuicString header = ConstructDataHeader(get_frame.size());
7531 if (version_ != quic::QUIC_VERSION_99) {
7532 mock_quic_data.AddWrite(
7533 SYNCHRONOUS,
7534 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357535 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7536 false, 0,
Renjief49758b2019-01-11 23:32:417537 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7538 } else {
7539 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417540 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357541 ConstructClientAckAndMultipleDataFramesPacket(
7542 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7543 false, 0,
7544 {header, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417545 }
Ryan Hamilton0239aac2018-05-19 00:03:137546 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567547 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417548 quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437549 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337550 ASYNC,
7551 ConstructServerDataPacket(
7552 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Renjief49758b2019-01-11 23:32:417553 header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567554
Ryan Hamilton0239aac2018-05-19 00:03:137555 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197556 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Renjief49758b2019-01-11 23:32:417557 quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437558 mock_quic_data.AddRead(
7559 SYNCHRONOUS,
7560 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337561 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417562 resp_frame.size() + header2.length(),
7563 header3 + quic::QuicString(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357564 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567565 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7566
7567 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437568 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357569 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7570 quic::QUIC_STREAM_CANCELLED,
7571 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567572
7573 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7574
7575 SSLSocketDataProvider ssl_data(ASYNC, OK);
7576 ssl_data.next_proto = kProtoHTTP2;
7577 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7578
7579 CreateSession();
7580
7581 request_.url = GURL("https://mail.example.org/");
7582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7583 HeadersHandler headers_handler;
7584 trans.SetBeforeHeadersSentCallback(
7585 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7586 base::Unretained(&headers_handler)));
7587 RunTransaction(&trans);
7588 CheckWasSpdyResponse(&trans);
7589 CheckResponsePort(&trans, 70);
7590 CheckResponseData(&trans, "0123456789");
7591 EXPECT_TRUE(headers_handler.was_proxied());
7592 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7593
Wez0e717112018-06-18 23:09:227594 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7595 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567596 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7597
7598 base::RunLoop().RunUntilIdle();
7599 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7600 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7601}
7602
7603// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7604// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147605TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567606 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147607 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567608 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497609 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567610
7611 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527612 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417613 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567614 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417615 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7616 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337617 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417618 SYNCHRONOUS,
7619 ConstructClientRequestHeadersPacket(
7620 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7621 true, false, ConnectRequestHeaders("mail.example.org:443"),
7622 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337623 mock_quic_data.AddRead(
7624 ASYNC, ConstructServerResponseHeadersPacket(
7625 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7626 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567627
Ryan Hamilton8d9ee76e2018-05-29 23:52:527628 quic::QuicStreamOffset client_data_offset = 0;
7629 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567630 const char get_request_1[] =
7631 "GET / HTTP/1.1\r\n"
7632 "Host: mail.example.org\r\n"
7633 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417634 quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
7635 if (version_ != quic::QUIC_VERSION_99) {
7636 mock_quic_data.AddWrite(
7637 SYNCHRONOUS,
7638 ConstructClientAckAndDataPacket(
7639 write_packet_index++, false,
7640 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7641 client_data_offset, quic::QuicStringPiece(get_request_1)));
7642 } else {
7643 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417644 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357645 ConstructClientAckAndMultipleDataFramesPacket(
7646 write_packet_index++, false,
7647 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7648 client_data_offset, {header, quic::QuicString(get_request_1)}));
Renjief49758b2019-01-11 23:32:417649 }
7650
7651 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567652
7653 const char get_response_1[] =
7654 "HTTP/1.1 200 OK\r\n"
7655 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417656 quic::QuicString header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437657 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417658 ASYNC,
7659 ConstructServerDataPacket(
7660 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7661 server_data_offset, header2 + quic::QuicString(get_response_1)));
7662 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567663
Renjief49758b2019-01-11 23:32:417664 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337665 mock_quic_data.AddRead(
7666 SYNCHRONOUS,
7667 ConstructServerDataPacket(
7668 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417669 server_data_offset, header3 + quic::QuicString("0123456789")));
7670 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567671
Renjief49758b2019-01-11 23:32:417672 mock_quic_data.AddWrite(
7673 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567674
7675 const char get_request_2[] =
7676 "GET /2 HTTP/1.1\r\n"
7677 "Host: mail.example.org\r\n"
7678 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417679 quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
7680 if (version_ == quic::QUIC_VERSION_99) {
7681 mock_quic_data.AddWrite(
7682 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357683 ConstructClientMultipleDataFramesPacket(
7684 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7685 false, false, client_data_offset,
7686 {header4, quic::QuicString(get_request_2)}));
7687 client_data_offset += header4.length() + strlen(get_request_2);
7688 } else {
7689 mock_quic_data.AddWrite(
7690 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417691 ConstructClientDataPacket(write_packet_index++,
7692 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357693 false, false, client_data_offset,
7694 quic::QuicStringPiece(get_request_2)));
7695 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417696 }
Yixin Wang46a273ec302018-01-23 17:59:567697
7698 const char get_response_2[] =
7699 "HTTP/1.1 200 OK\r\n"
7700 "Content-Length: 7\r\n\r\n";
Renjief49758b2019-01-11 23:32:417701 quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437702 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417703 ASYNC,
7704 ConstructServerDataPacket(
7705 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7706 server_data_offset, header5 + quic::QuicString(get_response_2)));
7707 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567708
Renjief49758b2019-01-11 23:32:417709 quic::QuicString header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527710 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337711 SYNCHRONOUS,
7712 ConstructServerDataPacket(
7713 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417714 server_data_offset, header6 + quic::QuicString("0123456")));
7715 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567716
Renjief49758b2019-01-11 23:32:417717 mock_quic_data.AddWrite(
7718 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567719 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7720
Renjief49758b2019-01-11 23:32:417721 mock_quic_data.AddWrite(
7722 SYNCHRONOUS,
7723 ConstructClientRstPacket(
7724 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7725 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567726
7727 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7728
7729 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7730
7731 CreateSession();
7732
7733 request_.url = GURL("https://mail.example.org/");
7734 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7735 HeadersHandler headers_handler_1;
7736 trans_1.SetBeforeHeadersSentCallback(
7737 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7738 base::Unretained(&headers_handler_1)));
7739 RunTransaction(&trans_1);
7740 CheckWasHttpResponse(&trans_1);
7741 CheckResponsePort(&trans_1, 70);
7742 CheckResponseData(&trans_1, "0123456789");
7743 EXPECT_TRUE(headers_handler_1.was_proxied());
7744 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7745
7746 request_.url = GURL("https://mail.example.org/2");
7747 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7748 HeadersHandler headers_handler_2;
7749 trans_2.SetBeforeHeadersSentCallback(
7750 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7751 base::Unretained(&headers_handler_2)));
7752 RunTransaction(&trans_2);
7753 CheckWasHttpResponse(&trans_2);
7754 CheckResponsePort(&trans_2, 70);
7755 CheckResponseData(&trans_2, "0123456");
7756 EXPECT_TRUE(headers_handler_2.was_proxied());
7757 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7758
7759 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7760 // proxy socket to disconnect.
7761 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7762
7763 base::RunLoop().RunUntilIdle();
7764 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7765 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7766}
7767
7768// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7769// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7770// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147771TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567772 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147773 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567774 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497775 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567776
7777 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527778 quic::QuicStreamOffset client_header_stream_offset = 0;
7779 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357780 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7781 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567782
7783 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337784 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357785 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7786 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7787 false, ConnectRequestHeaders("mail.example.org:443"),
7788 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437789 mock_quic_data.AddRead(
7790 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337791 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437792 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567793
7794 // GET request, response, and data over QUIC tunnel for first request
7795 const char get_request[] =
7796 "GET / HTTP/1.1\r\n"
7797 "Host: mail.example.org\r\n"
7798 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417799 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7800 if (version_ != quic::QUIC_VERSION_99) {
7801 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357802 SYNCHRONOUS,
7803 ConstructClientAckAndDataPacket(
7804 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7805 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417806 } else {
7807 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417808 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357809 ConstructClientAckAndMultipleDataFramesPacket(
7810 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7811 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417812 }
7813
Yixin Wang46a273ec302018-01-23 17:59:567814 const char get_response[] =
7815 "HTTP/1.1 200 OK\r\n"
7816 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417817 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567818 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337819 ASYNC, ConstructServerDataPacket(
7820 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417821 0, header2 + quic::QuicString(get_response)));
7822 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337823 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417824 SYNCHRONOUS, ConstructServerDataPacket(
7825 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7826 false, strlen(get_response) + header2.length(),
7827 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357828 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567829
7830 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437831 mock_quic_data.AddWrite(
7832 SYNCHRONOUS,
7833 ConstructClientRequestHeadersPacket(
Renjied172e812019-01-16 05:12:357834 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7835 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:337836 GetNthClientInitiatedBidirectionalStreamId(0),
7837 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437838 mock_quic_data.AddRead(
7839 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337840 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437841 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567842
7843 // GET request, response, and data over QUIC tunnel for second request
7844 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137845 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567846 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417847 quic::QuicString header4 = ConstructDataHeader(get_frame.size());
7848 if (version_ != quic::QUIC_VERSION_99) {
7849 mock_quic_data.AddWrite(
7850 SYNCHRONOUS,
7851 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357852 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7853 false, 0,
Renjief49758b2019-01-11 23:32:417854 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7855 } else {
7856 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417857 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357858 ConstructClientAckAndMultipleDataFramesPacket(
7859 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7860 false, 0,
7861 {header4, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417862 }
Yixin Wang46a273ec302018-01-23 17:59:567863
Ryan Hamilton0239aac2018-05-19 00:03:137864 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567865 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417866 quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437867 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337868 ASYNC,
7869 ConstructServerDataPacket(
7870 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Renjief49758b2019-01-11 23:32:417871 header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567872
Ryan Hamilton0239aac2018-05-19 00:03:137873 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197874 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Renjief49758b2019-01-11 23:32:417875 quic::QuicString header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437876 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417877 ASYNC,
7878 ConstructServerDataPacket(
7879 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7880 resp_frame.size() + header5.length(),
7881 header6 + quic::QuicString(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567882
Renjied172e812019-01-16 05:12:357883 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567884 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7885
7886 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417887 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357888 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7889 quic::QUIC_STREAM_CANCELLED,
7890 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567891 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437892 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357893 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7894 quic::QUIC_STREAM_CANCELLED,
7895 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567896
7897 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7898
7899 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7900
7901 SSLSocketDataProvider ssl_data(ASYNC, OK);
7902 ssl_data.next_proto = kProtoHTTP2;
7903 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7904
7905 CreateSession();
7906
7907 request_.url = GURL("https://mail.example.org/");
7908 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7909 HeadersHandler headers_handler_1;
7910 trans_1.SetBeforeHeadersSentCallback(
7911 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7912 base::Unretained(&headers_handler_1)));
7913 RunTransaction(&trans_1);
7914 CheckWasHttpResponse(&trans_1);
7915 CheckResponsePort(&trans_1, 70);
7916 CheckResponseData(&trans_1, "0123456789");
7917 EXPECT_TRUE(headers_handler_1.was_proxied());
7918 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7919
7920 request_.url = GURL("https://different.example.org/");
7921 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7922 HeadersHandler headers_handler_2;
7923 trans_2.SetBeforeHeadersSentCallback(
7924 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7925 base::Unretained(&headers_handler_2)));
7926 RunTransaction(&trans_2);
7927 CheckWasSpdyResponse(&trans_2);
7928 CheckResponsePort(&trans_2, 70);
7929 CheckResponseData(&trans_2, "0123456");
7930 EXPECT_TRUE(headers_handler_2.was_proxied());
7931 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7932
7933 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7934 // proxy socket to disconnect.
7935 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7936
7937 base::RunLoop().RunUntilIdle();
7938 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7939 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7940}
7941
7942// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147943TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567944 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147945 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567946 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497947 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567948
7949 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527950 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567951 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437952 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527953 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337954 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7955 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7956 false, ConnectRequestHeaders("mail.example.org:443"),
7957 &header_stream_offset));
7958 mock_quic_data.AddRead(
7959 ASYNC, ConstructServerResponseHeadersPacket(
7960 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7961 GetResponseHeaders("500")));
7962 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7963 mock_quic_data.AddWrite(SYNCHRONOUS,
7964 ConstructClientAckAndRstPacket(
7965 3, GetNthClientInitiatedBidirectionalStreamId(0),
7966 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567967
7968 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7969
7970 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7971
7972 CreateSession();
7973
7974 request_.url = GURL("https://mail.example.org/");
7975 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7976 HeadersHandler headers_handler;
7977 trans.SetBeforeHeadersSentCallback(
7978 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7979 base::Unretained(&headers_handler)));
7980 TestCompletionCallback callback;
7981 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7982 EXPECT_EQ(ERR_IO_PENDING, rv);
7983 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7984 EXPECT_EQ(false, headers_handler.was_proxied());
7985
7986 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7987 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7988}
7989
7990// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:147991TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:567992 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147993 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567994 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497995 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567996
7997 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527998 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567999 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438000 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338001 mock_quic_data.AddWrite(
8002 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8003 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8004 false, ConnectRequestHeaders("mail.example.org:443"),
8005 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568006 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8007
8008 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8009
8010 CreateSession();
8011
8012 request_.url = GURL("https://mail.example.org/");
8013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8014 HeadersHandler headers_handler;
8015 trans.SetBeforeHeadersSentCallback(
8016 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8017 base::Unretained(&headers_handler)));
8018 TestCompletionCallback callback;
8019 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8020 EXPECT_EQ(ERR_IO_PENDING, rv);
8021 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8022
8023 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8024 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8025}
8026
8027// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8028// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148029TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568030 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148031 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568032 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498033 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568034
8035 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528036 quic::QuicStreamOffset client_header_stream_offset = 0;
8037 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358038 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8039 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338040 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358041 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8042 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8043 false, ConnectRequestHeaders("mail.example.org:443"),
8044 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438045 mock_quic_data.AddRead(
8046 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338047 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438048 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358049 mock_quic_data.AddWrite(SYNCHRONOUS,
8050 ConstructClientAckAndRstPacket(
8051 3, GetNthClientInitiatedBidirectionalStreamId(0),
8052 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568053
Zhongyi Shi32f2fd02018-04-16 18:23:438054 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358055 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8056 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8057 false, ConnectRequestHeaders("mail.example.org:443"),
8058 GetNthClientInitiatedBidirectionalStreamId(0),
8059 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438060 mock_quic_data.AddRead(
8061 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338062 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438063 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568064
8065 const char get_request[] =
8066 "GET / HTTP/1.1\r\n"
8067 "Host: mail.example.org\r\n"
8068 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:418069 quic::QuicString header = ConstructDataHeader(strlen(get_request));
8070 if (version_ != quic::QUIC_VERSION_99) {
8071 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358072 SYNCHRONOUS,
8073 ConstructClientAckAndDataPacket(
8074 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8075 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418076 } else {
8077 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418078 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358079 ConstructClientAckAndMultipleDataFramesPacket(
8080 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8081 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:418082 }
Yixin Wang46a273ec302018-01-23 17:59:568083 const char get_response[] =
8084 "HTTP/1.1 200 OK\r\n"
8085 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:418086 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438087 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338088 ASYNC, ConstructServerDataPacket(
8089 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Renjief49758b2019-01-11 23:32:418090 0, header2 + quic::QuicString(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528091
Renjief49758b2019-01-11 23:32:418092 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338093 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418094 SYNCHRONOUS, ConstructServerDataPacket(
8095 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8096 false, strlen(get_response) + header2.length(),
8097 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358098 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568099 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8100
8101 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418102 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358103 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8104 quic::QUIC_STREAM_CANCELLED,
8105 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568106
8107 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8108
8109 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8110 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8111
8112 SSLSocketDataProvider ssl_data(ASYNC, OK);
8113 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8114
8115 CreateSession();
8116
8117 request_.url = GURL("https://mail.example.org/");
8118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8119 HeadersHandler headers_handler;
8120 trans.SetBeforeHeadersSentCallback(
8121 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8122 base::Unretained(&headers_handler)));
8123 TestCompletionCallback callback;
8124 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8125 EXPECT_EQ(ERR_IO_PENDING, rv);
8126 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8127
8128 rv = trans.RestartIgnoringLastError(callback.callback());
8129 EXPECT_EQ(ERR_IO_PENDING, rv);
8130 EXPECT_EQ(OK, callback.WaitForResult());
8131
8132 CheckWasHttpResponse(&trans);
8133 CheckResponsePort(&trans, 70);
8134 CheckResponseData(&trans, "0123456789");
8135 EXPECT_EQ(true, headers_handler.was_proxied());
8136 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8137
8138 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8139 // proxy socket to disconnect.
8140 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8141
8142 base::RunLoop().RunUntilIdle();
8143 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8144 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8145}
8146
8147// Checks if a request's specified "user-agent" header shows up correctly in the
8148// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148149TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Yixin Wang46a273ec302018-01-23 17:59:568150 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148151 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568152 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498153 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568154
8155 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528156 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568157 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438158 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568159
Ryan Hamilton0239aac2018-05-19 00:03:138160 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568161 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338162 mock_quic_data.AddWrite(
8163 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8164 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8165 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568166 // Return an error, so the transaction stops here (this test isn't interested
8167 // in the rest).
8168 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8169
8170 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8171
8172 CreateSession();
8173
8174 request_.url = GURL("https://mail.example.org/");
8175 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8176 "Chromium Ultra Awesome X Edition");
8177 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8178 HeadersHandler headers_handler;
8179 trans.SetBeforeHeadersSentCallback(
8180 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8181 base::Unretained(&headers_handler)));
8182 TestCompletionCallback callback;
8183 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8184 EXPECT_EQ(ERR_IO_PENDING, rv);
8185 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8186
8187 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8188 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8189}
8190
Yixin Wang00fc44c2018-01-23 21:12:208191// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8192// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148193TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208194 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148195 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208196 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498197 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208198
8199 const RequestPriority request_priority = MEDIUM;
8200
8201 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528202 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208203 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438204 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8205 mock_quic_data.AddWrite(
8206 SYNCHRONOUS,
8207 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338208 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8209 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438210 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208211 // Return an error, so the transaction stops here (this test isn't interested
8212 // in the rest).
8213 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8214
8215 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8216
8217 CreateSession();
8218
8219 request_.url = GURL("https://mail.example.org/");
8220 HttpNetworkTransaction trans(request_priority, session_.get());
8221 TestCompletionCallback callback;
8222 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8223 EXPECT_EQ(ERR_IO_PENDING, rv);
8224 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8225
8226 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8227 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8228}
8229
Yixin Wang46a273ec302018-01-23 17:59:568230// Test the request-challenge-retry sequence for basic auth, over a QUIC
8231// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148232TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568233 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8234 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138235 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568236 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8237
8238 std::unique_ptr<QuicTestPacketMaker> client_maker;
8239 std::unique_ptr<QuicTestPacketMaker> server_maker;
8240
8241 // On the second pass, the body read of the auth challenge is synchronous, so
8242 // IsConnectedAndIdle returns false. The socket should still be drained and
8243 // reused. See http://crbug.com/544255.
8244 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338245 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178246 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8247 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338248 client_headers_include_h2_stream_dependency_));
8249 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178250 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8251 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568252
8253 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148254 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568255 proxy_resolution_service_ =
8256 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498257 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568258
8259 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528260 quic::QuicStreamOffset client_header_stream_offset = 0;
8261 quic::QuicStreamOffset server_header_stream_offset = 0;
8262 quic::QuicStreamOffset client_data_offset = 0;
8263 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568264
Zhongyi Shi32f2fd02018-04-16 18:23:438265 mock_quic_data.AddWrite(SYNCHRONOUS,
8266 client_maker->MakeInitialSettingsPacket(
8267 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568268
8269 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438270 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568271 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338272 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8273 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568274 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8275 &client_header_stream_offset));
8276
Ryan Hamilton0239aac2018-05-19 00:03:138277 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568278 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8279 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8280 headers["content-length"] = "10";
8281 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438282 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338283 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8284 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568285
8286 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438287 mock_quic_data.AddRead(
8288 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338289 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8290 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568291 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438292 mock_quic_data.AddRead(
8293 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338294 2, GetNthClientInitiatedBidirectionalStreamId(0),
8295 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568296 }
8297 server_data_offset += 10;
8298
Zhongyi Shi32f2fd02018-04-16 18:23:438299 mock_quic_data.AddWrite(SYNCHRONOUS,
8300 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568301
8302 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338303 SYNCHRONOUS,
8304 client_maker->MakeRstPacket(
8305 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188306 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8307 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568308
8309 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8310 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8311 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338312 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8313 5, GetNthClientInitiatedBidirectionalStreamId(1),
8314 false, false, default_priority, std::move(headers),
8315 GetNthClientInitiatedBidirectionalStreamId(0),
8316 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568317
8318 // Response to wrong password
8319 headers =
8320 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8321 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8322 headers["content-length"] = "10";
8323 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438324 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338325 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8326 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568327 mock_quic_data.AddRead(SYNCHRONOUS,
8328 ERR_IO_PENDING); // No more data to read
8329
Fan Yang32c5a112018-12-10 20:06:338330 mock_quic_data.AddWrite(
8331 SYNCHRONOUS,
8332 client_maker->MakeAckAndRstPacket(
8333 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8334 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568335
8336 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8337 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8338
8339 CreateSession();
8340
8341 request_.url = GURL("https://mail.example.org/");
8342 // Ensure that proxy authentication is attempted even
8343 // when the no authentication data flag is set.
8344 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8345 {
8346 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8347 HeadersHandler headers_handler;
8348 trans.SetBeforeHeadersSentCallback(
8349 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8350 base::Unretained(&headers_handler)));
8351 RunTransaction(&trans);
8352
8353 const HttpResponseInfo* response = trans.GetResponseInfo();
8354 ASSERT_TRUE(response != nullptr);
8355 ASSERT_TRUE(response->headers.get() != nullptr);
8356 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8357 response->headers->GetStatusLine());
8358 EXPECT_TRUE(response->headers->IsKeepAlive());
8359 EXPECT_EQ(407, response->headers->response_code());
8360 EXPECT_EQ(10, response->headers->GetContentLength());
8361 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8362 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8363 ASSERT_TRUE(auth_challenge != nullptr);
8364 EXPECT_TRUE(auth_challenge->is_proxy);
8365 EXPECT_EQ("https://proxy.example.org:70",
8366 auth_challenge->challenger.Serialize());
8367 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8368 EXPECT_EQ("basic", auth_challenge->scheme);
8369
8370 TestCompletionCallback callback;
8371 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8372 callback.callback());
8373 EXPECT_EQ(ERR_IO_PENDING, rv);
8374 EXPECT_EQ(OK, callback.WaitForResult());
8375
8376 response = trans.GetResponseInfo();
8377 ASSERT_TRUE(response != nullptr);
8378 ASSERT_TRUE(response->headers.get() != nullptr);
8379 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8380 response->headers->GetStatusLine());
8381 EXPECT_TRUE(response->headers->IsKeepAlive());
8382 EXPECT_EQ(407, response->headers->response_code());
8383 EXPECT_EQ(10, response->headers->GetContentLength());
8384 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8385 auth_challenge = response->auth_challenge.get();
8386 ASSERT_TRUE(auth_challenge != nullptr);
8387 EXPECT_TRUE(auth_challenge->is_proxy);
8388 EXPECT_EQ("https://proxy.example.org:70",
8389 auth_challenge->challenger.Serialize());
8390 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8391 EXPECT_EQ("basic", auth_challenge->scheme);
8392 }
8393 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8394 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8395 // reused because it's not connected).
8396 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8397 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8398 }
8399}
8400
Yixin Wang385652a2018-02-16 02:37:238401TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8402 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8403 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268404 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238405 !client_headers_include_h2_stream_dependency_) {
8406 return;
8407 }
8408
8409 session_params_.origins_to_force_quic_on.insert(
8410 HostPortPair::FromString("mail.example.org:443"));
8411
Fan Yang32c5a112018-12-10 20:06:338412 const quic::QuicStreamId client_stream_0 =
8413 GetNthClientInitiatedBidirectionalStreamId(0);
8414 const quic::QuicStreamId client_stream_1 =
8415 GetNthClientInitiatedBidirectionalStreamId(1);
8416 const quic::QuicStreamId client_stream_2 =
8417 GetNthClientInitiatedBidirectionalStreamId(2);
8418 const quic::QuicStreamId push_stream_0 =
8419 GetNthServerInitiatedUnidirectionalStreamId(0);
8420 const quic::QuicStreamId push_stream_1 =
8421 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238422
8423 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528424 quic::QuicStreamOffset header_stream_offset = 0;
8425 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238426 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438427 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238428
8429 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438430 mock_quic_data.AddWrite(SYNCHRONOUS,
8431 ConstructClientRequestHeadersPacket(
8432 2, client_stream_0, true, true, HIGHEST,
8433 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8434 &header_stream_offset));
8435 mock_quic_data.AddWrite(SYNCHRONOUS,
8436 ConstructClientRequestHeadersPacket(
8437 3, client_stream_1, true, true, MEDIUM,
8438 GetRequestHeaders("GET", "https", "/1.jpg"),
8439 client_stream_0, &header_stream_offset));
8440 mock_quic_data.AddWrite(SYNCHRONOUS,
8441 ConstructClientRequestHeadersPacket(
8442 4, client_stream_2, true, true, MEDIUM,
8443 GetRequestHeaders("GET", "https", "/2.jpg"),
8444 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238445
8446 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438447 mock_quic_data.AddRead(
8448 ASYNC, ConstructServerResponseHeadersPacket(
8449 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8450 &server_header_offset));
8451 mock_quic_data.AddRead(
8452 ASYNC, ConstructServerResponseHeadersPacket(
8453 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8454 &server_header_offset));
8455 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8456 mock_quic_data.AddRead(
8457 ASYNC, ConstructServerResponseHeadersPacket(
8458 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8459 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238460
8461 // Server sends two push promises associated with |client_stream_0|; client
8462 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8463 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438464 mock_quic_data.AddRead(ASYNC,
8465 ConstructServerPushPromisePacket(
8466 4, client_stream_0, push_stream_0, false,
8467 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8468 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238469 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438470 SYNCHRONOUS,
8471 ConstructClientAckAndPriorityFramesPacket(
8472 6, false, 4, 3, 1,
8473 {{push_stream_0, client_stream_2,
8474 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8475 &header_stream_offset));
8476 mock_quic_data.AddRead(ASYNC,
8477 ConstructServerPushPromisePacket(
8478 5, client_stream_0, push_stream_1, false,
8479 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8480 &server_header_offset, &server_maker_));
8481 mock_quic_data.AddWrite(
8482 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238483 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8484 DEFAULT_PRIORITY, &header_stream_offset));
8485
8486 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438487 mock_quic_data.AddRead(
8488 ASYNC, ConstructServerResponseHeadersPacket(
8489 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8490 &server_header_offset));
8491 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8492 mock_quic_data.AddRead(
8493 ASYNC, ConstructServerResponseHeadersPacket(
8494 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8495 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238496
8497 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8498 // priority updates to match the request's priority. Client sends PRIORITY
8499 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438500 mock_quic_data.AddWrite(
8501 SYNCHRONOUS,
8502 ConstructClientAckAndPriorityFramesPacket(
8503 9, false, 7, 7, 1,
8504 {{push_stream_1, client_stream_2,
8505 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8506 {push_stream_0, client_stream_0,
8507 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8508 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238509
8510 // Server sends data for the three requests and the two push promises.
Renjief49758b2019-01-11 23:32:418511 quic::QuicString header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438512 mock_quic_data.AddRead(
8513 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418514 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438515 mock_quic_data.AddRead(
8516 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418517 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438518 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8519 mock_quic_data.AddRead(
8520 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418521 header + "hello 2!"));
8522 quic::QuicString header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438523 mock_quic_data.AddRead(
8524 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418525 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438526 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8527 mock_quic_data.AddRead(
8528 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418529 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238530
Yixin Wang385652a2018-02-16 02:37:238531 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8532 mock_quic_data.AddRead(ASYNC, 0); // EOF
8533 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8534
8535 // The non-alternate protocol job needs to hang in order to guarantee that
8536 // the alternate-protocol job will "win".
8537 AddHangingNonAlternateProtocolSocketData();
8538
8539 CreateSession();
8540
8541 request_.url = GURL("https://mail.example.org/0.jpg");
8542 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8543 TestCompletionCallback callback_0;
8544 EXPECT_EQ(ERR_IO_PENDING,
8545 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8546 base::RunLoop().RunUntilIdle();
8547
8548 request_.url = GURL("https://mail.example.org/1.jpg");
8549 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8550 TestCompletionCallback callback_1;
8551 EXPECT_EQ(ERR_IO_PENDING,
8552 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8553 base::RunLoop().RunUntilIdle();
8554
8555 request_.url = GURL("https://mail.example.org/2.jpg");
8556 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8557 TestCompletionCallback callback_2;
8558 EXPECT_EQ(ERR_IO_PENDING,
8559 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8560 base::RunLoop().RunUntilIdle();
8561
8562 // Client makes request that matches resource pushed in |pushed_stream_0|.
8563 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8564 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8565 TestCompletionCallback callback_3;
8566 EXPECT_EQ(ERR_IO_PENDING,
8567 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8568 base::RunLoop().RunUntilIdle();
8569
8570 EXPECT_TRUE(callback_0.have_result());
8571 EXPECT_EQ(OK, callback_0.WaitForResult());
8572 EXPECT_TRUE(callback_1.have_result());
8573 EXPECT_EQ(OK, callback_1.WaitForResult());
8574 EXPECT_TRUE(callback_2.have_result());
8575 EXPECT_EQ(OK, callback_2.WaitForResult());
8576
8577 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8578 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8579 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8580 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8581
8582 mock_quic_data.Resume();
8583 base::RunLoop().RunUntilIdle();
8584 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8585 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8586}
8587
[email protected]61a527782013-02-21 03:58:008588} // namespace test
8589} // namespace net