blob: 38e8c583b37bfab4d6dfa5d6edf4ca61858722f8 [file] [log] [blame]
[email protected]61a527782013-02-21 03:58:001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rchbd089ab2017-05-26 23:05:045#include <algorithm>
bnc359ed2a2016-04-29 20:43:456#include <ostream>
bnc912a04b2016-04-20 14:19:507#include <string>
8#include <utility>
[email protected]1e960032013-12-20 19:00:209#include <vector>
10
Sebastien Marchand6d0558fd2019-01-25 16:49:3711#include "base/bind.h"
[email protected]61a527782013-02-21 03:58:0012#include "base/compiler_specific.h"
Avi Drissman13fc8932015-12-20 04:40:4613#include "base/macros.h"
mmenke651bae7f2015-12-18 21:26:4514#include "base/run_loop.h"
[email protected]98b20ce2013-05-10 05:55:2615#include "base/stl_util.h"
zhongyie537a002017-06-27 16:48:2116#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1917#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0718#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4719#include "base/test/metrics/histogram_tester.h"
rtenneti56977812016-01-15 19:26:5620#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5821#include "net/base/completion_once_callback.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3722#include "net/base/ip_endpoint.h"
mgershaf9a9232017-04-13 20:19:0323#include "net/base/mock_network_change_notifier.h"
[email protected]61a527782013-02-21 03:58:0024#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0425#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2026#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1127#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1228#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5329#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0030#include "net/http/http_auth_handler_factory.h"
31#include "net/http/http_network_session.h"
32#include "net/http/http_network_transaction.h"
33#include "net/http/http_server_properties_impl.h"
34#include "net/http/http_stream.h"
35#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1936#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1137#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0038#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5139#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4640#include "net/log/test_net_log_entry.h"
41#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0343#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4044#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0845#include "net/quic/crypto/proof_verifier_chromium.h"
46#include "net/quic/mock_crypto_client_stream_factory.h"
47#include "net/quic/mock_quic_data.h"
48#include "net/quic/quic_chromium_alarm_factory.h"
49#include "net/quic/quic_http_stream.h"
50#include "net/quic/quic_http_utils.h"
51#include "net/quic/quic_stream_factory_peer.h"
52#include "net/quic/quic_test_packet_maker.h"
53#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0054#include "net/socket/client_socket_factory.h"
55#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2156#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2857#include "net/socket/socket_performance_watcher.h"
58#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0059#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5860#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5761#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2962#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0163#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4364#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0165#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1666#include "net/third_party/quic/core/crypto/quic_decrypter.h"
67#include "net/third_party/quic/core/crypto/quic_encrypter.h"
68#include "net/third_party/quic/core/quic_framer.h"
Ryan Hamilton47cf9d12018-10-17 04:33:0969#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1670#include "net/third_party/quic/platform/api/quic_str_cat.h"
71#include "net/third_party/quic/platform/api/quic_string_piece.h"
72#include "net/third_party/quic/platform/api/quic_test.h"
73#include "net/third_party/quic/test_tools/crypto_test_utils.h"
74#include "net/third_party/quic/test_tools/mock_clock.h"
75#include "net/third_party/quic/test_tools/mock_random.h"
76#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
77#include "net/third_party/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1478#include "net/third_party/quiche/src/spdy/core/spdy_frame_builder.h"
79#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2980#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
allada71b2efb2016-09-09 04:57:4881#include "net/url_request/url_request.h"
82#include "net/url_request/url_request_job_factory_impl.h"
83#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0184#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0085#include "testing/gtest/include/gtest/gtest.h"
86#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4687#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0088
Reilly Grant89a7e512018-01-20 01:57:1689using ::testing::ElementsAre;
90using ::testing::Key;
91
bnc508835902015-05-12 20:10:2992namespace net {
93namespace test {
[email protected]61a527782013-02-21 03:58:0094
95namespace {
96
bnc359ed2a2016-04-29 20:43:4597enum DestinationType {
98 // In pooling tests with two requests for different origins to the same
99 // destination, the destination should be
100 SAME_AS_FIRST, // the same as the first origin,
101 SAME_AS_SECOND, // the same as the second origin, or
102 DIFFERENT, // different from both.
103};
104
rchf114d982015-10-21 01:34:56105static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52106 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12107static const char kQuicAlternativeServiceWithProbabilityHeader[] =
108 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56109static const char kQuicAlternativeServiceDifferentPortHeader[] =
110 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20111
rch9ae5b3b2016-02-11 00:36:29112const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45113const char kDifferentHostname[] = "different.example.com";
114
115// Run QuicNetworkTransactionWithDestinationTest instances with all value
116// combinations of version and destination_type.
117struct PoolingTestParams {
118 friend std::ostream& operator<<(std::ostream& os,
119 const PoolingTestParams& p) {
120 os << "{ version: " << QuicVersionToString(p.version)
121 << ", destination_type: ";
122 switch (p.destination_type) {
123 case SAME_AS_FIRST:
124 os << "SAME_AS_FIRST";
125 break;
126 case SAME_AS_SECOND:
127 os << "SAME_AS_SECOND";
128 break;
129 case DIFFERENT:
130 os << "DIFFERENT";
131 break;
132 }
Yixin Wang079ad542018-01-11 04:06:05133 os << ", client_headers_include_h2_stream_dependency: "
134 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45135 os << " }";
136 return os;
137 }
138
Ryan Hamilton8d9ee76e2018-05-29 23:52:52139 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45140 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05141 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45142};
143
zhongyie537a002017-06-27 16:48:21144std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52145 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21146 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52147 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21148 if (!result.empty())
149 result.append(",");
Raul Tambre8c1981dd2019-02-08 02:22:26150 result.append(base::NumberToString(version));
zhongyie537a002017-06-27 16:48:21151 }
152 return result;
153}
154
bnc359ed2a2016-04-29 20:43:45155std::vector<PoolingTestParams> GetPoolingTestParams() {
156 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52157 quic::QuicTransportVersionVector all_supported_versions =
158 quic::AllSupportedTransportVersions();
159 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05160 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
161 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
162 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
163 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
164 params.push_back(PoolingTestParams{version, DIFFERENT, false});
165 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45166 }
167 return params;
168}
bncb07c05532015-05-14 19:07:20169
[email protected]61a527782013-02-21 03:58:00170} // namespace
171
ryansturm49a8cb12016-06-15 16:51:09172class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12173 public:
ryansturm49a8cb12016-06-15 16:51:09174 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12175
ryansturm49a8cb12016-06-15 16:51:09176 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12177
ryansturm49a8cb12016-06-15 16:51:09178 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
179 HttpRequestHeaders* request_headers) {
180 if (!proxy_info.is_http() && !proxy_info.is_https() &&
181 !proxy_info.is_quic()) {
182 return;
183 }
184 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12185 }
186
187 private:
ryansturm49a8cb12016-06-15 16:51:09188 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12189};
190
tbansal0f56a39a2016-04-07 22:03:38191class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40192 public:
tbansal180587c2017-02-16 15:13:23193 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
194 bool* rtt_notification_received)
195 : should_notify_updated_rtt_(should_notify_updated_rtt),
196 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38197 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40198
tbansal180587c2017-02-16 15:13:23199 bool ShouldNotifyUpdatedRTT() const override {
200 return *should_notify_updated_rtt_;
201 }
tbansalfdf5665b2015-09-21 22:46:40202
tbansal0f56a39a2016-04-07 22:03:38203 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
204 *rtt_notification_received_ = true;
205 }
206
207 void OnConnectionChanged() override {}
208
209 private:
tbansal180587c2017-02-16 15:13:23210 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38211 bool* rtt_notification_received_;
212
213 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
214};
215
216class TestSocketPerformanceWatcherFactory
217 : public SocketPerformanceWatcherFactory {
218 public:
219 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23220 : watcher_count_(0u),
221 should_notify_updated_rtt_(true),
222 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38223 ~TestSocketPerformanceWatcherFactory() override {}
224
225 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42226 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41227 const Protocol protocol,
228 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51229 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38230 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51231 }
232 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42233 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23234 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
235 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40236 }
237
tbansalc8a94ea2015-11-02 23:58:51238 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40239
tbansalc8a94ea2015-11-02 23:58:51240 bool rtt_notification_received() const { return rtt_notification_received_; }
241
tbansal180587c2017-02-16 15:13:23242 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
243 should_notify_updated_rtt_ = should_notify_updated_rtt;
244 }
245
tbansalc8a94ea2015-11-02 23:58:51246 private:
tbansal0f56a39a2016-04-07 22:03:38247 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23248 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51249 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38250
251 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51252};
253
Ryan Hamilton8d9ee76e2018-05-29 23:52:52254class QuicNetworkTransactionTest
255 : public PlatformTest,
256 public ::testing::WithParamInterface<
257 std::tuple<quic::QuicTransportVersion, bool>>,
258 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00259 protected:
[email protected]1c04f9522013-02-21 20:32:43260 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05261 : version_(std::get<0>(GetParam())),
262 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52263 supported_versions_(quic::test::SupportedTransportVersions(version_)),
David Schinazic8281052019-01-24 06:14:17264 random_generator_(0),
265 client_maker_(
266 version_,
267 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
268 &clock_,
269 kDefaultServerHostName,
270 quic::Perspective::IS_CLIENT,
271 client_headers_include_h2_stream_dependency_),
272 server_maker_(
273 version_,
274 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
275 &clock_,
276 kDefaultServerHostName,
277 quic::Perspective::IS_SERVER,
278 false),
rtenneti052774e2015-11-24 21:00:12279 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43280 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59281 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
[email protected]1c04f9522013-02-21 20:32:43282 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30283 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
rchf114d982015-10-21 01:34:56284 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19285 request_.method = "GET";
rchf114d982015-10-21 01:34:56286 std::string url("https://");
bncb07c05532015-05-14 19:07:20287 url.append(kDefaultServerHostName);
288 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19289 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10290 request_.traffic_annotation =
291 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52292 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56293
294 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29295 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56296 verify_details_.cert_verify_result.verified_cert = cert;
297 verify_details_.cert_verify_result.is_issued_by_known_root = true;
298 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43299 }
[email protected]61a527782013-02-21 03:58:00300
dcheng67be2b1f2014-10-27 21:47:29301 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00302 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55303 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00304 }
305
dcheng67be2b1f2014-10-27 21:47:29306 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
308 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55309 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00310 PlatformTest::TearDown();
311 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55312 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40313 session_.reset();
[email protected]61a527782013-02-21 03:58:00314 }
315
Ryan Hamilton8d9ee76e2018-05-29 23:52:52316 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23317 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03318 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52319 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30320 }
321
Ryan Hamilton8d9ee76e2018-05-29 23:52:52322 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23323 ConstructServerConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03324 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52325 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58326 }
327
Ryan Hamilton8d9ee76e2018-05-29 23:52:52328 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23329 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52330 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20331 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58332 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20333 }
334
Ryan Hamilton8d9ee76e2018-05-29 23:52:52335 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23336 uint64_t packet_number,
337 uint64_t largest_received,
338 uint64_t smallest_received,
339 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37340 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49341 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37342 }
343
Ryan Hamilton8d9ee76e2018-05-29 23:52:52344 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:23345 uint64_t packet_number,
346 uint64_t largest_received,
347 uint64_t smallest_received,
348 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52349 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23350 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49351 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23352 ack_delay_time);
353 }
354
Ryan Hamilton8d9ee76e2018-05-29 23:52:52355 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23356 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52357 quic::QuicStreamId stream_id,
358 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23359 uint64_t largest_received,
360 uint64_t smallest_received,
361 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58362 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49363 num, false, stream_id, error_code, largest_received, smallest_received,
364 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20365 }
366
Ryan Hamilton8d9ee76e2018-05-29 23:52:52367 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23368 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52369 quic::QuicStreamId stream_id,
370 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56371 size_t bytes_written) {
372 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18373 bytes_written,
374 /*include_stop_sending_if_v99=*/true);
Yixin Wang46a273ec302018-01-23 17:59:56375 }
376
Ryan Hamilton8d9ee76e2018-05-29 23:52:52377 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23378 ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
379 uint64_t largest_received,
380 uint64_t smallest_received,
381 uint64_t least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58382 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49383 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20384 }
[email protected]61a527782013-02-21 03:58:00385
Ryan Hamilton8d9ee76e2018-05-29 23:52:52386 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58387 ConstructClientAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23388 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52389 quic::QuicTime::Delta delta_time_largest_observed,
Fan Yangac867502019-01-28 21:10:23390 uint64_t largest_received,
391 uint64_t smallest_received,
392 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52393 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50394 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58395 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12396 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49397 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12398 }
399
Ryan Hamilton8d9ee76e2018-05-29 23:52:52400 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
Fan Yangac867502019-01-28 21:10:23401 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12402 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52403 quic::QuicStreamId stream_id,
404 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58405 return server_maker_.MakeRstPacket(num, include_version, stream_id,
406 error_code);
zhongyica364fbb2015-12-12 03:39:12407 }
408
Ryan Hamilton8d9ee76e2018-05-29 23:52:52409 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23410 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36412 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37413 }
414
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
Fan Yangac867502019-01-28 21:10:23416 uint64_t packet_number,
417 uint64_t largest_received,
418 uint64_t smallest_received,
419 uint64_t least_unacked) {
fayang3bcb8b502016-12-07 21:44:37420 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49421 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37422 }
423
Ryan Hamilton8d9ee76e2018-05-29 23:52:52424 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
Fan Yangac867502019-01-28 21:10:23425 uint64_t packet_number,
Yixin Wangb470bc882018-02-15 18:43:57426 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52427 quic::QuicStreamId id,
428 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57429 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52430 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57431 return client_maker_.MakePriorityPacket(
432 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23433 ConvertRequestPriorityToQuicPriority(request_priority), offset);
434 }
435
Ryan Hamilton8d9ee76e2018-05-29 23:52:52436 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25437 ConstructClientAckAndPriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:23438 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:23439 bool should_include_version,
Fan Yangac867502019-01-28 21:10:23440 uint64_t largest_received,
441 uint64_t smallest_received,
442 uint64_t least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25443 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
444 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52445 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25446 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23447 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25448 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57449 }
450
zhongyi32569c62016-01-08 02:54:30451 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13452 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
453 const std::string& scheme,
454 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58455 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30456 }
457
458 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13459 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
460 const std::string& scheme,
461 const std::string& path,
462 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50463 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00464 }
465
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56467 return client_maker_.ConnectRequestHeaders(host_port);
468 }
469
Ryan Hamilton0239aac2018-05-19 00:03:13470 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58471 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00472 }
473
zhongyi32569c62016-01-08 02:54:30474 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13475 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
476 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58477 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30478 }
479
Ryan Hamilton8d9ee76e2018-05-29 23:52:52480 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:23481 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52482 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05483 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00484 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52485 quic::QuicStreamOffset offset,
486 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58487 return server_maker_.MakeDataPacket(
488 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00489 }
490
Ryan Hamilton8d9ee76e2018-05-29 23:52:52491 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
Fan Yangac867502019-01-28 21:10:23492 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52493 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36494 bool should_include_version,
495 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52496 quic::QuicStreamOffset offset,
497 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36498 return client_maker_.MakeDataPacket(
499 packet_number, stream_id, should_include_version, fin, offset, data);
500 }
501
Renjied172e812019-01-16 05:12:35502 std::unique_ptr<quic::QuicEncryptedPacket>
503 ConstructClientMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23504 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35505 quic::QuicStreamId stream_id,
506 bool should_include_version,
507 bool fin,
508 quic::QuicStreamOffset offset,
509 const std::vector<std::string> data_writes) {
510 return client_maker_.MakeMultipleDataFramesPacket(packet_number, stream_id,
511 should_include_version,
512 fin, offset, data_writes);
513 }
514
Ryan Hamilton8d9ee76e2018-05-29 23:52:52515 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
Fan Yangac867502019-01-28 21:10:23516 uint64_t packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56517 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52518 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23519 uint64_t largest_received,
520 uint64_t smallest_received,
521 uint64_t least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56522 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52523 quic::QuicStreamOffset offset,
524 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56525 return client_maker_.MakeAckAndDataPacket(
526 packet_number, include_version, stream_id, largest_received,
527 smallest_received, least_unacked, fin, offset, data);
528 }
529
Renjied172e812019-01-16 05:12:35530 std::unique_ptr<quic::QuicEncryptedPacket>
531 ConstructClientAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23532 uint64_t packet_number,
Renjied172e812019-01-16 05:12:35533 bool include_version,
534 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23535 uint64_t largest_received,
536 uint64_t smallest_received,
537 uint64_t least_unacked,
Renjied172e812019-01-16 05:12:35538 bool fin,
539 quic::QuicStreamOffset offset,
540 const std::vector<std::string> data_writes) {
541 return client_maker_.MakeAckAndMultipleDataFramesPacket(
542 packet_number, include_version, stream_id, largest_received,
543 smallest_received, least_unacked, fin, offset, data_writes);
544 }
545
Ryan Hamilton8d9ee76e2018-05-29 23:52:52546 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
Fan Yangac867502019-01-28 21:10:23547 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52548 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36549 bool should_include_version,
550 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52551 quic::QuicStreamOffset* offset,
552 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36553 return client_maker_.MakeForceHolDataPacket(
554 packet_number, stream_id, should_include_version, fin, offset, data);
555 }
556
Ryan Hamilton8d9ee76e2018-05-29 23:52:52557 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23558 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52559 quic::QuicStreamId stream_id,
560 bool should_include_version,
561 bool fin,
562 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56563 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
564 should_include_version, fin,
565 std::move(headers), nullptr);
566 }
567
Ryan Hamilton8d9ee76e2018-05-29 23:52:52568 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23569 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52570 quic::QuicStreamId stream_id,
571 bool should_include_version,
572 bool fin,
573 spdy::SpdyHeaderBlock headers,
574 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48575 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
576 should_include_version, fin,
577 std::move(headers), 0, offset);
578 }
579
Ryan Hamilton8d9ee76e2018-05-29 23:52:52580 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23581 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52582 quic::QuicStreamId stream_id,
583 bool should_include_version,
584 bool fin,
585 spdy::SpdyHeaderBlock headers,
586 quic::QuicStreamId parent_stream_id,
587 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56588 return ConstructClientRequestHeadersPacket(
589 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48590 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30591 }
592
Ryan Hamilton8d9ee76e2018-05-29 23:52:52593 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23594 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52595 quic::QuicStreamId stream_id,
596 bool should_include_version,
597 bool fin,
598 RequestPriority request_priority,
599 spdy::SpdyHeaderBlock headers,
600 quic::QuicStreamId parent_stream_id,
601 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13602 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56603 ConvertRequestPriorityToQuicPriority(request_priority);
604 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
605 packet_number, stream_id, should_include_version, fin, priority,
606 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00607 }
608
Ryan Hamilton8d9ee76e2018-05-29 23:52:52609 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25610 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23611 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52612 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25613 bool should_include_version,
614 bool fin,
615 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13616 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52617 quic::QuicStreamId parent_stream_id,
618 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25619 size_t* spdy_headers_frame_length,
620 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13621 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25622 ConvertRequestPriorityToQuicPriority(request_priority);
623 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
624 packet_number, stream_id, should_include_version, fin, priority,
625 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
626 data_writes);
627 }
628
Ryan Hamilton8d9ee76e2018-05-29 23:52:52629 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23630 ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52631 quic::QuicStreamId stream_id,
632 bool should_include_version,
633 bool fin,
634 const std::vector<std::string>& data,
635 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27636 return client_maker_.MakeMultipleDataFramesPacket(
637 packet_number, stream_id, should_include_version, fin, offset, data);
638 }
639
Ryan Hamilton8d9ee76e2018-05-29 23:52:52640 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
Fan Yangac867502019-01-28 21:10:23641 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 quic::QuicStreamId stream_id,
643 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13644 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13645 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52646 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13647 QuicTestPacketMaker* maker) {
648 return maker->MakePushPromisePacket(
649 packet_number, stream_id, promised_stream_id, should_include_version,
650 false, std::move(headers), nullptr, offset);
651 }
652
Ryan Hamilton8d9ee76e2018-05-29 23:52:52653 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23654 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52655 quic::QuicStreamId stream_id,
656 bool should_include_version,
657 bool fin,
658 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27659 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
660 should_include_version, fin,
661 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30662 }
663
Ryan Hamilton8d9ee76e2018-05-29 23:52:52664 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23665 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52666 quic::QuicStreamId stream_id,
667 bool should_include_version,
668 bool fin,
669 spdy::SpdyHeaderBlock headers,
670 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58671 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25672 packet_number, stream_id, should_include_version, fin,
673 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30674 }
675
Renjief49758b2019-01-11 23:32:41676 quic::QuicString ConstructDataHeader(size_t body_len) {
677 if (version_ != quic::QUIC_VERSION_99) {
678 return "";
679 }
680 quic::HttpEncoder encoder;
681 std::unique_ptr<char[]> buffer;
682 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
683 return quic::QuicString(buffer.get(), header_length);
684 }
685
Ryan Hamilton8d9ee76e2018-05-29 23:52:52686 void CreateSession(
687 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41688 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21689 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05690 session_params_.quic_headers_include_h2_stream_dependency =
691 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00692
mmenke6ddfbea2017-05-31 21:48:41693 session_context_.quic_clock = &clock_;
694 session_context_.quic_random = &random_generator_;
695 session_context_.client_socket_factory = &socket_factory_;
696 session_context_.quic_crypto_client_stream_factory =
697 &crypto_client_stream_factory_;
698 session_context_.host_resolver = &host_resolver_;
699 session_context_.cert_verifier = &cert_verifier_;
700 session_context_.transport_security_state = &transport_security_state_;
701 session_context_.cert_transparency_verifier =
702 cert_transparency_verifier_.get();
703 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
704 session_context_.socket_performance_watcher_factory =
705 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59706 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41707 session_context_.ssl_config_service = ssl_config_service_.get();
708 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
709 session_context_.http_server_properties = &http_server_properties_;
710 session_context_.net_log = net_log_.bound().net_log();
711
712 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12713 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56714 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
715 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00716 }
717
zhongyi86838d52017-06-30 01:19:44718 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21719
bnc691fda62016-08-12 00:43:16720 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19721 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42722 ASSERT_TRUE(response != nullptr);
723 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19724 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
725 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52726 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44727 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19728 response->connection_info);
729 }
730
bnc691fda62016-08-12 00:43:16731 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41732 const HttpResponseInfo* response = trans->GetResponseInfo();
733 ASSERT_TRUE(response != nullptr);
Tsuyoshi Horo01faed62019-02-20 22:11:37734 EXPECT_EQ(port, response->remote_endpoint.port());
bnc62a44f022015-04-02 15:59:41735 }
736
bnc691fda62016-08-12 00:43:16737 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19738 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42739 ASSERT_TRUE(response != nullptr);
740 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19741 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
742 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52743 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52744 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19745 response->connection_info);
746 }
747
Yixin Wang46a273ec302018-01-23 17:59:56748 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
749 const HttpResponseInfo* response = trans->GetResponseInfo();
750 ASSERT_TRUE(response != nullptr);
751 ASSERT_TRUE(response->headers.get() != nullptr);
752 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
753 EXPECT_TRUE(response->was_fetched_via_spdy);
754 EXPECT_TRUE(response->was_alpn_negotiated);
755 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
756 response->connection_info);
757 }
758
bnc691fda62016-08-12 00:43:16759 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19760 const std::string& expected) {
761 std::string response_data;
bnc691fda62016-08-12 00:43:16762 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19763 EXPECT_EQ(expected, response_data);
764 }
765
bnc691fda62016-08-12 00:43:16766 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19767 TestCompletionCallback callback;
768 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
770 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19771 }
772
773 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
775 RunTransaction(&trans);
776 CheckWasHttpResponse(&trans);
777 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19778 }
779
tbansalc3308d72016-08-27 10:25:04780 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
781 bool used_proxy,
782 uint16_t port) {
783 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
784 HeadersHandler headers_handler;
785 trans.SetBeforeHeadersSentCallback(
786 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
787 base::Unretained(&headers_handler)));
788 RunTransaction(&trans);
789 CheckWasHttpResponse(&trans);
790 CheckResponsePort(&trans, port);
791 CheckResponseData(&trans, expected);
792 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47793 if (used_proxy) {
794 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
795 } else {
796 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
797 }
tbansalc3308d72016-08-27 10:25:04798 }
799
[email protected]aa9b14d2013-05-10 23:45:19800 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56801 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12802 }
803
bnc62a44f022015-04-02 15:59:41804 void SendRequestAndExpectQuicResponseFromProxyOnPort(
805 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46806 uint16_t port) {
bnc62a44f022015-04-02 15:59:41807 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19808 }
809
810 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27811 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19812 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46813 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21814 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12815 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21816 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44817 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19818 }
819
rchbe69cb902016-02-11 01:10:48820 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27821 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48822 const HostPortPair& alternative) {
823 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46824 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21825 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48826 alternative.port());
827 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21828 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44829 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48830 }
831
[email protected]aa9b14d2013-05-10 23:45:19832 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46833 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34834 const AlternativeServiceInfoVector alternative_service_info_vector =
835 http_server_properties_.GetAlternativeServiceInfos(server);
836 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07837 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54838 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19839 }
840
[email protected]4d590c9c2014-05-02 05:14:33841 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46842 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34843 const AlternativeServiceInfoVector alternative_service_info_vector =
844 http_server_properties_.GetAlternativeServiceInfos(server);
845 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54846 EXPECT_EQ(
847 kProtoQUIC,
848 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23849 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54850 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33851 }
852
[email protected]aa9b14d2013-05-10 23:45:19853 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42854 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30855 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30856 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30857 hanging_data->set_connect_data(hanging_connect);
858 hanging_data_.push_back(std::move(hanging_data));
859 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56860 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19861 }
862
Zhongyi Shia6b68d112018-09-24 07:49:03863 void SetUpTestForRetryConnectionOnAlternateNetwork() {
864 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
865 session_params_.quic_migrate_sessions_early_v2 = true;
866 session_params_.quic_retry_on_alternate_network_before_handshake = true;
867 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
868 MockNetworkChangeNotifier* mock_ncn =
869 scoped_mock_change_notifier_->mock_network_change_notifier();
870 mock_ncn->ForceNetworkHandlesSupported();
871 mock_ncn->SetConnectedNetworksList(
872 {kDefaultNetworkForTests, kNewNetworkForTests});
873 }
874
tbansalc3308d72016-08-27 10:25:04875 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
876 // alternative proxy. Verifies that if the alternative proxy job returns
877 // |error_code|, the request is fetched successfully by the main job.
878 void TestAlternativeProxy(int error_code) {
879 // Use a non-cryptographic scheme for the request URL since this request
880 // will be fetched via proxy with QUIC as the alternative service.
881 request_.url = GURL("http://example.org/");
882 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27883 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04884 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27885 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04886 };
887
Ryan Sleevib8d7ea02018-05-07 20:01:01888 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04889 socket_factory_.AddSocketDataProvider(&quic_data);
890
891 // Main job succeeds and the alternative job fails.
892 // Add data for two requests that will be read by the main job.
893 MockRead http_reads_1[] = {
894 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
895 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
896 MockRead(ASYNC, OK)};
897
898 MockRead http_reads_2[] = {
899 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
900 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
901 MockRead(ASYNC, OK)};
902
Ryan Sleevib8d7ea02018-05-07 20:01:01903 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
904 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04905 socket_factory_.AddSocketDataProvider(&http_data_1);
906 socket_factory_.AddSocketDataProvider(&http_data_2);
907 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
909
910 TestProxyDelegate test_proxy_delegate;
911 // Proxy URL is different from the request URL.
912 test_proxy_delegate.set_alternative_proxy_server(
913 ProxyServer::FromPacString("QUIC myproxy.org:443"));
914
Lily Houghton8c2f97d2018-01-22 05:06:59915 proxy_resolution_service_ =
916 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49917 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52918 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04919
920 CreateSession();
921 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
922
923 // The first request should be fetched via the HTTPS proxy.
924 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
925
Reilly Grant89a7e512018-01-20 01:57:16926 // Since the main job succeeded only the alternative proxy server should be
927 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59928 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16929 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04930
931 // Verify that the second request completes successfully, and the
932 // alternative proxy server job is not started.
933 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
934 }
935
Fan Yang32c5a112018-12-10 20:06:33936 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
937 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36938 }
939
Fan Yang32c5a112018-12-10 20:06:33940 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
941 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36942 }
943
Bence Béky230ac612017-08-30 19:17:08944 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49945 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08946 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49947 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08948 }
949
Ryan Hamilton8d9ee76e2018-05-29 23:52:52950 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05951 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52952 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01953 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52954 quic::MockClock clock_;
David Schinazic8281052019-01-24 06:14:17955 quic::test::MockRandom random_generator_;
alyssar2adf3ac2016-05-03 17:12:58956 QuicTestPacketMaker client_maker_;
957 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42958 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00959 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56960 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05961 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43962 MockHostResolver host_resolver_;
963 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11964 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42965 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23966 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38967 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07968 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59969 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42970 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
bnc6be245c12015-05-15 11:24:07971 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41972 HttpNetworkSession::Params session_params_;
973 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19974 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51975 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42976 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56977 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03978 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12979
980 private:
981 void SendRequestAndExpectQuicResponseMaybeFromProxy(
982 const std::string& expected,
bnc62a44f022015-04-02 15:59:41983 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46984 uint16_t port) {
bnc691fda62016-08-12 00:43:16985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09986 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16987 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09988 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
989 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16990 RunTransaction(&trans);
991 CheckWasQuicResponse(&trans);
992 CheckResponsePort(&trans, port);
993 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09994 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47995 if (used_proxy) {
996 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
997 } else {
998 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
999 }
tbansal7cec3812015-02-05 21:25:121000 }
[email protected]61a527782013-02-21 03:58:001001};
1002
Victor Costane635086f2019-01-27 05:20:301003INSTANTIATE_TEST_SUITE_P(
Yixin Wang385652a2018-02-16 02:37:231004 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:051005 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521006 ::testing::Combine(
1007 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
1008 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:201009
Ryan Hamiltona64a5bcf2017-11-30 07:35:281010TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:481011 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281012 base::HistogramTester histograms;
1013 session_params_.origins_to_force_quic_on.insert(
1014 HostPortPair::FromString("mail.example.org:443"));
1015 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271016 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281017
1018 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521019 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281020 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431021 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281022 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
1023 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1024 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1025
1026 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1027
1028 CreateSession();
1029
1030 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1031 TestCompletionCallback callback;
1032 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1033 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1034 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1035
1036 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1037 -ERR_INTERNET_DISCONNECTED, 1);
1038 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1039 -ERR_INTERNET_DISCONNECTED, 1);
1040}
1041
1042TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481043 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281044 base::HistogramTester histograms;
1045 session_params_.origins_to_force_quic_on.insert(
1046 HostPortPair::FromString("mail.example.org:443"));
1047 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271048 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281049
1050 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521051 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281052 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431053 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281054 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1055 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1056 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1057
1058 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1059
1060 CreateSession();
1061
1062 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1063 TestCompletionCallback callback;
1064 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1065 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1066 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1067
1068 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1069 -ERR_INTERNET_DISCONNECTED, 1);
1070 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1071 -ERR_INTERNET_DISCONNECTED, 1);
1072}
1073
tbansal180587c2017-02-16 15:13:231074TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411075 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231076 HostPortPair::FromString("mail.example.org:443"));
1077
1078 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521079 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361080 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431081 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1082 mock_quic_data.AddWrite(
1083 SYNCHRONOUS,
1084 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331085 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431086 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431087 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331088 ASYNC, ConstructServerResponseHeadersPacket(
1089 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1090 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411091 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331092 mock_quic_data.AddRead(
1093 ASYNC, ConstructServerDataPacket(
1094 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411095 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431096 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231097 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1098
1099 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1100
1101 CreateSession();
1102 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1103
1104 EXPECT_FALSE(
1105 test_socket_performance_watcher_factory_.rtt_notification_received());
1106 SendRequestAndExpectQuicResponse("hello!");
1107 EXPECT_TRUE(
1108 test_socket_performance_watcher_factory_.rtt_notification_received());
1109}
1110
1111TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411112 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231113 HostPortPair::FromString("mail.example.org:443"));
1114
1115 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521116 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361117 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431118 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1119 mock_quic_data.AddWrite(
1120 SYNCHRONOUS,
1121 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331122 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431123 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431124 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331125 ASYNC, ConstructServerResponseHeadersPacket(
1126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1127 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411128 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331129 mock_quic_data.AddRead(
1130 ASYNC, ConstructServerDataPacket(
1131 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411132 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431133 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231134 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1135
1136 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1137
1138 CreateSession();
1139 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1140
1141 EXPECT_FALSE(
1142 test_socket_performance_watcher_factory_.rtt_notification_received());
1143 SendRequestAndExpectQuicResponse("hello!");
1144 EXPECT_FALSE(
1145 test_socket_performance_watcher_factory_.rtt_notification_received());
1146}
1147
[email protected]1e960032013-12-20 19:00:201148TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411149 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571150 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471151
[email protected]1e960032013-12-20 19:00:201152 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521153 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361154 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431155 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1156 mock_quic_data.AddWrite(
1157 SYNCHRONOUS,
1158 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331159 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431160 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431161 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331162 ASYNC, ConstructServerResponseHeadersPacket(
1163 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1164 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411165 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331166 mock_quic_data.AddRead(
1167 ASYNC, ConstructServerDataPacket(
1168 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411169 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431170 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591171 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471172
rcha5399e02015-04-21 19:32:041173 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471174
[email protected]4dca587c2013-03-07 16:54:471175 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471176
[email protected]aa9b14d2013-05-10 23:45:191177 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471178
[email protected]98b20ce2013-05-10 05:55:261179 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461180 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191181 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261182 EXPECT_LT(0u, entries.size());
1183
1184 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291185 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001186 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1187 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261188 EXPECT_LT(0, pos);
1189
rchfd527212015-08-25 00:41:261190 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291191 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261192 entries, 0,
mikecirone8b85c432016-09-08 19:11:001193 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1194 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261195 EXPECT_LT(0, pos);
1196
Eric Romanaefc98c2018-12-18 21:38:011197 int packet_number;
1198 ASSERT_TRUE(entries[pos].GetIntegerValue("packet_number", &packet_number));
1199 EXPECT_EQ(1, packet_number);
[email protected]98b20ce2013-05-10 05:55:261200
rchfd527212015-08-25 00:41:261201 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1202 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001203 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1204 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261205 EXPECT_LT(0, pos);
1206
[email protected]98b20ce2013-05-10 05:55:261207 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291208 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001209 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1210 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261211 EXPECT_LT(0, pos);
1212
1213 int log_stream_id;
1214 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381215 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1216 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471217}
1218
rchbd089ab2017-05-26 23:05:041219TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411220 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041221 HostPortPair::FromString("mail.example.org:443"));
1222
1223 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521224 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041225 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431226 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1227 mock_quic_data.AddWrite(
1228 SYNCHRONOUS,
1229 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331230 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431231 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131232 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041233 response_headers["key1"] = std::string(30000, 'A');
1234 response_headers["key2"] = std::string(30000, 'A');
1235 response_headers["key3"] = std::string(30000, 'A');
1236 response_headers["key4"] = std::string(30000, 'A');
1237 response_headers["key5"] = std::string(30000, 'A');
1238 response_headers["key6"] = std::string(30000, 'A');
1239 response_headers["key7"] = std::string(30000, 'A');
1240 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331241 spdy::SpdyHeadersIR headers_frame(
1242 GetNthClientInitiatedBidirectionalStreamId(0),
1243 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131244 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1245 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041246 response_framer.SerializeFrame(headers_frame);
1247
Fan Yangac867502019-01-28 21:10:231248 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041249 size_t chunk_size = 1200;
1250 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1251 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431252 mock_quic_data.AddRead(
1253 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091254 packet_number++,
1255 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521256 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041257 }
1258
Renjief49758b2019-01-11 23:32:411259 quic::QuicString header = ConstructDataHeader(6);
rchbd089ab2017-05-26 23:05:041260 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331261 ASYNC, ConstructServerDataPacket(
1262 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411263 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041264 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431265 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1266 mock_quic_data.AddWrite(ASYNC,
1267 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041268
1269 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1270
1271 CreateSession();
1272
1273 SendRequestAndExpectQuicResponse("hello!");
1274}
1275
1276TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481277 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411278 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041279 HostPortPair::FromString("mail.example.org:443"));
1280
1281 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521282 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041283 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431284 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1285 mock_quic_data.AddWrite(
1286 SYNCHRONOUS,
1287 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331288 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431289 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131290 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041291 response_headers["key1"] = std::string(30000, 'A');
1292 response_headers["key2"] = std::string(30000, 'A');
1293 response_headers["key3"] = std::string(30000, 'A');
1294 response_headers["key4"] = std::string(30000, 'A');
1295 response_headers["key5"] = std::string(30000, 'A');
1296 response_headers["key6"] = std::string(30000, 'A');
1297 response_headers["key7"] = std::string(30000, 'A');
1298 response_headers["key8"] = std::string(30000, 'A');
1299 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331300 spdy::SpdyHeadersIR headers_frame(
1301 GetNthClientInitiatedBidirectionalStreamId(0),
1302 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131303 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1304 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041305 response_framer.SerializeFrame(headers_frame);
1306
Fan Yangac867502019-01-28 21:10:231307 uint64_t packet_number = 1;
rchbd089ab2017-05-26 23:05:041308 size_t chunk_size = 1200;
1309 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1310 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431311 mock_quic_data.AddRead(
1312 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091313 packet_number++,
1314 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521315 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041316 }
1317
Renjief49758b2019-01-11 23:32:411318 quic::QuicString header = ConstructDataHeader(6);
1319
rchbd089ab2017-05-26 23:05:041320 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331321 ASYNC, ConstructServerDataPacket(
1322 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
Renjief49758b2019-01-11 23:32:411323 false, true, 0, header + "hello!"));
rchbd089ab2017-05-26 23:05:041324 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431325 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1326 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331327 ASYNC, ConstructClientAckAndRstPacket(
1328 4, GetNthClientInitiatedBidirectionalStreamId(0),
1329 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041330
1331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1332
1333 CreateSession();
1334
1335 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1336 TestCompletionCallback callback;
1337 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1339 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1340}
1341
rcha2bd44b2016-07-02 00:42:551342TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411343 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551344
Ryan Hamilton9835e662018-08-02 05:36:271345 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551346
1347 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521348 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361349 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431350 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1351 mock_quic_data.AddWrite(
1352 SYNCHRONOUS,
1353 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331354 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431355 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431356 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331357 ASYNC, ConstructServerResponseHeadersPacket(
1358 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1359 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411360 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331361 mock_quic_data.AddRead(
1362 ASYNC, ConstructServerDataPacket(
1363 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411364 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431365 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551366 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1367
1368 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1369
1370 CreateSession();
1371
1372 SendRequestAndExpectQuicResponse("hello!");
1373 EXPECT_TRUE(
1374 test_socket_performance_watcher_factory_.rtt_notification_received());
1375}
1376
[email protected]cf3e3cd62014-02-05 16:16:161377TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411378 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591379 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491380 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161381
[email protected]cf3e3cd62014-02-05 16:16:161382 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521383 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361384 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431385 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1386 mock_quic_data.AddWrite(
1387 SYNCHRONOUS,
1388 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331389 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431390 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431391 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331392 ASYNC, ConstructServerResponseHeadersPacket(
1393 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1394 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411395 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331396 mock_quic_data.AddRead(
1397 ASYNC, ConstructServerDataPacket(
1398 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411399 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431400 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501401 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591402 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161403
rcha5399e02015-04-21 19:32:041404 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161405
tbansal0f56a39a2016-04-07 22:03:381406 EXPECT_FALSE(
1407 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161408 // There is no need to set up an alternate protocol job, because
1409 // no attempt will be made to speak to the proxy over TCP.
1410
rch9ae5b3b2016-02-11 00:36:291411 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161412 CreateSession();
1413
bnc62a44f022015-04-02 15:59:411414 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381415 EXPECT_TRUE(
1416 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161417}
1418
bnc313ba9c2015-06-11 15:42:311419// Regression test for https://crbug.com/492458. Test that for an HTTP
1420// connection through a QUIC proxy, the certificate exhibited by the proxy is
1421// checked against the proxy hostname, not the origin hostname.
1422TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291423 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311424 const std::string proxy_host = "www.example.org";
1425
mmenke6ddfbea2017-05-31 21:48:411426 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591427 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491428 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311429
alyssar2adf3ac2016-05-03 17:12:581430 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311431 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521432 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361433 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431434 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1435 mock_quic_data.AddWrite(
1436 SYNCHRONOUS,
1437 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331438 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431439 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431440 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331441 ASYNC, ConstructServerResponseHeadersPacket(
1442 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1443 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411444 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331445 mock_quic_data.AddRead(
1446 ASYNC, ConstructServerDataPacket(
1447 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411448 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431449 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501450 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591451 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311452 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1453
1454 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291455 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311456 ASSERT_TRUE(cert.get());
1457 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241458 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1459 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311460 ProofVerifyDetailsChromium verify_details;
1461 verify_details.cert_verify_result.verified_cert = cert;
1462 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561463 ProofVerifyDetailsChromium verify_details2;
1464 verify_details2.cert_verify_result.verified_cert = cert;
1465 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311466
1467 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091468 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321469 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271470 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311471 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1472}
1473
rchbe69cb902016-02-11 01:10:481474TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341475 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481476 HostPortPair origin("www.example.org", 443);
1477 HostPortPair alternative("mail.example.org", 443);
1478
1479 base::FilePath certs_dir = GetTestCertsDirectory();
1480 scoped_refptr<X509Certificate> cert(
1481 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1482 ASSERT_TRUE(cert.get());
1483 // TODO(rch): the connection should be "to" the origin, so if the cert is
1484 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241485 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1486 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481487 ProofVerifyDetailsChromium verify_details;
1488 verify_details.cert_verify_result.verified_cert = cert;
1489 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1490
alyssar2adf3ac2016-05-03 17:12:581491 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481492 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521493 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361494 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431495 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1496 mock_quic_data.AddWrite(
1497 SYNCHRONOUS,
1498 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331499 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431500 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431501 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331502 ASYNC, ConstructServerResponseHeadersPacket(
1503 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1504 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411505 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331506 mock_quic_data.AddRead(
1507 ASYNC, ConstructServerDataPacket(
1508 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411509 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431510 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481511 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1512 mock_quic_data.AddRead(ASYNC, 0);
1513 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1514
1515 request_.url = GURL("https://" + origin.host());
1516 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271517 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091518 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321519 CreateSession();
rchbe69cb902016-02-11 01:10:481520
1521 SendRequestAndExpectQuicResponse("hello!");
1522}
1523
zhongyief3f4ce52017-07-05 23:53:281524TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521525 quic::QuicTransportVersion unsupported_version =
1526 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281527 // Add support for another QUIC version besides |version_|. Also find a
1528 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521529 for (const quic::QuicTransportVersion& version :
1530 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281531 if (version == version_)
1532 continue;
1533 if (supported_versions_.size() != 2) {
1534 supported_versions_.push_back(version);
1535 continue;
1536 }
1537 unsupported_version = version;
1538 break;
1539 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521540 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281541
1542 // Set up alternative service to use QUIC with a version that is not
1543 // supported.
1544 url::SchemeHostPort server(request_.url);
1545 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1546 443);
1547 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1548 http_server_properties_.SetQuicAlternativeService(
1549 server, alternative_service, expiration, {unsupported_version});
1550
1551 AlternativeServiceInfoVector alt_svc_info_vector =
1552 http_server_properties_.GetAlternativeServiceInfos(server);
1553 EXPECT_EQ(1u, alt_svc_info_vector.size());
1554 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1555 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1556 EXPECT_EQ(unsupported_version,
1557 alt_svc_info_vector[0].advertised_versions()[0]);
1558
1559 // First request should still be sent via TCP as the QUIC version advertised
1560 // in the stored AlternativeService is not supported by the client. However,
1561 // the response from the server will advertise new Alt-Svc with supported
1562 // versions.
1563 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521564 GenerateQuicVersionsListForAltSvcHeader(
1565 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281566 std::string altsvc_header =
1567 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1568 advertised_versions_list_str.c_str());
1569 MockRead http_reads[] = {
1570 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1571 MockRead("hello world"),
1572 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1573 MockRead(ASYNC, OK)};
1574
Ryan Sleevib8d7ea02018-05-07 20:01:011575 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281576 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081577 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281578 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1579
1580 // Second request should be sent via QUIC as a new list of verions supported
1581 // by the client has been advertised by the server.
1582 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521583 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281584 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431585 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1586 mock_quic_data.AddWrite(
1587 SYNCHRONOUS,
1588 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331589 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431590 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431591 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331592 ASYNC, ConstructServerResponseHeadersPacket(
1593 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1594 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411595 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331596 mock_quic_data.AddRead(
1597 ASYNC, ConstructServerDataPacket(
1598 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411599 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431600 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281601 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1602 mock_quic_data.AddRead(ASYNC, 0); // EOF
1603
1604 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1605
1606 AddHangingNonAlternateProtocolSocketData();
1607
1608 CreateSession(supported_versions_);
1609
1610 SendRequestAndExpectHttpResponse("hello world");
1611 SendRequestAndExpectQuicResponse("hello!");
1612
1613 // Check alternative service list is updated with new versions.
1614 alt_svc_info_vector =
1615 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1616 EXPECT_EQ(1u, alt_svc_info_vector.size());
1617 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1618 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1619 // Advertised versions will be lised in a sorted order.
1620 std::sort(supported_versions_.begin(), supported_versions_.end());
1621 EXPECT_EQ(supported_versions_[0],
1622 alt_svc_info_vector[0].advertised_versions()[0]);
1623 EXPECT_EQ(supported_versions_[1],
1624 alt_svc_info_vector[0].advertised_versions()[1]);
1625}
1626
bncaccd4962017-04-06 21:00:261627// Regression test for https://crbug.com/546991.
1628// The server might not be able to serve a request on an alternative connection,
1629// and might send a 421 Misdirected Request response status to indicate this.
1630// HttpNetworkTransaction should reset the request and retry without using
1631// alternative services.
1632TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1633 // Set up alternative service to use QUIC.
1634 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1635 // that overrides |enable_alternative_services|.
1636 url::SchemeHostPort server(request_.url);
1637 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1638 443);
1639 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211640 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441641 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261642
davidbena4449722017-05-05 23:30:531643 // First try: The alternative job uses QUIC and reports an HTTP 421
1644 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1645 // paused at Connect(), so it will never exit the socket pool. This ensures
1646 // that the alternate job always wins the race and keeps whether the
1647 // |http_data| exits the socket pool before the main job is aborted
1648 // deterministic. The first main job gets aborted without the socket pool ever
1649 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261650 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521651 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361652 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431653 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1654 mock_quic_data.AddWrite(
1655 SYNCHRONOUS,
1656 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331657 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431658 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331659 mock_quic_data.AddRead(
1660 ASYNC, ConstructServerResponseHeadersPacket(
1661 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1662 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261663 mock_quic_data.AddRead(ASYNC, OK);
1664 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1665
davidbena4449722017-05-05 23:30:531666 // Second try: The main job uses TCP, and there is no alternate job. Once the
1667 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1668 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261669 // Note that if there was an alternative QUIC Job created for the second try,
1670 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1671 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531672 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1673 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1674 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1675 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1676 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1677 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011678 reads, writes);
bncaccd4962017-04-06 21:00:261679 socket_factory_.AddSocketDataProvider(&http_data);
1680 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1681
bncaccd4962017-04-06 21:00:261682 CreateSession();
1683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531684
1685 // Run until |mock_quic_data| has failed and |http_data| has paused.
1686 TestCompletionCallback callback;
1687 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1688 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1689 base::RunLoop().RunUntilIdle();
1690
1691 // |mock_quic_data| must have run to completion.
1692 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1693 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1694
1695 // Now that the QUIC data has been consumed, unblock |http_data|.
1696 http_data.socket()->OnConnectComplete(MockConnect());
1697
1698 // The retry logic must hide the 421 status. The transaction succeeds on
1699 // |http_data|.
1700 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261701 CheckWasHttpResponse(&trans);
1702 CheckResponsePort(&trans, 443);
1703 CheckResponseData(&trans, "hello!");
1704}
1705
[email protected]1e960032013-12-20 19:00:201706TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411707 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571708 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301709
tbansalfdf5665b2015-09-21 22:46:401710 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521711 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361712 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431713 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401714 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401715 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371716 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361717 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431718 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301719 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401720 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431721 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401722
1723 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1724 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301725
1726 CreateSession();
1727
tbansal0f56a39a2016-04-07 22:03:381728 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401729 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401731 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161732 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1734 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381735 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531736
1737 NetErrorDetails details;
1738 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521739 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401740 }
[email protected]cebe3282013-05-22 23:49:301741}
1742
tbansalc8a94ea2015-11-02 23:58:511743TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1744 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411745 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571746 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511747
1748 MockRead http_reads[] = {
1749 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1750 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1751 MockRead(ASYNC, OK)};
1752
Ryan Sleevib8d7ea02018-05-07 20:01:011753 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511754 socket_factory_.AddSocketDataProvider(&data);
1755 SSLSocketDataProvider ssl(ASYNC, OK);
1756 socket_factory_.AddSSLSocketDataProvider(&ssl);
1757
1758 CreateSession();
1759
1760 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381761 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511762}
1763
bncc958faa2015-07-31 18:14:521764TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521765 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561766 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1767 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521768 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1769 MockRead(ASYNC, OK)};
1770
Ryan Sleevib8d7ea02018-05-07 20:01:011771 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521772 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081773 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561774 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521775
1776 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521777 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361778 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431779 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1780 mock_quic_data.AddWrite(
1781 SYNCHRONOUS,
1782 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331783 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431784 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431785 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331786 ASYNC, ConstructServerResponseHeadersPacket(
1787 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1788 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411789 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331790 mock_quic_data.AddRead(
1791 ASYNC, ConstructServerDataPacket(
1792 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411793 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431794 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521795 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591796 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521797
1798 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1799
rtennetib8e80fb2016-05-16 00:12:091800 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321801 CreateSession();
bncc958faa2015-07-31 18:14:521802
1803 SendRequestAndExpectHttpResponse("hello world");
1804 SendRequestAndExpectQuicResponse("hello!");
1805}
1806
zhongyia00ca012017-07-06 23:36:391807TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1808 // Both server advertises and client supports two QUIC versions.
1809 // Only |version_| is advertised and supported.
1810 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1811 // PacketMakers are using |version_|.
1812
1813 // Add support for another QUIC version besides |version_| on the client side.
1814 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521815 quic::QuicTransportVersion advertised_version_2 =
1816 quic::QUIC_VERSION_UNSUPPORTED;
1817 for (const quic::QuicTransportVersion& version :
1818 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391819 if (version == version_)
1820 continue;
1821 if (supported_versions_.size() != 2) {
1822 supported_versions_.push_back(version);
1823 continue;
1824 }
1825 advertised_version_2 = version;
1826 break;
1827 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521828 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391829
1830 std::string QuicAltSvcWithVersionHeader =
1831 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1832 advertised_version_2, version_);
1833
1834 MockRead http_reads[] = {
1835 MockRead("HTTP/1.1 200 OK\r\n"),
1836 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1837 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1838 MockRead(ASYNC, OK)};
1839
Ryan Sleevib8d7ea02018-05-07 20:01:011840 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391841 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081842 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391843 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1844
1845 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521846 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391847 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431848 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1849 mock_quic_data.AddWrite(
1850 SYNCHRONOUS,
1851 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331852 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431853 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431854 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331855 ASYNC, ConstructServerResponseHeadersPacket(
1856 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1857 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411858 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331859 mock_quic_data.AddRead(
1860 ASYNC, ConstructServerDataPacket(
1861 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411862 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431863 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391864 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1865 mock_quic_data.AddRead(ASYNC, 0); // EOF
1866
1867 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1868
1869 AddHangingNonAlternateProtocolSocketData();
1870 CreateSession(supported_versions_);
1871
1872 SendRequestAndExpectHttpResponse("hello world");
1873 SendRequestAndExpectQuicResponse("hello!");
1874}
1875
1876TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1877 // Client and server mutually support more than one QUIC_VERSION.
1878 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1879 // which is verified as the PacketMakers are using |version_|.
1880
Ryan Hamilton8d9ee76e2018-05-29 23:52:521881 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1882 for (const quic::QuicTransportVersion& version :
1883 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391884 if (version == version_)
1885 continue;
1886 common_version_2 = version;
1887 break;
1888 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521889 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391890
1891 supported_versions_.push_back(
1892 common_version_2); // Supported but unpreferred.
1893
1894 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1895 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1896
1897 MockRead http_reads[] = {
1898 MockRead("HTTP/1.1 200 OK\r\n"),
1899 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1900 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1901 MockRead(ASYNC, OK)};
1902
Ryan Sleevib8d7ea02018-05-07 20:01:011903 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391904 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081905 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391906 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1907
1908 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521909 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391910 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431911 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1912 mock_quic_data.AddWrite(
1913 SYNCHRONOUS,
1914 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331915 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431916 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431917 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331918 ASYNC, ConstructServerResponseHeadersPacket(
1919 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1920 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411921 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331922 mock_quic_data.AddRead(
1923 ASYNC, ConstructServerDataPacket(
1924 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411925 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431926 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391927 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1928 mock_quic_data.AddRead(ASYNC, 0); // EOF
1929
1930 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1931
1932 AddHangingNonAlternateProtocolSocketData();
1933 CreateSession(supported_versions_);
1934
1935 SendRequestAndExpectHttpResponse("hello world");
1936 SendRequestAndExpectQuicResponse("hello!");
1937}
1938
rchf47265dc2016-03-21 21:33:121939TEST_P(QuicNetworkTransactionTest,
1940 UseAlternativeServiceWithProbabilityForQuic) {
1941 MockRead http_reads[] = {
1942 MockRead("HTTP/1.1 200 OK\r\n"),
1943 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1944 MockRead("hello world"),
1945 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1946 MockRead(ASYNC, OK)};
1947
Ryan Sleevib8d7ea02018-05-07 20:01:011948 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121949 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081950 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121951 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1952
1953 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521954 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361955 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431956 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1957 mock_quic_data.AddWrite(
1958 SYNCHRONOUS,
1959 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331960 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431961 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431962 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331963 ASYNC, ConstructServerResponseHeadersPacket(
1964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1965 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:411966 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:331967 mock_quic_data.AddRead(
1968 ASYNC, ConstructServerDataPacket(
1969 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:411970 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431971 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121972 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1973 mock_quic_data.AddRead(ASYNC, 0); // EOF
1974
1975 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1976
rtennetib8e80fb2016-05-16 00:12:091977 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121978 CreateSession();
1979
1980 SendRequestAndExpectHttpResponse("hello world");
1981 SendRequestAndExpectQuicResponse("hello!");
1982}
1983
zhongyi3d4a55e72016-04-22 20:36:461984TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1985 MockRead http_reads[] = {
1986 MockRead("HTTP/1.1 200 OK\r\n"),
1987 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1988 MockRead("hello world"),
1989 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1990 MockRead(ASYNC, OK)};
1991
Ryan Sleevib8d7ea02018-05-07 20:01:011992 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461993 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081994 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461995 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1996
1997 CreateSession();
bncb26024382016-06-29 02:39:451998 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461999 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:452000 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:462001 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402002 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462003 session_->http_server_properties();
2004 url::SchemeHostPort http_server("http", "mail.example.org", 443);
2005 url::SchemeHostPort https_server("https", "mail.example.org", 443);
2006 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:462007 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:342008 2u,
2009 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:452010 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:342011 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:462012}
2013
2014TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
2015 MockRead http_reads[] = {
2016 MockRead("HTTP/1.1 200 OK\r\n"),
2017 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
2018 MockRead("hello world"),
2019 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2020 MockRead(ASYNC, OK)};
2021
Ryan Sleevib8d7ea02018-05-07 20:01:012022 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:082023 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:462024
2025 socket_factory_.AddSocketDataProvider(&http_data);
2026 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2027 socket_factory_.AddSocketDataProvider(&http_data);
2028 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2029
2030 CreateSession();
2031
2032 // Send https request and set alternative services if response header
2033 // advertises alternative service for mail.example.org.
2034 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:402035 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:462036 session_->http_server_properties();
2037
2038 const url::SchemeHostPort https_server(request_.url);
2039 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:342040 EXPECT_EQ(
2041 2u,
2042 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:462043
2044 // Send http request to the same origin but with diffrent scheme, should not
2045 // use QUIC.
2046 request_.url = GURL("http://mail.example.org:443");
2047 SendRequestAndExpectHttpResponse("hello world");
2048}
2049
zhongyie537a002017-06-27 16:48:212050TEST_P(QuicNetworkTransactionTest,
2051 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:442052 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522053 for (const quic::QuicTransportVersion& version :
2054 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:442055 if (version == version_)
2056 continue;
2057 supported_versions_.push_back(version);
2058 break;
2059 }
2060
zhongyie537a002017-06-27 16:48:212061 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522062 GenerateQuicVersionsListForAltSvcHeader(
2063 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212064 std::string altsvc_header =
2065 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2066 advertised_versions_list_str.c_str());
2067 MockRead http_reads[] = {
2068 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2069 MockRead("hello world"),
2070 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2071 MockRead(ASYNC, OK)};
2072
Ryan Sleevib8d7ea02018-05-07 20:01:012073 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212074 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082075 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212076 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2077
2078 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522079 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212080 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432081 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2082 mock_quic_data.AddWrite(
2083 SYNCHRONOUS,
2084 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332085 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432086 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432087 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332088 ASYNC, ConstructServerResponseHeadersPacket(
2089 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2090 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412091 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332092 mock_quic_data.AddRead(
2093 ASYNC, ConstructServerDataPacket(
2094 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412095 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432096 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212097 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2098 mock_quic_data.AddRead(ASYNC, 0); // EOF
2099
2100 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2101
2102 AddHangingNonAlternateProtocolSocketData();
2103
zhongyi86838d52017-06-30 01:19:442104 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212105
2106 SendRequestAndExpectHttpResponse("hello world");
2107 SendRequestAndExpectQuicResponse("hello!");
2108
2109 // Check alternative service is set with only mutually supported versions.
2110 const url::SchemeHostPort https_server(request_.url);
2111 const AlternativeServiceInfoVector alt_svc_info_vector =
2112 session_->http_server_properties()->GetAlternativeServiceInfos(
2113 https_server);
2114 EXPECT_EQ(1u, alt_svc_info_vector.size());
2115 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2116 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2117 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442118 std::sort(supported_versions_.begin(), supported_versions_.end());
2119 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212120 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442121 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212122 alt_svc_info_vector[0].advertised_versions()[1]);
2123}
2124
danzh3134c2562016-08-12 14:07:522125TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442126 std::string altsvc_header =
2127 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072128 MockRead http_reads[] = {
2129 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2130 MockRead("hello world"),
2131 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2132 MockRead(ASYNC, OK)};
2133
Ryan Sleevib8d7ea02018-05-07 20:01:012134 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072135 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082136 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072137 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2138
2139 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522140 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362141 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432142 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2143 mock_quic_data.AddWrite(
2144 SYNCHRONOUS,
2145 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332146 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432147 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432148 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332149 ASYNC, ConstructServerResponseHeadersPacket(
2150 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2151 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:412152 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332153 mock_quic_data.AddRead(
2154 ASYNC, ConstructServerDataPacket(
2155 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412156 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432157 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072158 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592159 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072160
2161 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2162
rtennetib8e80fb2016-05-16 00:12:092163 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322164 CreateSession();
bnc8be55ebb2015-10-30 14:12:072165
2166 SendRequestAndExpectHttpResponse("hello world");
2167 SendRequestAndExpectQuicResponse("hello!");
2168}
2169
zhongyi6b5a3892016-03-12 04:46:202170TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092171 if (version_ == quic::QUIC_VERSION_99) {
2172 // Not available under version 99
2173 return;
2174 }
zhongyi6b5a3892016-03-12 04:46:202175 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522176 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362177 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432178 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2179 mock_quic_data.AddWrite(
2180 SYNCHRONOUS,
2181 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332182 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432183 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332184 mock_quic_data.AddRead(
2185 ASYNC, ConstructServerResponseHeadersPacket(
2186 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2187 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202188 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522189 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432190 mock_quic_data.AddRead(SYNCHRONOUS,
2191 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522192 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432193 "connection migration with port change only"));
2194 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Renjief49758b2019-01-11 23:32:412195 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:332196 mock_quic_data.AddRead(
2197 SYNCHRONOUS, ConstructServerDataPacket(
2198 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
Renjief49758b2019-01-11 23:32:412199 true, 0, header + "hello!"));
Fan Yang32c5a112018-12-10 20:06:332200 mock_quic_data.AddWrite(SYNCHRONOUS,
2201 ConstructClientAckAndRstPacket(
2202 4, GetNthClientInitiatedBidirectionalStreamId(0),
2203 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202204 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2205 mock_quic_data.AddRead(ASYNC, 0); // EOF
2206
2207 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2208
2209 // The non-alternate protocol job needs to hang in order to guarantee that
2210 // the alternate-protocol job will "win".
2211 AddHangingNonAlternateProtocolSocketData();
2212
2213 // In order for a new QUIC session to be established via alternate-protocol
2214 // without racing an HTTP connection, we need the host resolution to happen
2215 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2216 // connection to the the server, in this test we require confirmation
2217 // before encrypting so the HTTP job will still start.
2218 host_resolver_.set_synchronous_mode(true);
2219 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2220 "");
zhongyi6b5a3892016-03-12 04:46:202221
2222 CreateSession();
2223 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272224 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202225
bnc691fda62016-08-12 00:43:162226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202227 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362228 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012229 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202230
2231 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522232 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012233 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202234
2235 // Check whether this transaction is correctly marked as received a go-away
2236 // because of migrating port.
2237 NetErrorDetails details;
2238 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162239 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202240 EXPECT_TRUE(details.quic_port_migration_detected);
2241}
2242
Zhongyi Shia6b68d112018-09-24 07:49:032243// This test verifies that a new QUIC connection will be attempted on the
2244// alternate network if the original QUIC connection fails with idle timeout
2245// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2246// alternate network as well, QUIC is marked as broken and the brokenness will
2247// not expire when default network changes.
2248TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2249 SetUpTestForRetryConnectionOnAlternateNetwork();
2250
2251 std::string request_data;
2252 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2253 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2254
2255 // The request will initially go out over QUIC.
2256 MockQuicData quic_data;
2257 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2258 int packet_num = 1;
2259 quic_data.AddWrite(SYNCHRONOUS,
2260 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2261 // Retranmit the handshake messages.
2262 quic_data.AddWrite(SYNCHRONOUS,
2263 client_maker_.MakeDummyCHLOPacket(packet_num++));
2264 quic_data.AddWrite(SYNCHRONOUS,
2265 client_maker_.MakeDummyCHLOPacket(packet_num++));
2266 quic_data.AddWrite(SYNCHRONOUS,
2267 client_maker_.MakeDummyCHLOPacket(packet_num++));
2268 quic_data.AddWrite(SYNCHRONOUS,
2269 client_maker_.MakeDummyCHLOPacket(packet_num++));
2270 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2271 if (version_ <= quic::QUIC_VERSION_39) {
2272 quic_data.AddWrite(SYNCHRONOUS,
2273 client_maker_.MakeDummyCHLOPacket(packet_num++));
2274 }
2275 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2276 quic_data.AddWrite(SYNCHRONOUS,
2277 client_maker_.MakeConnectionClosePacket(
2278 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2279 "No recent network activity."));
2280 quic_data.AddSocketDataToFactory(&socket_factory_);
2281
2282 // Add successful TCP data so that TCP job will succeed.
2283 MockWrite http_writes[] = {
2284 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2285 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2286 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2287
2288 MockRead http_reads[] = {
2289 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2290 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2291 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2292 SequencedSocketData http_data(http_reads, http_writes);
2293 socket_factory_.AddSocketDataProvider(&http_data);
2294 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2295
2296 // Add data for the second QUIC connection to fail.
2297 MockQuicData quic_data2;
2298 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2299 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2300 quic_data2.AddSocketDataToFactory(&socket_factory_);
2301
2302 // Resolve the host resolution synchronously.
2303 host_resolver_.set_synchronous_mode(true);
2304 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2305 "");
Zhongyi Shia6b68d112018-09-24 07:49:032306
2307 CreateSession();
2308 session_->quic_stream_factory()->set_require_confirmation(true);
2309 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2310 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2311 QuicStreamFactoryPeer::SetAlarmFactory(
2312 session_->quic_stream_factory(),
2313 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2314 &clock_));
2315 // Add alternate protocol mapping to race QUIC and TCP.
2316 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2317 // peer.
2318 AddQuicAlternateProtocolMapping(
2319 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2320
2321 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2322 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362323 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032324 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2325
2326 // Pump the message loop to get the request started.
2327 // Request will be served with TCP job.
2328 base::RunLoop().RunUntilIdle();
2329 EXPECT_THAT(callback.WaitForResult(), IsOk());
2330 CheckResponseData(&trans, "TCP succeeds");
2331
2332 // Fire the retransmission alarm, from this point, connection will idle
2333 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062334 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182335 quic_fix_time_of_first_packet_sent_after_receiving)) {
2336 quic_task_runner_->RunNextTask();
2337 }
Zhongyi Shia6b68d112018-09-24 07:49:032338 // Fast forward to idle timeout the original connection. A new connection will
2339 // be kicked off on the alternate network.
2340 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2341 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2342 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2343
2344 // Run the message loop to execute posted tasks, which will report job status.
2345 base::RunLoop().RunUntilIdle();
2346
2347 // Verify that QUIC is marked as broken.
2348 ExpectBrokenAlternateProtocolMapping();
2349
2350 // Deliver a message to notify the new network becomes default, the brokenness
2351 // will not expire as QUIC is broken on both networks.
2352 scoped_mock_change_notifier_->mock_network_change_notifier()
2353 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2354 ExpectBrokenAlternateProtocolMapping();
2355
2356 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2357 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2358}
2359
2360// This test verifies that a new QUIC connection will be attempted on the
2361// alternate network if the original QUIC connection fails with idle timeout
2362// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2363// alternate network, QUIC is marked as broken. The brokenness will expire when
2364// the default network changes.
2365TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2366 SetUpTestForRetryConnectionOnAlternateNetwork();
2367
2368 std::string request_data;
2369 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2370 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2371
2372 // The request will initially go out over QUIC.
2373 MockQuicData quic_data;
2374 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2375 int packet_num = 1;
2376 quic_data.AddWrite(SYNCHRONOUS,
2377 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2378 // Retranmit the handshake messages.
2379 quic_data.AddWrite(SYNCHRONOUS,
2380 client_maker_.MakeDummyCHLOPacket(packet_num++));
2381 quic_data.AddWrite(SYNCHRONOUS,
2382 client_maker_.MakeDummyCHLOPacket(packet_num++));
2383 quic_data.AddWrite(SYNCHRONOUS,
2384 client_maker_.MakeDummyCHLOPacket(packet_num++));
2385 quic_data.AddWrite(SYNCHRONOUS,
2386 client_maker_.MakeDummyCHLOPacket(packet_num++));
2387 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2388 if (version_ <= quic::QUIC_VERSION_39) {
2389 quic_data.AddWrite(SYNCHRONOUS,
2390 client_maker_.MakeDummyCHLOPacket(packet_num++));
2391 }
2392 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2393 quic_data.AddWrite(SYNCHRONOUS,
2394 client_maker_.MakeConnectionClosePacket(
2395 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2396 "No recent network activity."));
2397 quic_data.AddSocketDataToFactory(&socket_factory_);
2398
2399 // Add successful TCP data so that TCP job will succeed.
2400 MockWrite http_writes[] = {
2401 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2402 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2403 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2404
2405 MockRead http_reads[] = {
2406 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2407 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2408 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2409 SequencedSocketData http_data(http_reads, http_writes);
2410 socket_factory_.AddSocketDataProvider(&http_data);
2411 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2412
2413 // Quic connection will be retried on the alternate network after the initial
2414 // one fails on the default network.
2415 MockQuicData quic_data2;
2416 quic::QuicStreamOffset header_stream_offset = 0;
2417 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2418 quic_data2.AddWrite(SYNCHRONOUS,
2419 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2420
2421 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2422 quic_data2.AddWrite(SYNCHRONOUS,
2423 ConstructInitialSettingsPacket(2, &header_stream_offset));
2424 quic_data2.AddSocketDataToFactory(&socket_factory_);
2425
2426 // Resolve the host resolution synchronously.
2427 host_resolver_.set_synchronous_mode(true);
2428 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2429 "");
Zhongyi Shia6b68d112018-09-24 07:49:032430
2431 CreateSession();
2432 session_->quic_stream_factory()->set_require_confirmation(true);
2433 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2434 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2435 QuicStreamFactoryPeer::SetAlarmFactory(
2436 session_->quic_stream_factory(),
2437 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2438 &clock_));
2439 // Add alternate protocol mapping to race QUIC and TCP.
2440 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2441 // peer.
2442 AddQuicAlternateProtocolMapping(
2443 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2444
2445 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2446 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362447 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032448 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2449
2450 // Pump the message loop to get the request started.
2451 // Request will be served with TCP job.
2452 base::RunLoop().RunUntilIdle();
2453 EXPECT_THAT(callback.WaitForResult(), IsOk());
2454 CheckResponseData(&trans, "TCP succeeds");
2455
2456 // Fire the retransmission alarm, after which connection will idle
2457 // timeout after 4 seconds.
Michael Warres112212822018-12-26 17:51:062458 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182459 quic_fix_time_of_first_packet_sent_after_receiving)) {
2460 quic_task_runner_->RunNextTask();
2461 }
Zhongyi Shia6b68d112018-09-24 07:49:032462 // Fast forward to idle timeout the original connection. A new connection will
2463 // be kicked off on the alternate network.
2464 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2465 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2466 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2467
2468 // The second connection hasn't finish handshake, verify that QUIC is not
2469 // marked as broken.
2470 ExpectQuicAlternateProtocolMapping();
2471 // Explicitly confirm the handshake on the second connection.
2472 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2473 quic::QuicSession::HANDSHAKE_CONFIRMED);
2474 // Run message loop to execute posted tasks, which will notify JoController
2475 // about the orphaned job status.
2476 base::RunLoop().RunUntilIdle();
2477
2478 // Verify that QUIC is marked as broken.
2479 ExpectBrokenAlternateProtocolMapping();
2480
2481 // Deliver a message to notify the new network becomes default, the previous
2482 // brokenness will be clear as the brokenness is bond with old default
2483 // network.
2484 scoped_mock_change_notifier_->mock_network_change_notifier()
2485 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2486 ExpectQuicAlternateProtocolMapping();
2487
2488 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2489 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2490}
2491
2492// This test verifies that a new QUIC connection will be attempted on the
2493// alternate network if the original QUIC connection fails with idle timeout
2494// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2495// alternative network succeeds, QUIC is not marked as broken.
2496TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2497 SetUpTestForRetryConnectionOnAlternateNetwork();
2498
2499 std::string request_data;
2500 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2501 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2502
2503 // The request will initially go out over QUIC.
2504 MockQuicData quic_data;
2505 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2506 int packet_num = 1;
2507 quic_data.AddWrite(SYNCHRONOUS,
2508 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2509 // Retranmit the handshake messages.
2510 quic_data.AddWrite(SYNCHRONOUS,
2511 client_maker_.MakeDummyCHLOPacket(packet_num++));
2512 quic_data.AddWrite(SYNCHRONOUS,
2513 client_maker_.MakeDummyCHLOPacket(packet_num++));
2514 quic_data.AddWrite(SYNCHRONOUS,
2515 client_maker_.MakeDummyCHLOPacket(packet_num++));
2516 quic_data.AddWrite(SYNCHRONOUS,
2517 client_maker_.MakeDummyCHLOPacket(packet_num++));
2518 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2519 // quic_fix_has_pending_crypto_data is introduced and enabled.
2520 if (version_ <= quic::QUIC_VERSION_39) {
2521 quic_data.AddWrite(SYNCHRONOUS,
2522 client_maker_.MakeDummyCHLOPacket(packet_num++));
2523 }
2524 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2525 quic_data.AddWrite(SYNCHRONOUS,
2526 client_maker_.MakeConnectionClosePacket(
2527 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2528 "No recent network activity."));
2529 quic_data.AddSocketDataToFactory(&socket_factory_);
2530
2531 // Add hanging TCP data so that TCP job will never succeeded.
2532 AddHangingNonAlternateProtocolSocketData();
2533
2534 // Quic connection will then be retried on the alternate network.
2535 MockQuicData quic_data2;
2536 quic::QuicStreamOffset header_stream_offset = 0;
2537 quic_data2.AddWrite(SYNCHRONOUS,
2538 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2539
Renjief49758b2019-01-11 23:32:412540 const quic::QuicString body = "hello!";
2541 quic::QuicString header = ConstructDataHeader(body.length());
2542
Zhongyi Shia6b68d112018-09-24 07:49:032543 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2544 quic_data2.AddWrite(SYNCHRONOUS,
2545 ConstructInitialSettingsPacket(2, &header_stream_offset));
2546 quic_data2.AddWrite(
2547 SYNCHRONOUS,
2548 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332549 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032550 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032551 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332552 ASYNC, ConstructServerResponseHeadersPacket(
2553 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2554 GetResponseHeaders("200 OK")));
2555 quic_data2.AddRead(
2556 ASYNC, ConstructServerDataPacket(
2557 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:412558 0, header + body));
Zhongyi Shia6b68d112018-09-24 07:49:032559 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2560 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2561 quic_data2.AddSocketDataToFactory(&socket_factory_);
2562
2563 // Resolve the host resolution synchronously.
2564 host_resolver_.set_synchronous_mode(true);
2565 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2566 "");
Zhongyi Shia6b68d112018-09-24 07:49:032567
2568 CreateSession();
2569 session_->quic_stream_factory()->set_require_confirmation(true);
2570 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2571 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2572 QuicStreamFactoryPeer::SetAlarmFactory(
2573 session_->quic_stream_factory(),
2574 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2575 &clock_));
2576 // Add alternate protocol mapping to race QUIC and TCP.
2577 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2578 // peer.
2579 AddQuicAlternateProtocolMapping(
2580 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2581
2582 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2583 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362584 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
Zhongyi Shia6b68d112018-09-24 07:49:032585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2586
2587 // Pump the message loop to get the request started.
2588 base::RunLoop().RunUntilIdle();
Michael Warres112212822018-12-26 17:51:062589 if (!GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:182590 quic_fix_time_of_first_packet_sent_after_receiving)) {
2591 quic_task_runner_->RunNextTask();
2592 }
Zhongyi Shia6b68d112018-09-24 07:49:032593
2594 // Fast forward to idle timeout the original connection. A new connection will
2595 // be kicked off on the alternate network.
2596 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2597 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2598 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2599
2600 // Verify that QUIC is not marked as broken.
2601 ExpectQuicAlternateProtocolMapping();
2602 // Explicitly confirm the handshake on the second connection.
2603 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2604 quic::QuicSession::HANDSHAKE_CONFIRMED);
2605
2606 // Read the response.
2607 EXPECT_THAT(callback.WaitForResult(), IsOk());
Renjief49758b2019-01-11 23:32:412608 CheckResponseData(&trans, body);
Zhongyi Shia6b68d112018-09-24 07:49:032609 // Verify that QUIC is not marked as broken.
2610 ExpectQuicAlternateProtocolMapping();
2611
2612 // Deliver a message to notify the new network becomes default.
2613 scoped_mock_change_notifier_->mock_network_change_notifier()
2614 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2615 ExpectQuicAlternateProtocolMapping();
2616 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2617 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2618}
2619
rch9ecde09b2017-04-08 00:18:232620// Verify that if a QUIC connection times out, the QuicHttpStream will
2621// return QUIC_PROTOCOL_ERROR.
2622TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482623 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412624 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232625
2626 // The request will initially go out over QUIC.
2627 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522628 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132629 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232630 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2631
2632 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522633 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2634 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432635 quic_data.AddWrite(SYNCHRONOUS,
2636 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332637 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2638 true, priority, GetRequestHeaders("GET", "https", "/"),
2639 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232640
2641 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522642 quic::QuicStreamOffset settings_offset = header_stream_offset;
2643 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432644 quic_data.AddWrite(SYNCHRONOUS,
2645 client_maker_.MakeInitialSettingsPacketAndSaveData(
2646 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232647 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092648 quic_data.AddWrite(SYNCHRONOUS,
2649 client_maker_.MakeDataPacket(
2650 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2651 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232652 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092653 quic_data.AddWrite(SYNCHRONOUS,
2654 client_maker_.MakeDataPacket(
2655 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2656 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232657 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092658 quic_data.AddWrite(SYNCHRONOUS,
2659 client_maker_.MakeDataPacket(
2660 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2661 false, 0, request_data));
2662 quic_data.AddWrite(SYNCHRONOUS,
2663 client_maker_.MakeDataPacket(
2664 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2665 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232666 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092667 quic_data.AddWrite(SYNCHRONOUS,
2668 client_maker_.MakeDataPacket(
2669 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2670 false, 0, request_data));
2671 quic_data.AddWrite(SYNCHRONOUS,
2672 client_maker_.MakeDataPacket(
2673 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2674 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232675 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092676 quic_data.AddWrite(SYNCHRONOUS,
2677 client_maker_.MakeDataPacket(
2678 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2679 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522680 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092681 SYNCHRONOUS, client_maker_.MakeDataPacket(
2682 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2683 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232684
Zhongyi Shi32f2fd02018-04-16 18:23:432685 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522686 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432687 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222688
rch9ecde09b2017-04-08 00:18:232689 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2690 quic_data.AddRead(ASYNC, OK);
2691 quic_data.AddSocketDataToFactory(&socket_factory_);
2692
2693 // In order for a new QUIC session to be established via alternate-protocol
2694 // without racing an HTTP connection, we need the host resolution to happen
2695 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2696 // connection to the the server, in this test we require confirmation
2697 // before encrypting so the HTTP job will still start.
2698 host_resolver_.set_synchronous_mode(true);
2699 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2700 "");
rch9ecde09b2017-04-08 00:18:232701
2702 CreateSession();
2703 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552704 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232705 QuicStreamFactoryPeer::SetAlarmFactory(
2706 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192707 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552708 &clock_));
rch9ecde09b2017-04-08 00:18:232709
Ryan Hamilton9835e662018-08-02 05:36:272710 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232711
2712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2713 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362714 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232715 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2716
2717 // Pump the message loop to get the request started.
2718 base::RunLoop().RunUntilIdle();
2719 // Explicitly confirm the handshake.
2720 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522721 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232722
2723 // Run the QUIC session to completion.
2724 quic_task_runner_->RunUntilIdle();
2725
2726 ExpectQuicAlternateProtocolMapping();
2727 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2728 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2729}
2730
2731// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2732// return QUIC_PROTOCOL_ERROR.
2733TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482734 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522735 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232736
2737 // The request will initially go out over QUIC.
2738 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522739 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132740 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232741 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2742
2743 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522744 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2745 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432746 quic_data.AddWrite(SYNCHRONOUS,
2747 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332748 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2749 true, priority, GetRequestHeaders("GET", "https", "/"),
2750 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232751
2752 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522753 quic::QuicStreamOffset settings_offset = header_stream_offset;
2754 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432755 quic_data.AddWrite(SYNCHRONOUS,
2756 client_maker_.MakeInitialSettingsPacketAndSaveData(
2757 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232758 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092759 quic_data.AddWrite(SYNCHRONOUS,
2760 client_maker_.MakeDataPacket(
2761 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2762 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232763 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092764 quic_data.AddWrite(SYNCHRONOUS,
2765 client_maker_.MakeDataPacket(
2766 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2767 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232768 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092769 quic_data.AddWrite(SYNCHRONOUS,
2770 client_maker_.MakeDataPacket(
2771 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2772 false, 0, request_data));
2773 quic_data.AddWrite(SYNCHRONOUS,
2774 client_maker_.MakeDataPacket(
2775 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2776 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232777 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092778 quic_data.AddWrite(SYNCHRONOUS,
2779 client_maker_.MakeDataPacket(
2780 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2781 false, 0, request_data));
2782 quic_data.AddWrite(SYNCHRONOUS,
2783 client_maker_.MakeDataPacket(
2784 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2785 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232786 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092787 quic_data.AddWrite(SYNCHRONOUS,
2788 client_maker_.MakeDataPacket(
2789 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2790 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522791 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092792 SYNCHRONOUS, client_maker_.MakeDataPacket(
2793 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2794 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232795 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522796 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092797 SYNCHRONOUS, client_maker_.MakeDataPacket(
2798 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2799 false, 0, request_data));
2800 quic_data.AddWrite(
2801 SYNCHRONOUS, client_maker_.MakeDataPacket(
2802 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2803 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232804 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432805 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522806 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432807 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232808
2809 quic_data.AddRead(ASYNC, OK);
2810 quic_data.AddSocketDataToFactory(&socket_factory_);
2811
2812 // In order for a new QUIC session to be established via alternate-protocol
2813 // without racing an HTTP connection, we need the host resolution to happen
2814 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2815 // connection to the the server, in this test we require confirmation
2816 // before encrypting so the HTTP job will still start.
2817 host_resolver_.set_synchronous_mode(true);
2818 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2819 "");
rch9ecde09b2017-04-08 00:18:232820
2821 CreateSession();
2822 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552823 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232824 QuicStreamFactoryPeer::SetAlarmFactory(
2825 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192826 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552827 &clock_));
rch9ecde09b2017-04-08 00:18:232828
Ryan Hamilton9835e662018-08-02 05:36:272829 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232830
2831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2832 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362833 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2835
2836 // Pump the message loop to get the request started.
2837 base::RunLoop().RunUntilIdle();
2838 // Explicitly confirm the handshake.
2839 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522840 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232841
2842 // Run the QUIC session to completion.
2843 quic_task_runner_->RunUntilIdle();
2844
2845 ExpectQuicAlternateProtocolMapping();
2846 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2847 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2848}
2849
2850// Verify that if a QUIC connection RTOs, while there are no active streams
2851// QUIC will not be marked as broken.
2852TEST_P(QuicNetworkTransactionTest,
2853 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522854 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232855
2856 // The request will initially go out over QUIC.
2857 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522858 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132859 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232860 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2861
2862 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522863 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2864 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432865 quic_data.AddWrite(SYNCHRONOUS,
2866 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332867 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2868 true, priority, GetRequestHeaders("GET", "https", "/"),
2869 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232870
2871 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522872 quic::QuicStreamOffset settings_offset = header_stream_offset;
2873 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432874 quic_data.AddWrite(SYNCHRONOUS,
2875 client_maker_.MakeInitialSettingsPacketAndSaveData(
2876 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232877
Fan Yang32c5a112018-12-10 20:06:332878 quic_data.AddWrite(SYNCHRONOUS,
2879 client_maker_.MakeRstPacket(
2880 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2881 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232882 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092883 quic_data.AddWrite(SYNCHRONOUS,
2884 client_maker_.MakeDataPacket(
2885 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2886 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232887 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092888 quic_data.AddWrite(SYNCHRONOUS,
2889 client_maker_.MakeDataPacket(
2890 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2891 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232892 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332893 quic_data.AddWrite(SYNCHRONOUS,
2894 client_maker_.MakeRstPacket(
2895 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2896 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092897 quic_data.AddWrite(SYNCHRONOUS,
2898 client_maker_.MakeDataPacket(
2899 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2900 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232901 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092902 quic_data.AddWrite(SYNCHRONOUS,
2903 client_maker_.MakeDataPacket(
2904 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2905 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332906 quic_data.AddWrite(SYNCHRONOUS,
2907 client_maker_.MakeRstPacket(
2908 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2909 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232910 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522911 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092912 SYNCHRONOUS, client_maker_.MakeDataPacket(
2913 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2914 false, 0, request_data));
2915 quic_data.AddWrite(
2916 SYNCHRONOUS, client_maker_.MakeDataPacket(
2917 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2918 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232919 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432920 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332921 SYNCHRONOUS, client_maker_.MakeRstPacket(
2922 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2923 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522924 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092925 SYNCHRONOUS, client_maker_.MakeDataPacket(
2926 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2927 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232928 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432929 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522930 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432931 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232932
2933 quic_data.AddRead(ASYNC, OK);
2934 quic_data.AddSocketDataToFactory(&socket_factory_);
2935
2936 // In order for a new QUIC session to be established via alternate-protocol
2937 // without racing an HTTP connection, we need the host resolution to happen
2938 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2939 // connection to the the server, in this test we require confirmation
2940 // before encrypting so the HTTP job will still start.
2941 host_resolver_.set_synchronous_mode(true);
2942 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2943 "");
rch9ecde09b2017-04-08 00:18:232944
2945 CreateSession();
2946 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552947 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232948 QuicStreamFactoryPeer::SetAlarmFactory(
2949 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192950 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552951 &clock_));
rch9ecde09b2017-04-08 00:18:232952
Ryan Hamilton9835e662018-08-02 05:36:272953 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232954
Jeremy Roman0579ed62017-08-29 15:56:192955 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232956 session_.get());
2957 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:362958 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232959 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2960
2961 // Pump the message loop to get the request started.
2962 base::RunLoop().RunUntilIdle();
2963 // Explicitly confirm the handshake.
2964 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522965 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232966
2967 // Now cancel the request.
2968 trans.reset();
2969
2970 // Run the QUIC session to completion.
2971 quic_task_runner_->RunUntilIdle();
2972
2973 ExpectQuicAlternateProtocolMapping();
2974
2975 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2976}
2977
rch2f2991c2017-04-13 19:28:172978// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2979// the request fails with QUIC_PROTOCOL_ERROR.
2980TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482981 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172982 // The request will initially go out over QUIC.
2983 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522984 quic::QuicStreamOffset header_stream_offset = 0;
2985 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2986 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432987 quic_data.AddWrite(
2988 SYNCHRONOUS,
2989 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332990 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432991 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522992 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432993 quic_data.AddWrite(SYNCHRONOUS,
2994 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:172995 // Peer sending data from an non-existing stream causes this end to raise
2996 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:332997 quic_data.AddRead(
2998 ASYNC, ConstructServerRstPacket(
2999 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3000 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173001 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433002 quic_data.AddWrite(SYNCHRONOUS,
3003 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523004 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3005 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173006 quic_data.AddSocketDataToFactory(&socket_factory_);
3007
3008 // In order for a new QUIC session to be established via alternate-protocol
3009 // without racing an HTTP connection, we need the host resolution to happen
3010 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3011 // connection to the the server, in this test we require confirmation
3012 // before encrypting so the HTTP job will still start.
3013 host_resolver_.set_synchronous_mode(true);
3014 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3015 "");
rch2f2991c2017-04-13 19:28:173016
3017 CreateSession();
3018
Ryan Hamilton9835e662018-08-02 05:36:273019 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173020
3021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3022 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363023 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3025
3026 // Pump the message loop to get the request started.
3027 base::RunLoop().RunUntilIdle();
3028 // Explicitly confirm the handshake.
3029 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523030 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173031
3032 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3033
3034 // Run the QUIC session to completion.
3035 base::RunLoop().RunUntilIdle();
3036 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3037 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3038
3039 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3040 ExpectQuicAlternateProtocolMapping();
3041 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3042}
3043
rch9ecde09b2017-04-08 00:18:233044// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3045// connection times out, then QUIC will be marked as broken and the request
3046// retried over TCP.
3047TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413048 session_params_.mark_quic_broken_when_network_blackholes = true;
3049 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233050
3051 // The request will initially go out over QUIC.
3052 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523053 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133054 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233055 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3056
3057 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523058 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3059 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433060 quic_data.AddWrite(SYNCHRONOUS,
3061 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333062 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3063 true, priority, GetRequestHeaders("GET", "https", "/"),
3064 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233065
3066 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523067 quic::QuicStreamOffset settings_offset = header_stream_offset;
3068 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433069 quic_data.AddWrite(SYNCHRONOUS,
3070 client_maker_.MakeInitialSettingsPacketAndSaveData(
3071 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233072 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093073 quic_data.AddWrite(SYNCHRONOUS,
3074 client_maker_.MakeDataPacket(
3075 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3076 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233077 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093078 quic_data.AddWrite(SYNCHRONOUS,
3079 client_maker_.MakeDataPacket(
3080 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3081 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233082 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093083 quic_data.AddWrite(SYNCHRONOUS,
3084 client_maker_.MakeDataPacket(
3085 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3086 false, 0, request_data));
3087 quic_data.AddWrite(SYNCHRONOUS,
3088 client_maker_.MakeDataPacket(
3089 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3090 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233091 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093092 quic_data.AddWrite(SYNCHRONOUS,
3093 client_maker_.MakeDataPacket(
3094 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3095 false, 0, request_data));
3096 quic_data.AddWrite(SYNCHRONOUS,
3097 client_maker_.MakeDataPacket(
3098 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3099 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233100 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093101 quic_data.AddWrite(SYNCHRONOUS,
3102 client_maker_.MakeDataPacket(
3103 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3104 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523105 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093106 SYNCHRONOUS, client_maker_.MakeDataPacket(
3107 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3108 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233109
Zhongyi Shi32f2fd02018-04-16 18:23:433110 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523111 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433112 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223113
rch9ecde09b2017-04-08 00:18:233114 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3115 quic_data.AddRead(ASYNC, OK);
3116 quic_data.AddSocketDataToFactory(&socket_factory_);
3117
3118 // After that fails, it will be resent via TCP.
3119 MockWrite http_writes[] = {
3120 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3121 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3122 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3123
3124 MockRead http_reads[] = {
3125 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3126 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3127 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013128 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233129 socket_factory_.AddSocketDataProvider(&http_data);
3130 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3131
3132 // In order for a new QUIC session to be established via alternate-protocol
3133 // without racing an HTTP connection, we need the host resolution to happen
3134 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3135 // connection to the the server, in this test we require confirmation
3136 // before encrypting so the HTTP job will still start.
3137 host_resolver_.set_synchronous_mode(true);
3138 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3139 "");
rch9ecde09b2017-04-08 00:18:233140
3141 CreateSession();
3142 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553143 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233144 QuicStreamFactoryPeer::SetAlarmFactory(
3145 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193146 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553147 &clock_));
rch9ecde09b2017-04-08 00:18:233148
Ryan Hamilton9835e662018-08-02 05:36:273149 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233150
3151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3152 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363153 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3155
3156 // Pump the message loop to get the request started.
3157 base::RunLoop().RunUntilIdle();
3158 // Explicitly confirm the handshake.
3159 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523160 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233161
3162 // Run the QUIC session to completion.
3163 quic_task_runner_->RunUntilIdle();
3164 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3165
3166 // Let the transaction proceed which will result in QUIC being marked
3167 // as broken and the request falling back to TCP.
3168 EXPECT_THAT(callback.WaitForResult(), IsOk());
3169
3170 ExpectBrokenAlternateProtocolMapping();
3171 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3172 ASSERT_FALSE(http_data.AllReadDataConsumed());
3173
3174 // Read the response body over TCP.
3175 CheckResponseData(&trans, "hello world");
3176 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3177 ASSERT_TRUE(http_data.AllReadDataConsumed());
3178}
3179
rch2f2991c2017-04-13 19:28:173180// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3181// connection times out, then QUIC will be marked as broken and the request
3182// retried over TCP.
3183TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413184 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173185
3186 // The request will initially go out over QUIC.
3187 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523188 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133189 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173190 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3191
3192 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523193 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3194 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433195 quic_data.AddWrite(SYNCHRONOUS,
3196 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333197 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3198 true, priority, GetRequestHeaders("GET", "https", "/"),
3199 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173200
3201 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523202 quic::QuicStreamOffset settings_offset = header_stream_offset;
3203 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433204 quic_data.AddWrite(SYNCHRONOUS,
3205 client_maker_.MakeInitialSettingsPacketAndSaveData(
3206 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173207 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093208 quic_data.AddWrite(SYNCHRONOUS,
3209 client_maker_.MakeDataPacket(
3210 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3211 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173212 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093213 quic_data.AddWrite(SYNCHRONOUS,
3214 client_maker_.MakeDataPacket(
3215 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3216 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173217 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093218 quic_data.AddWrite(SYNCHRONOUS,
3219 client_maker_.MakeDataPacket(
3220 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3221 false, 0, request_data));
3222 quic_data.AddWrite(SYNCHRONOUS,
3223 client_maker_.MakeDataPacket(
3224 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3225 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173226 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093227 quic_data.AddWrite(SYNCHRONOUS,
3228 client_maker_.MakeDataPacket(
3229 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3230 false, 0, request_data));
3231 quic_data.AddWrite(SYNCHRONOUS,
3232 client_maker_.MakeDataPacket(
3233 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3234 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173235 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093236 quic_data.AddWrite(SYNCHRONOUS,
3237 client_maker_.MakeDataPacket(
3238 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3239 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523240 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093241 SYNCHRONOUS, client_maker_.MakeDataPacket(
3242 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3243 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173244
Zhongyi Shi32f2fd02018-04-16 18:23:433245 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523246 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433247 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223248
rch2f2991c2017-04-13 19:28:173249 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3250 quic_data.AddRead(ASYNC, OK);
3251 quic_data.AddSocketDataToFactory(&socket_factory_);
3252
3253 // After that fails, it will be resent via TCP.
3254 MockWrite http_writes[] = {
3255 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3256 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3257 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3258
3259 MockRead http_reads[] = {
3260 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3261 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3262 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013263 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173264 socket_factory_.AddSocketDataProvider(&http_data);
3265 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3266
3267 // In order for a new QUIC session to be established via alternate-protocol
3268 // without racing an HTTP connection, we need the host resolution to happen
3269 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3270 // connection to the the server, in this test we require confirmation
3271 // before encrypting so the HTTP job will still start.
3272 host_resolver_.set_synchronous_mode(true);
3273 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3274 "");
rch2f2991c2017-04-13 19:28:173275
3276 CreateSession();
3277 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553278 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173279 QuicStreamFactoryPeer::SetAlarmFactory(
3280 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193281 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553282 &clock_));
rch2f2991c2017-04-13 19:28:173283
Ryan Hamilton9835e662018-08-02 05:36:273284 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173285
3286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3287 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363288 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3290
3291 // Pump the message loop to get the request started.
3292 base::RunLoop().RunUntilIdle();
3293 // Explicitly confirm the handshake.
3294 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523295 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173296
3297 // Run the QUIC session to completion.
3298 quic_task_runner_->RunUntilIdle();
3299 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3300
3301 ExpectQuicAlternateProtocolMapping();
3302
3303 // Let the transaction proceed which will result in QUIC being marked
3304 // as broken and the request falling back to TCP.
3305 EXPECT_THAT(callback.WaitForResult(), IsOk());
3306
3307 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3308 ASSERT_FALSE(http_data.AllReadDataConsumed());
3309
3310 // Read the response body over TCP.
3311 CheckResponseData(&trans, "hello world");
3312 ExpectBrokenAlternateProtocolMapping();
3313 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3314 ASSERT_TRUE(http_data.AllReadDataConsumed());
3315}
3316
rch9ecde09b2017-04-08 00:18:233317// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3318// connection times out, then QUIC will be marked as broken but the request
3319// will not be retried over TCP.
3320TEST_P(QuicNetworkTransactionTest,
3321 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413322 session_params_.mark_quic_broken_when_network_blackholes = true;
3323 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233324
3325 // The request will initially go out over QUIC.
3326 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523327 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133328 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233329 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3330
3331 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523332 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3333 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433334 quic_data.AddWrite(SYNCHRONOUS,
3335 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333336 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3337 true, priority, GetRequestHeaders("GET", "https", "/"),
3338 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233339
3340 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523341 quic::QuicStreamOffset settings_offset = header_stream_offset;
3342 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433343 quic_data.AddWrite(SYNCHRONOUS,
3344 client_maker_.MakeInitialSettingsPacketAndSaveData(
3345 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233346
Zhongyi Shi32f2fd02018-04-16 18:23:433347 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333348 1, GetNthClientInitiatedBidirectionalStreamId(0),
3349 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433350 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523351 quic_data.AddWrite(
3352 SYNCHRONOUS,
3353 ConstructClientAckPacket(3, 1, 1, 1,
3354 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233355
3356 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523357 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093358 SYNCHRONOUS, client_maker_.MakeDataPacket(
3359 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3360 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233361 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093362 quic_data.AddWrite(
3363 SYNCHRONOUS, client_maker_.MakeDataPacket(
3364 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3365 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233366 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523367 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093368 SYNCHRONOUS, client_maker_.MakeDataPacket(
3369 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3370 false, 0, request_data));
3371 quic_data.AddWrite(
3372 SYNCHRONOUS, client_maker_.MakeDataPacket(
3373 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3374 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233375 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523376 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093377 SYNCHRONOUS, client_maker_.MakeDataPacket(
3378 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3379 false, 0, request_data));
3380 quic_data.AddWrite(
3381 SYNCHRONOUS, client_maker_.MakeDataPacket(
3382 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3383 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233384 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523385 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093386 SYNCHRONOUS, client_maker_.MakeDataPacket(
3387 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3388 false, 0, request_data));
3389 quic_data.AddWrite(
3390 SYNCHRONOUS, client_maker_.MakeDataPacket(
3391 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3392 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233393
Michael Warres112212822018-12-26 17:51:063394 if (GetQuicReloadableFlag(
Zhongyi Shia15736c2018-09-25 00:31:183395 quic_fix_time_of_first_packet_sent_after_receiving)) {
3396 quic_data.AddWrite(
3397 SYNCHRONOUS,
3398 client_maker_.MakeAckAndConnectionClosePacket(
3399 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3400 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3401
3402 } else {
3403 quic_data.AddWrite(
3404 SYNCHRONOUS,
3405 client_maker_.MakeAckAndConnectionClosePacket(
3406 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3407 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3408 }
Fan Yang928f1632017-12-14 18:55:223409
rch9ecde09b2017-04-08 00:18:233410 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3411 quic_data.AddRead(ASYNC, OK);
3412 quic_data.AddSocketDataToFactory(&socket_factory_);
3413
3414 // In order for a new QUIC session to be established via alternate-protocol
3415 // without racing an HTTP connection, we need the host resolution to happen
3416 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3417 // connection to the the server, in this test we require confirmation
3418 // before encrypting so the HTTP job will still start.
3419 host_resolver_.set_synchronous_mode(true);
3420 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3421 "");
rch9ecde09b2017-04-08 00:18:233422
3423 CreateSession();
3424 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553425 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233426 QuicStreamFactoryPeer::SetAlarmFactory(
3427 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193428 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553429 &clock_));
rch9ecde09b2017-04-08 00:18:233430
Ryan Hamilton9835e662018-08-02 05:36:273431 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233432
3433 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3434 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363435 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3437
3438 // Pump the message loop to get the request started.
3439 base::RunLoop().RunUntilIdle();
3440 // Explicitly confirm the handshake.
3441 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523442 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233443
3444 // Pump the message loop to get the request started.
3445 base::RunLoop().RunUntilIdle();
3446
3447 // Run the QUIC session to completion.
3448 quic_task_runner_->RunUntilIdle();
3449 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3450
3451 // Let the transaction proceed which will result in QUIC being marked
3452 // as broken and the request falling back to TCP.
3453 EXPECT_THAT(callback.WaitForResult(), IsOk());
3454
3455 ExpectBrokenAlternateProtocolMapping();
3456 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3457
3458 std::string response_data;
3459 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3460 IsError(ERR_QUIC_PROTOCOL_ERROR));
3461}
3462
3463// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3464// connection RTOs, then QUIC will be marked as broken and the request retried
3465// over TCP.
3466TEST_P(QuicNetworkTransactionTest,
3467 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413468 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523469 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233470
3471 // The request will initially go out over QUIC.
3472 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523473 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133474 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233475 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3476
3477 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523478 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3479 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433480 quic_data.AddWrite(SYNCHRONOUS,
3481 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333482 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3483 true, priority, GetRequestHeaders("GET", "https", "/"),
3484 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233485
3486 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523487 quic::QuicStreamOffset settings_offset = header_stream_offset;
3488 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433489 quic_data.AddWrite(SYNCHRONOUS,
3490 client_maker_.MakeInitialSettingsPacketAndSaveData(
3491 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233492 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093493 quic_data.AddWrite(SYNCHRONOUS,
3494 client_maker_.MakeDataPacket(
3495 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3496 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233497 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093498 quic_data.AddWrite(SYNCHRONOUS,
3499 client_maker_.MakeDataPacket(
3500 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3501 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233502 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093503 quic_data.AddWrite(SYNCHRONOUS,
3504 client_maker_.MakeDataPacket(
3505 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3506 false, 0, request_data));
3507 quic_data.AddWrite(SYNCHRONOUS,
3508 client_maker_.MakeDataPacket(
3509 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3510 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233511 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093512 quic_data.AddWrite(SYNCHRONOUS,
3513 client_maker_.MakeDataPacket(
3514 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3515 false, 0, request_data));
3516 quic_data.AddWrite(SYNCHRONOUS,
3517 client_maker_.MakeDataPacket(
3518 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3519 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233520 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093521 quic_data.AddWrite(SYNCHRONOUS,
3522 client_maker_.MakeDataPacket(
3523 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3524 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523525 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093526 SYNCHRONOUS, client_maker_.MakeDataPacket(
3527 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3528 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233529 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523530 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093531 SYNCHRONOUS, client_maker_.MakeDataPacket(
3532 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3533 false, 0, request_data));
3534 quic_data.AddWrite(
3535 SYNCHRONOUS, client_maker_.MakeDataPacket(
3536 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3537 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233538
Zhongyi Shi32f2fd02018-04-16 18:23:433539 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523540 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433541 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233542
3543 quic_data.AddRead(ASYNC, OK);
3544 quic_data.AddSocketDataToFactory(&socket_factory_);
3545
3546 // After that fails, it will be resent via TCP.
3547 MockWrite http_writes[] = {
3548 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3549 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3550 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3551
3552 MockRead http_reads[] = {
3553 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3554 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3555 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013556 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233557 socket_factory_.AddSocketDataProvider(&http_data);
3558 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3559
3560 // In order for a new QUIC session to be established via alternate-protocol
3561 // without racing an HTTP connection, we need the host resolution to happen
3562 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3563 // connection to the the server, in this test we require confirmation
3564 // before encrypting so the HTTP job will still start.
3565 host_resolver_.set_synchronous_mode(true);
3566 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3567 "");
rch9ecde09b2017-04-08 00:18:233568
3569 CreateSession();
3570 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553571 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233572 QuicStreamFactoryPeer::SetAlarmFactory(
3573 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193574 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553575 &clock_));
rch9ecde09b2017-04-08 00:18:233576
Ryan Hamilton9835e662018-08-02 05:36:273577 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233578
3579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3580 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363581 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3583
3584 // Pump the message loop to get the request started.
3585 base::RunLoop().RunUntilIdle();
3586 // Explicitly confirm the handshake.
3587 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523588 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233589
3590 // Run the QUIC session to completion.
3591 quic_task_runner_->RunUntilIdle();
3592 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3593
3594 // Let the transaction proceed which will result in QUIC being marked
3595 // as broken and the request falling back to TCP.
3596 EXPECT_THAT(callback.WaitForResult(), IsOk());
3597
3598 ExpectBrokenAlternateProtocolMapping();
3599 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3600 ASSERT_FALSE(http_data.AllReadDataConsumed());
3601
3602 // Read the response body over TCP.
3603 CheckResponseData(&trans, "hello world");
3604 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3605 ASSERT_TRUE(http_data.AllReadDataConsumed());
3606}
3607
3608// Verify that if a QUIC connection RTOs, while there are no active streams
3609// QUIC will be marked as broken.
3610TEST_P(QuicNetworkTransactionTest,
3611 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413612 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523613 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233614
3615 // The request will initially go out over QUIC.
3616 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523617 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133618 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233619 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3620
3621 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523622 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3623 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433624 quic_data.AddWrite(SYNCHRONOUS,
3625 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333626 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3627 true, priority, GetRequestHeaders("GET", "https", "/"),
3628 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233629
3630 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523631 quic::QuicStreamOffset settings_offset = header_stream_offset;
3632 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433633 quic_data.AddWrite(SYNCHRONOUS,
3634 client_maker_.MakeInitialSettingsPacketAndSaveData(
3635 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233636
Fan Yang32c5a112018-12-10 20:06:333637 quic_data.AddWrite(SYNCHRONOUS,
3638 client_maker_.MakeRstPacket(
3639 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3640 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233641 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093642 quic_data.AddWrite(SYNCHRONOUS,
3643 client_maker_.MakeDataPacket(
3644 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3645 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233646 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093647 quic_data.AddWrite(SYNCHRONOUS,
3648 client_maker_.MakeDataPacket(
3649 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3650 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233651 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333652 quic_data.AddWrite(SYNCHRONOUS,
3653 client_maker_.MakeRstPacket(
3654 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3655 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093656 quic_data.AddWrite(SYNCHRONOUS,
3657 client_maker_.MakeDataPacket(
3658 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3659 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233660 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093661 quic_data.AddWrite(SYNCHRONOUS,
3662 client_maker_.MakeDataPacket(
3663 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3664 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333665 quic_data.AddWrite(SYNCHRONOUS,
3666 client_maker_.MakeRstPacket(
3667 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3668 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233669 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523670 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093671 SYNCHRONOUS, client_maker_.MakeDataPacket(
3672 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3673 false, 0, request_data));
3674 quic_data.AddWrite(
3675 SYNCHRONOUS, client_maker_.MakeDataPacket(
3676 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3677 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233678 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433679 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333680 SYNCHRONOUS, client_maker_.MakeRstPacket(
3681 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3682 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523683 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093684 SYNCHRONOUS, client_maker_.MakeDataPacket(
3685 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3686 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233687 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433688 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523689 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433690 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233691
3692 quic_data.AddRead(ASYNC, OK);
3693 quic_data.AddSocketDataToFactory(&socket_factory_);
3694
3695 // In order for a new QUIC session to be established via alternate-protocol
3696 // without racing an HTTP connection, we need the host resolution to happen
3697 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3698 // connection to the the server, in this test we require confirmation
3699 // before encrypting so the HTTP job will still start.
3700 host_resolver_.set_synchronous_mode(true);
3701 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3702 "");
rch9ecde09b2017-04-08 00:18:233703
3704 CreateSession();
3705 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553706 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233707 QuicStreamFactoryPeer::SetAlarmFactory(
3708 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193709 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553710 &clock_));
rch9ecde09b2017-04-08 00:18:233711
Ryan Hamilton9835e662018-08-02 05:36:273712 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233713
Jeremy Roman0579ed62017-08-29 15:56:193714 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233715 session_.get());
3716 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363717 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3719
3720 // Pump the message loop to get the request started.
3721 base::RunLoop().RunUntilIdle();
3722 // Explicitly confirm the handshake.
3723 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523724 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233725
3726 // Now cancel the request.
3727 trans.reset();
3728
3729 // Run the QUIC session to completion.
3730 quic_task_runner_->RunUntilIdle();
3731
3732 ExpectBrokenAlternateProtocolMapping();
3733
3734 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3735}
3736
rch2f2991c2017-04-13 19:28:173737// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3738// protocol error occurs after the handshake is confirmed, the request
3739// retried over TCP and the QUIC will be marked as broken.
3740TEST_P(QuicNetworkTransactionTest,
3741 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413742 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173743
3744 // The request will initially go out over QUIC.
3745 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523746 quic::QuicStreamOffset header_stream_offset = 0;
3747 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3748 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433749 quic_data.AddWrite(
3750 SYNCHRONOUS,
3751 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333752 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433753 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523754 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433755 quic_data.AddWrite(SYNCHRONOUS,
3756 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173757 // Peer sending data from an non-existing stream causes this end to raise
3758 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333759 quic_data.AddRead(
3760 ASYNC, ConstructServerRstPacket(
3761 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3762 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173763 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433764 quic_data.AddWrite(SYNCHRONOUS,
3765 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523766 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3767 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173768 quic_data.AddSocketDataToFactory(&socket_factory_);
3769
3770 // After that fails, it will be resent via TCP.
3771 MockWrite http_writes[] = {
3772 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3773 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3774 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3775
3776 MockRead http_reads[] = {
3777 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3778 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3779 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013780 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173781 socket_factory_.AddSocketDataProvider(&http_data);
3782 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3783
3784 // In order for a new QUIC session to be established via alternate-protocol
3785 // without racing an HTTP connection, we need the host resolution to happen
3786 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3787 // connection to the the server, in this test we require confirmation
3788 // before encrypting so the HTTP job will still start.
3789 host_resolver_.set_synchronous_mode(true);
3790 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3791 "");
rch2f2991c2017-04-13 19:28:173792
3793 CreateSession();
3794
Ryan Hamilton9835e662018-08-02 05:36:273795 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173796
3797 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3798 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363799 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3801
3802 // Pump the message loop to get the request started.
3803 base::RunLoop().RunUntilIdle();
3804 // Explicitly confirm the handshake.
3805 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523806 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173807
3808 // Run the QUIC session to completion.
3809 base::RunLoop().RunUntilIdle();
3810 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3811
3812 ExpectQuicAlternateProtocolMapping();
3813
3814 // Let the transaction proceed which will result in QUIC being marked
3815 // as broken and the request falling back to TCP.
3816 EXPECT_THAT(callback.WaitForResult(), IsOk());
3817
3818 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3819 ASSERT_FALSE(http_data.AllReadDataConsumed());
3820
3821 // Read the response body over TCP.
3822 CheckResponseData(&trans, "hello world");
3823 ExpectBrokenAlternateProtocolMapping();
3824 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3825 ASSERT_TRUE(http_data.AllReadDataConsumed());
3826}
3827
rch30943ee2017-06-12 21:28:443828// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3829// request is reset from, then QUIC will be marked as broken and the request
3830// retried over TCP.
3831TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443832 // The request will initially go out over QUIC.
3833 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523834 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133835 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443836 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3837
3838 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523839 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3840 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433841 quic_data.AddWrite(SYNCHRONOUS,
3842 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333843 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3844 true, priority, GetRequestHeaders("GET", "https", "/"),
3845 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443846
3847 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523848 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3849 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433850 quic_data.AddWrite(SYNCHRONOUS,
3851 client_maker_.MakeInitialSettingsPacketAndSaveData(
3852 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443853
Fan Yang32c5a112018-12-10 20:06:333854 quic_data.AddRead(ASYNC,
3855 ConstructServerRstPacket(
3856 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3857 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443858
3859 quic_data.AddRead(ASYNC, OK);
3860 quic_data.AddSocketDataToFactory(&socket_factory_);
3861
3862 // After that fails, it will be resent via TCP.
3863 MockWrite http_writes[] = {
3864 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3865 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3866 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3867
3868 MockRead http_reads[] = {
3869 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3870 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3871 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013872 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443873 socket_factory_.AddSocketDataProvider(&http_data);
3874 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3875
3876 // In order for a new QUIC session to be established via alternate-protocol
3877 // without racing an HTTP connection, we need the host resolution to happen
3878 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3879 // connection to the the server, in this test we require confirmation
3880 // before encrypting so the HTTP job will still start.
3881 host_resolver_.set_synchronous_mode(true);
3882 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3883 "");
rch30943ee2017-06-12 21:28:443884
3885 CreateSession();
3886
Ryan Hamilton9835e662018-08-02 05:36:273887 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443888
3889 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3890 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:363891 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443892 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3893
3894 // Pump the message loop to get the request started.
3895 base::RunLoop().RunUntilIdle();
3896 // Explicitly confirm the handshake.
3897 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523898 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443899
3900 // Run the QUIC session to completion.
3901 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3902
3903 ExpectQuicAlternateProtocolMapping();
3904
3905 // Let the transaction proceed which will result in QUIC being marked
3906 // as broken and the request falling back to TCP.
3907 EXPECT_THAT(callback.WaitForResult(), IsOk());
3908
3909 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3910 ASSERT_FALSE(http_data.AllReadDataConsumed());
3911
3912 // Read the response body over TCP.
3913 CheckResponseData(&trans, "hello world");
3914 ExpectBrokenAlternateProtocolMapping();
3915 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3916 ASSERT_TRUE(http_data.AllReadDataConsumed());
3917}
3918
Ryan Hamilton6c2a2a82017-12-15 02:06:283919// Verify that when an origin has two alt-svc advertisements, one local and one
3920// remote, that when the local is broken the request will go over QUIC via
3921// the remote Alt-Svc.
3922// This is a regression test for crbug/825646.
3923TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3924 session_params_.quic_allow_remote_alt_svc = true;
3925
3926 GURL origin1 = request_.url; // mail.example.org
3927 GURL origin2("https://www.example.org/");
3928 ASSERT_NE(origin1.host(), origin2.host());
3929
3930 scoped_refptr<X509Certificate> cert(
3931 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243932 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3933 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283934
3935 ProofVerifyDetailsChromium verify_details;
3936 verify_details.cert_verify_result.verified_cert = cert;
3937 verify_details.cert_verify_result.is_issued_by_known_root = true;
3938 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3939
3940 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523941 quic::QuicStreamOffset request_header_offset(0);
3942 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283943 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433944 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3945 mock_quic_data.AddWrite(
3946 SYNCHRONOUS,
3947 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333948 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433949 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3950 mock_quic_data.AddRead(
3951 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333952 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433953 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:413954 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:433955 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333956 ASYNC, ConstructServerDataPacket(
3957 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:413958 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433959 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283960 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3961 mock_quic_data.AddRead(ASYNC, 0); // EOF
3962
3963 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3964 MockQuicData mock_quic_data2;
3965 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3966 AddHangingNonAlternateProtocolSocketData();
3967
3968 CreateSession();
3969
3970 // Set up alternative service for |origin1|.
3971 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3972 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3973 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3974 AlternativeServiceInfoVector alternative_services;
3975 alternative_services.push_back(
3976 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3977 local_alternative, expiration,
3978 session_->params().quic_supported_versions));
3979 alternative_services.push_back(
3980 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3981 remote_alternative, expiration,
3982 session_->params().quic_supported_versions));
3983 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3984 alternative_services);
3985
3986 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3987
3988 SendRequestAndExpectQuicResponse("hello!");
3989}
3990
rch30943ee2017-06-12 21:28:443991// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3992// request is reset from, then QUIC will be marked as broken and the request
3993// retried over TCP. Then, subsequent requests will go over a new QUIC
3994// connection instead of going back to the broken QUIC connection.
3995// This is a regression tests for crbug/731303.
3996TEST_P(QuicNetworkTransactionTest,
3997 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:343998 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443999
4000 GURL origin1 = request_.url;
4001 GURL origin2("https://www.example.org/");
4002 ASSERT_NE(origin1.host(), origin2.host());
4003
4004 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524005 quic::QuicStreamOffset request_header_offset(0);
4006 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444007
4008 scoped_refptr<X509Certificate> cert(
4009 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244010 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4011 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444012
4013 ProofVerifyDetailsChromium verify_details;
4014 verify_details.cert_verify_result.verified_cert = cert;
4015 verify_details.cert_verify_result.is_issued_by_known_root = true;
4016 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4017
4018 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434019 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444020 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434021 mock_quic_data.AddWrite(
4022 SYNCHRONOUS,
4023 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334024 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434025 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4026 mock_quic_data.AddRead(
4027 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334028 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434029 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414030 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434031 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334032 ASYNC, ConstructServerDataPacket(
4033 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414034 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434035 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444036
4037 // Second request will go over the pooled QUIC connection, but will be
4038 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054039 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174040 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4041 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054042 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174043 QuicTestPacketMaker server_maker2(
4044 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4045 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434046 mock_quic_data.AddWrite(
4047 SYNCHRONOUS,
4048 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334049 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434050 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334051 GetNthClientInitiatedBidirectionalStreamId(0),
4052 &request_header_offset));
4053 mock_quic_data.AddRead(
4054 ASYNC, ConstructServerRstPacket(
4055 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4056 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444057 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4058 mock_quic_data.AddRead(ASYNC, 0); // EOF
4059
4060 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4061
4062 // After that fails, it will be resent via TCP.
4063 MockWrite http_writes[] = {
4064 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4065 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4066 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4067
4068 MockRead http_reads[] = {
4069 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4070 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4071 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014072 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444073 socket_factory_.AddSocketDataProvider(&http_data);
4074 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4075
Ryan Hamilton6c2a2a82017-12-15 02:06:284076 // Then the next request to the second origin will be sent over TCP.
4077 socket_factory_.AddSocketDataProvider(&http_data);
4078 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444079
4080 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564081 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4082 QuicStreamFactoryPeer::SetAlarmFactory(
4083 session_->quic_stream_factory(),
4084 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4085 &clock_));
rch30943ee2017-06-12 21:28:444086
4087 // Set up alternative service for |origin1|.
4088 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244089 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214090 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244091 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444092 supported_versions_);
rch30943ee2017-06-12 21:28:444093
4094 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244095 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214096 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244097 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444098 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344099
rch30943ee2017-06-12 21:28:444100 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524101 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444102 SendRequestAndExpectQuicResponse("hello!");
4103
4104 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524105 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444106 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4107 request_.url = origin2;
4108 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284109 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244110 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284111 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244112 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444113
4114 // The third request should use a new QUIC connection, not the broken
4115 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284116 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444117}
4118
bnc8be55ebb2015-10-30 14:12:074119TEST_P(QuicNetworkTransactionTest,
4120 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4121 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444122 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074123 MockRead http_reads[] = {
4124 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4125 MockRead("hello world"),
4126 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4127 MockRead(ASYNC, OK)};
4128
Ryan Sleevib8d7ea02018-05-07 20:01:014129 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074130 socket_factory_.AddSocketDataProvider(&http_data);
4131 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4132 socket_factory_.AddSocketDataProvider(&http_data);
4133 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4134
rch3f4b8452016-02-23 16:59:324135 CreateSession();
bnc8be55ebb2015-10-30 14:12:074136
4137 SendRequestAndExpectHttpResponse("hello world");
4138 SendRequestAndExpectHttpResponse("hello world");
4139}
4140
Xida Chen9bfe0b62018-04-24 19:52:214141// When multiple alternative services are advertised, HttpStreamFactory should
4142// select the alternative service which uses existing QUIC session if available.
4143// If no existing QUIC session can be used, use the first alternative service
4144// from the list.
zhongyi32569c62016-01-08 02:54:304145TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344146 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524147 MockRead http_reads[] = {
4148 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294149 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524150 MockRead("hello world"),
4151 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4152 MockRead(ASYNC, OK)};
4153
Ryan Sleevib8d7ea02018-05-07 20:01:014154 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524155 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084156 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564157 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524158
Ryan Hamilton8d9ee76e2018-05-29 23:52:524159 quic::QuicStreamOffset request_header_offset = 0;
4160 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304161 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294162 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304163 // alternative service list.
bncc958faa2015-07-31 18:14:524164 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364165 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434166 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4167 mock_quic_data.AddWrite(
4168 SYNCHRONOUS,
4169 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334170 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434171 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304172
4173 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294174 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4175 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434176 mock_quic_data.AddRead(
4177 ASYNC,
4178 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334179 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434180 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414181 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434182 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334183 ASYNC, ConstructServerDataPacket(
4184 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414185 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434186 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304187
4188 // Second QUIC request data.
4189 // Connection pooling, using existing session, no need to include version
4190 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584191 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334192 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4193 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4194 true, GetRequestHeaders("GET", "https", "/"),
4195 GetNthClientInitiatedBidirectionalStreamId(0),
4196 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434197 mock_quic_data.AddRead(
4198 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334199 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434200 GetResponseHeaders("200 OK"), &response_header_offset));
4201 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334202 ASYNC, ConstructServerDataPacket(
4203 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414204 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434205 mock_quic_data.AddWrite(
4206 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524207 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594208 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524209
4210 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4211
rtennetib8e80fb2016-05-16 00:12:094212 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324213 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564214 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4215 QuicStreamFactoryPeer::SetAlarmFactory(
4216 session_->quic_stream_factory(),
4217 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4218 &clock_));
bncc958faa2015-07-31 18:14:524219
4220 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304221
bnc359ed2a2016-04-29 20:43:454222 SendRequestAndExpectQuicResponse("hello!");
4223 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304224}
4225
tbansal6490783c2016-09-20 17:55:274226// Check that an existing QUIC connection to an alternative proxy server is
4227// used.
4228TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4229 base::HistogramTester histogram_tester;
4230
Ryan Hamilton8d9ee76e2018-05-29 23:52:524231 quic::QuicStreamOffset request_header_offset = 0;
4232 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274233 // First QUIC request data.
4234 // Open a session to foo.example.org:443 using the first entry of the
4235 // alternative service list.
4236 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364237 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434238 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4239 mock_quic_data.AddWrite(
4240 SYNCHRONOUS,
4241 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334242 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434243 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274244
4245 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434246 mock_quic_data.AddRead(
4247 ASYNC,
4248 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334249 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434250 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
Renjief49758b2019-01-11 23:32:414251 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434252 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334253 ASYNC, ConstructServerDataPacket(
4254 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414255 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434256 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274257
4258 // Second QUIC request data.
4259 // Connection pooling, using existing session, no need to include version
4260 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274261 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334262 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4263 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4264 true, GetRequestHeaders("GET", "http", "/"),
4265 GetNthClientInitiatedBidirectionalStreamId(0),
4266 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434267 mock_quic_data.AddRead(
4268 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334269 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434270 GetResponseHeaders("200 OK"), &response_header_offset));
4271 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334272 ASYNC, ConstructServerDataPacket(
4273 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414274 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434275 mock_quic_data.AddWrite(
4276 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274277 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4278 mock_quic_data.AddRead(ASYNC, 0); // EOF
4279
4280 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4281
4282 AddHangingNonAlternateProtocolSocketData();
4283
4284 TestProxyDelegate test_proxy_delegate;
4285
Lily Houghton8c2f97d2018-01-22 05:06:594286 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494287 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274288
4289 test_proxy_delegate.set_alternative_proxy_server(
4290 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524291 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274292
4293 request_.url = GURL("http://mail.example.org/");
4294
4295 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564296 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4297 QuicStreamFactoryPeer::SetAlarmFactory(
4298 session_->quic_stream_factory(),
4299 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4300 &clock_));
tbansal6490783c2016-09-20 17:55:274301
4302 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4303 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4304 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4305 1);
4306
4307 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4308 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4309 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4310 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4311 1);
4312}
4313
Ryan Hamilton8d9ee76e2018-05-29 23:52:524314// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454315// even if alternative service destination is different.
4316TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344317 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304318 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524319 quic::QuicStreamOffset request_header_offset(0);
4320 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454321
rch5cb522462017-04-25 20:18:364322 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434323 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454324 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434325 mock_quic_data.AddWrite(
4326 SYNCHRONOUS,
4327 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334328 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434329 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4330 mock_quic_data.AddRead(
4331 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334332 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434333 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414334 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434335 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334336 ASYNC, ConstructServerDataPacket(
4337 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414338 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434339 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304340
bnc359ed2a2016-04-29 20:43:454341 // Second request.
alyssar2adf3ac2016-05-03 17:12:584342 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334343 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4344 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4345 true, GetRequestHeaders("GET", "https", "/"),
4346 GetNthClientInitiatedBidirectionalStreamId(0),
4347 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434348 mock_quic_data.AddRead(
4349 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334350 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434351 GetResponseHeaders("200 OK"), &response_header_offset));
4352 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334353 ASYNC, ConstructServerDataPacket(
4354 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414355 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434356 mock_quic_data.AddWrite(
4357 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304358 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4359 mock_quic_data.AddRead(ASYNC, 0); // EOF
4360
4361 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454362
4363 AddHangingNonAlternateProtocolSocketData();
4364 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304365
rch3f4b8452016-02-23 16:59:324366 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564367 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4368 QuicStreamFactoryPeer::SetAlarmFactory(
4369 session_->quic_stream_factory(),
4370 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4371 &clock_));
zhongyi32569c62016-01-08 02:54:304372
bnc359ed2a2016-04-29 20:43:454373 const char destination1[] = "first.example.com";
4374 const char destination2[] = "second.example.com";
4375
4376 // Set up alternative service entry to destination1.
4377 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214378 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454379 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214380 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444381 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454382 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524383 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454384 SendRequestAndExpectQuicResponse("hello!");
4385
4386 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214387 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214388 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444389 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524390 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454391 // even though alternative service destination is different.
4392 SendRequestAndExpectQuicResponse("hello!");
4393}
4394
4395// Pool to existing session with matching destination and matching certificate
4396// even if origin is different, and even if the alternative service with
4397// matching destination is not the first one on the list.
4398TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344399 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454400 GURL origin1 = request_.url;
4401 GURL origin2("https://www.example.org/");
4402 ASSERT_NE(origin1.host(), origin2.host());
4403
4404 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524405 quic::QuicStreamOffset request_header_offset(0);
4406 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454407
rch5cb522462017-04-25 20:18:364408 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434409 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454410 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434411 mock_quic_data.AddWrite(
4412 SYNCHRONOUS,
4413 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334414 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434415 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4416 mock_quic_data.AddRead(
4417 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334418 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434419 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414420 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:434421 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334422 ASYNC, ConstructServerDataPacket(
4423 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414424 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434425 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454426
4427 // Second request.
Yixin Wang079ad542018-01-11 04:06:054428 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:174429 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4430 &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054431 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:174432 QuicTestPacketMaker server_maker2(
4433 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4434 &clock_, origin2.host(), quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584435 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434436 SYNCHRONOUS,
4437 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334438 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434439 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334440 GetNthClientInitiatedBidirectionalStreamId(0),
4441 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434442 mock_quic_data.AddRead(
4443 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334444 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434445 GetResponseHeaders("200 OK"), &response_header_offset));
4446 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334447 ASYNC, ConstructServerDataPacket(
4448 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414449 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434450 mock_quic_data.AddWrite(
4451 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454452 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4453 mock_quic_data.AddRead(ASYNC, 0); // EOF
4454
4455 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4456
4457 AddHangingNonAlternateProtocolSocketData();
4458 AddHangingNonAlternateProtocolSocketData();
4459
4460 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564461 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4462 QuicStreamFactoryPeer::SetAlarmFactory(
4463 session_->quic_stream_factory(),
4464 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4465 &clock_));
bnc359ed2a2016-04-29 20:43:454466
4467 const char destination1[] = "first.example.com";
4468 const char destination2[] = "second.example.com";
4469
4470 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214471 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454472 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214473 http_server_properties_.SetQuicAlternativeService(
4474 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444475 supported_versions_);
bnc359ed2a2016-04-29 20:43:454476
4477 // Set up multiple alternative service entries for |origin2|,
4478 // the first one with a different destination as for |origin1|,
4479 // the second one with the same. The second one should be used,
4480 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214481 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454482 AlternativeServiceInfoVector alternative_services;
4483 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214484 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4485 alternative_service2, expiration,
4486 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454487 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214488 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4489 alternative_service1, expiration,
4490 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454491 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4492 alternative_services);
bnc359ed2a2016-04-29 20:43:454493 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524494 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454495 SendRequestAndExpectQuicResponse("hello!");
4496
4497 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524498 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454499 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584500
bnc359ed2a2016-04-29 20:43:454501 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304502}
4503
4504// Multiple origins have listed the same alternative services. When there's a
4505// existing QUIC session opened by a request to other origin,
4506// if the cert is valid, should select this QUIC session to make the request
4507// if this is also the first existing QUIC session.
4508TEST_P(QuicNetworkTransactionTest,
4509 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344510 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294511 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304512
rch9ae5b3b2016-02-11 00:36:294513 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304514 MockRead http_reads[] = {
4515 MockRead("HTTP/1.1 200 OK\r\n"),
4516 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294517 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304518 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4519 MockRead(ASYNC, OK)};
4520
Ryan Sleevib8d7ea02018-05-07 20:01:014521 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304522 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084523 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304524 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4525
4526 // HTTP data for request to mail.example.org.
4527 MockRead http_reads2[] = {
4528 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294529 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304530 MockRead("hello world from mail.example.org"),
4531 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4532 MockRead(ASYNC, OK)};
4533
Ryan Sleevib8d7ea02018-05-07 20:01:014534 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304535 socket_factory_.AddSocketDataProvider(&http_data2);
4536 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4537
Ryan Hamilton8d9ee76e2018-05-29 23:52:524538 quic::QuicStreamOffset request_header_offset = 0;
4539 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304540
Yixin Wang079ad542018-01-11 04:06:054541 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:174542 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
4543 &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054544 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584545 server_maker_.set_hostname("www.example.org");
4546 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304547 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364548 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434549 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304550 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584551 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434552 SYNCHRONOUS,
4553 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334554 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434555 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4556
4557 mock_quic_data.AddRead(
4558 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334559 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434560 GetResponseHeaders("200 OK"), &response_header_offset));
Renjief49758b2019-01-11 23:32:414561 quic::QuicString header = ConstructDataHeader(21);
Fan Yang32c5a112018-12-10 20:06:334562 mock_quic_data.AddRead(
4563 ASYNC, ConstructServerDataPacket(
4564 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414565 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434566 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4567 // Second QUIC request data.
4568 mock_quic_data.AddWrite(
4569 SYNCHRONOUS,
4570 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334571 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434572 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334573 GetNthClientInitiatedBidirectionalStreamId(0),
4574 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434575 mock_quic_data.AddRead(
4576 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334577 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434578 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334579 mock_quic_data.AddRead(
4580 ASYNC, ConstructServerDataPacket(
4581 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:414582 0, header + "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434583 mock_quic_data.AddWrite(
4584 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304585 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4586 mock_quic_data.AddRead(ASYNC, 0); // EOF
4587
4588 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304589
rtennetib8e80fb2016-05-16 00:12:094590 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324591 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564592 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4593 QuicStreamFactoryPeer::SetAlarmFactory(
4594 session_->quic_stream_factory(),
4595 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4596 &clock_));
zhongyi32569c62016-01-08 02:54:304597
4598 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294599 request_.url = GURL("https://www.example.org/");
4600 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304601 request_.url = GURL("https://mail.example.org/");
4602 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4603
rch9ae5b3b2016-02-11 00:36:294604 // Open a QUIC session to mail.example.org:443 when making request
4605 // to mail.example.org.
4606 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454607 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304608
rch9ae5b3b2016-02-11 00:36:294609 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304610 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454611 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524612}
4613
4614TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524615 MockRead http_reads[] = {
4616 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564617 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524618 MockRead("hello world"),
4619 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4620 MockRead(ASYNC, OK)};
4621
Ryan Sleevib8d7ea02018-05-07 20:01:014622 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524623 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084624 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564625 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524626
rtennetib8e80fb2016-05-16 00:12:094627 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324628 CreateSession();
bncc958faa2015-07-31 18:14:524629
4630 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454631
4632 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344633 AlternativeServiceInfoVector alternative_service_info_vector =
4634 http_server_properties_.GetAlternativeServiceInfos(http_server);
4635 ASSERT_EQ(1u, alternative_service_info_vector.size());
4636 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544637 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344638 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4639 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4640 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524641}
4642
4643TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524644 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564645 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4646 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524647 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4648 MockRead(ASYNC, OK)};
4649
Ryan Sleevib8d7ea02018-05-07 20:01:014650 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524651 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084652 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564653 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524654
4655 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524656 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364657 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434658 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4659 mock_quic_data.AddWrite(
4660 SYNCHRONOUS,
4661 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334662 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434663 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434664 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334665 ASYNC, ConstructServerResponseHeadersPacket(
4666 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4667 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414668 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334669 mock_quic_data.AddRead(
4670 ASYNC, ConstructServerDataPacket(
4671 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414672 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434673 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524674 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4675 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524676
4677 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4678
rtennetib8e80fb2016-05-16 00:12:094679 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324680 CreateSession();
bncc958faa2015-07-31 18:14:524681
bnc3472afd2016-11-17 15:27:214682 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524683 HostPortPair::FromURL(request_.url));
4684 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4685 alternative_service);
4686 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4687 alternative_service));
4688
4689 SendRequestAndExpectHttpResponse("hello world");
4690 SendRequestAndExpectQuicResponse("hello!");
4691
mmenkee24011922015-12-17 22:12:594692 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524693
4694 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4695 alternative_service));
rchac7f35e2017-03-15 20:42:304696 EXPECT_NE(nullptr,
4697 http_server_properties_.GetServerNetworkStats(
4698 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524699}
4700
bncc958faa2015-07-31 18:14:524701TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524702 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564703 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4704 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524705 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4706 MockRead(ASYNC, OK)};
4707
Ryan Sleevib8d7ea02018-05-07 20:01:014708 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524709 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564710 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524711
4712 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524713 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364714 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434715 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4716 mock_quic_data.AddWrite(
4717 SYNCHRONOUS,
4718 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334719 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434720 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434721 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334722 ASYNC, ConstructServerResponseHeadersPacket(
4723 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4724 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414725 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334726 mock_quic_data.AddRead(
4727 ASYNC, ConstructServerDataPacket(
4728 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414729 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434730 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524731 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4732
4733 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4734
4735 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324736 CreateSession();
bncc958faa2015-07-31 18:14:524737
4738 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4739 SendRequestAndExpectHttpResponse("hello world");
4740}
4741
tbansalc3308d72016-08-27 10:25:044742// Tests that the connection to an HTTPS proxy is raced with an available
4743// alternative proxy server.
4744TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274745 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594746 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494747 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044748
4749 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524750 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364751 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434752 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4753 mock_quic_data.AddWrite(
4754 SYNCHRONOUS,
4755 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334756 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434757 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434758 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334759 ASYNC, ConstructServerResponseHeadersPacket(
4760 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4761 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414762 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334763 mock_quic_data.AddRead(
4764 ASYNC, ConstructServerDataPacket(
4765 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414766 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434767 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044768 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4769 mock_quic_data.AddRead(ASYNC, 0); // EOF
4770
4771 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4772
4773 // There is no need to set up main job, because no attempt will be made to
4774 // speak to the proxy over TCP.
4775 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044776 TestProxyDelegate test_proxy_delegate;
4777 const HostPortPair host_port_pair("mail.example.org", 443);
4778
4779 test_proxy_delegate.set_alternative_proxy_server(
4780 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524781 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044782 CreateSession();
4783 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4784
4785 // The main job needs to hang in order to guarantee that the alternative
4786 // proxy server job will "win".
4787 AddHangingNonAlternateProtocolSocketData();
4788
4789 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4790
4791 // Verify that the alternative proxy server is not marked as broken.
4792 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4793
4794 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594795 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274796
4797 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4798 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4799 1);
tbansalc3308d72016-08-27 10:25:044800}
4801
bnc1c196c6e2016-05-28 13:51:484802TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304803 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274804 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304805
4806 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564807 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294808 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564809 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304810
4811 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564812 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484813 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564814 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304815
Ryan Sleevib8d7ea02018-05-07 20:01:014816 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504817 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084818 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504819 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304820
4821 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454822 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304823 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454824 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304825 };
Ryan Sleevib8d7ea02018-05-07 20:01:014826 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504827 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304828
4829 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014830 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504831 socket_factory_.AddSocketDataProvider(&http_data2);
4832 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304833
bnc912a04b2016-04-20 14:19:504834 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304835
4836 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304837 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174838 ASSERT_TRUE(http_data.AllReadDataConsumed());
4839 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304840
4841 // Now run the second request in which the QUIC socket hangs,
4842 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304843 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454844 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304845
rch37de576c2015-05-17 20:28:174846 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4847 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454848 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304849}
4850
[email protected]1e960032013-12-20 19:00:204851TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204852 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524853 quic::QuicStreamOffset header_stream_offset = 0;
4854 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4855 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434856 mock_quic_data.AddWrite(
4857 SYNCHRONOUS,
4858 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334859 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434860 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434861 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334862 ASYNC, ConstructServerResponseHeadersPacket(
4863 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4864 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414865 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334866 mock_quic_data.AddRead(
4867 ASYNC, ConstructServerDataPacket(
4868 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414869 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434870 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504871 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594872 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484873
rcha5399e02015-04-21 19:32:044874 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484875
rtennetib8e80fb2016-05-16 00:12:094876 // The non-alternate protocol job needs to hang in order to guarantee that
4877 // the alternate-protocol job will "win".
4878 AddHangingNonAlternateProtocolSocketData();
4879
rch3f4b8452016-02-23 16:59:324880 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274881 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194882 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304883
4884 EXPECT_EQ(nullptr,
4885 http_server_properties_.GetServerNetworkStats(
4886 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484887}
4888
[email protected]1e960032013-12-20 19:00:204889TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204890 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524891 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4892 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334893 mock_quic_data.AddWrite(
4894 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4895 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4896 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434897 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334898 ASYNC, ConstructServerResponseHeadersPacket(
4899 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4900 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414901 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334902 mock_quic_data.AddRead(
4903 ASYNC, ConstructServerDataPacket(
4904 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414905 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434906 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504907 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594908 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044909 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274910
4911 // In order for a new QUIC session to be established via alternate-protocol
4912 // without racing an HTTP connection, we need the host resolution to happen
4913 // synchronously.
4914 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294915 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564916 "");
[email protected]3a120a6b2013-06-25 01:08:274917
rtennetib8e80fb2016-05-16 00:12:094918 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324919 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274920 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274921 SendRequestAndExpectQuicResponse("hello!");
4922}
4923
[email protected]0fc924b2014-03-31 04:34:154924TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494925 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4926 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154927
4928 // Since we are using a proxy, the QUIC job will not succeed.
4929 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294930 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4931 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564932 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154933
4934 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564935 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484936 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564937 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154938
Ryan Sleevib8d7ea02018-05-07 20:01:014939 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154940 socket_factory_.AddSocketDataProvider(&http_data);
4941
4942 // In order for a new QUIC session to be established via alternate-protocol
4943 // without racing an HTTP connection, we need the host resolution to happen
4944 // synchronously.
4945 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294946 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564947 "");
[email protected]0fc924b2014-03-31 04:34:154948
rch9ae5b3b2016-02-11 00:36:294949 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324950 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274951 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154952 SendRequestAndExpectHttpResponse("hello world");
4953}
4954
[email protected]1e960032013-12-20 19:00:204955TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204956 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524957 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364958 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434959 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4960 mock_quic_data.AddWrite(
4961 SYNCHRONOUS,
4962 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334963 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434964 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434965 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334966 ASYNC, ConstructServerResponseHeadersPacket(
4967 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4968 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:414969 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:334970 mock_quic_data.AddRead(
4971 ASYNC, ConstructServerDataPacket(
4972 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:414973 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434974 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594975 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044976 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124977
rtennetib8e80fb2016-05-16 00:12:094978 // The non-alternate protocol job needs to hang in order to guarantee that
4979 // the alternate-protocol job will "win".
4980 AddHangingNonAlternateProtocolSocketData();
4981
[email protected]11c05872013-08-20 02:04:124982 // In order for a new QUIC session to be established via alternate-protocol
4983 // without racing an HTTP connection, we need the host resolution to happen
4984 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4985 // connection to the the server, in this test we require confirmation
4986 // before encrypting so the HTTP job will still start.
4987 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294988 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564989 "");
[email protected]11c05872013-08-20 02:04:124990
rch3f4b8452016-02-23 16:59:324991 CreateSession();
[email protected]11c05872013-08-20 02:04:124992 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274993 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124994
bnc691fda62016-08-12 00:43:164995 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124996 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:364997 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014998 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124999
5000 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525001 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015002 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505003
bnc691fda62016-08-12 00:43:165004 CheckWasQuicResponse(&trans);
5005 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125006}
5007
Steven Valdez58097ec32018-07-16 18:29:045008TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5009 MockQuicData mock_quic_data;
5010 quic::QuicStreamOffset client_header_stream_offset = 0;
5011 quic::QuicStreamOffset server_header_stream_offset = 0;
5012 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5013 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045014 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335015 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5016 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5017 true, GetRequestHeaders("GET", "https", "/"),
5018 &client_header_stream_offset));
5019 mock_quic_data.AddRead(
5020 ASYNC,
5021 ConstructServerResponseHeadersPacket(
5022 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5023 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5024 mock_quic_data.AddWrite(SYNCHRONOUS,
5025 ConstructClientAckAndRstPacket(
5026 2, GetNthClientInitiatedBidirectionalStreamId(0),
5027 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045028
5029 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5030
5031 spdy::SpdySettingsIR settings_frame;
5032 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5033 quic::kDefaultMaxUncompressedHeaderSize);
5034 spdy::SpdySerializedFrame spdy_frame(
5035 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5036 mock_quic_data.AddWrite(
5037 SYNCHRONOUS,
5038 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385039 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5040 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045041 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5042 client_header_stream_offset += spdy_frame.size();
5043
5044 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335045 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5046 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5047 true, GetRequestHeaders("GET", "https", "/"),
5048 GetNthClientInitiatedBidirectionalStreamId(0),
5049 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045050 mock_quic_data.AddRead(
5051 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335052 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045053 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjief49758b2019-01-11 23:32:415054 quic::QuicString header = ConstructDataHeader(6);
Steven Valdez58097ec32018-07-16 18:29:045055 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335056 ASYNC, ConstructServerDataPacket(
5057 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:415058 0, header + "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045059 mock_quic_data.AddWrite(
5060 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5061 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5062 mock_quic_data.AddRead(ASYNC, 0); // EOF
5063
5064 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5065
5066 // In order for a new QUIC session to be established via alternate-protocol
5067 // without racing an HTTP connection, we need the host resolution to happen
5068 // synchronously.
5069 host_resolver_.set_synchronous_mode(true);
5070 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5071 "");
Steven Valdez58097ec32018-07-16 18:29:045072
5073 AddHangingNonAlternateProtocolSocketData();
5074 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275075 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565076 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5077 QuicStreamFactoryPeer::SetAlarmFactory(
5078 session_->quic_stream_factory(),
5079 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5080 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045081
5082 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5083 TestCompletionCallback callback;
5084 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5086
5087 // Confirm the handshake after the 425 Too Early.
5088 base::RunLoop().RunUntilIdle();
5089
5090 // The handshake hasn't been confirmed yet, so the retry should not have
5091 // succeeded.
5092 EXPECT_FALSE(callback.have_result());
5093
5094 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5095 quic::QuicSession::HANDSHAKE_CONFIRMED);
5096
5097 EXPECT_THAT(callback.WaitForResult(), IsOk());
5098 CheckWasQuicResponse(&trans);
5099 CheckResponseData(&trans, "hello!");
5100}
5101
5102TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5103 MockQuicData mock_quic_data;
5104 quic::QuicStreamOffset client_header_stream_offset = 0;
5105 quic::QuicStreamOffset server_header_stream_offset = 0;
5106 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5107 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045108 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335109 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5110 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5111 true, GetRequestHeaders("GET", "https", "/"),
5112 &client_header_stream_offset));
5113 mock_quic_data.AddRead(
5114 ASYNC,
5115 ConstructServerResponseHeadersPacket(
5116 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5117 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5118 mock_quic_data.AddWrite(SYNCHRONOUS,
5119 ConstructClientAckAndRstPacket(
5120 2, GetNthClientInitiatedBidirectionalStreamId(0),
5121 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045122
5123 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5124
5125 spdy::SpdySettingsIR settings_frame;
5126 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5127 quic::kDefaultMaxUncompressedHeaderSize);
5128 spdy::SpdySerializedFrame spdy_frame(
5129 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5130 mock_quic_data.AddWrite(
5131 SYNCHRONOUS,
5132 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385133 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5134 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045135 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5136 client_header_stream_offset += spdy_frame.size();
5137
5138 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335139 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5140 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5141 true, GetRequestHeaders("GET", "https", "/"),
5142 GetNthClientInitiatedBidirectionalStreamId(0),
5143 &client_header_stream_offset));
5144 mock_quic_data.AddRead(
5145 ASYNC,
5146 ConstructServerResponseHeadersPacket(
5147 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5148 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5149 mock_quic_data.AddWrite(SYNCHRONOUS,
5150 ConstructClientAckAndRstPacket(
5151 5, GetNthClientInitiatedBidirectionalStreamId(1),
5152 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045153 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5154 mock_quic_data.AddRead(ASYNC, 0); // EOF
5155
5156 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5157
5158 // In order for a new QUIC session to be established via alternate-protocol
5159 // without racing an HTTP connection, we need the host resolution to happen
5160 // synchronously.
5161 host_resolver_.set_synchronous_mode(true);
5162 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5163 "");
Steven Valdez58097ec32018-07-16 18:29:045164
5165 AddHangingNonAlternateProtocolSocketData();
5166 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275167 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565168 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5169 QuicStreamFactoryPeer::SetAlarmFactory(
5170 session_->quic_stream_factory(),
5171 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5172 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045173
5174 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5175 TestCompletionCallback callback;
5176 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5178
5179 // Confirm the handshake after the 425 Too Early.
5180 base::RunLoop().RunUntilIdle();
5181
5182 // The handshake hasn't been confirmed yet, so the retry should not have
5183 // succeeded.
5184 EXPECT_FALSE(callback.have_result());
5185
5186 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5187 quic::QuicSession::HANDSHAKE_CONFIRMED);
5188
5189 EXPECT_THAT(callback.WaitForResult(), IsOk());
5190 const HttpResponseInfo* response = trans.GetResponseInfo();
5191 ASSERT_TRUE(response != nullptr);
5192 ASSERT_TRUE(response->headers.get() != nullptr);
5193 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5194 EXPECT_TRUE(response->was_fetched_via_spdy);
5195 EXPECT_TRUE(response->was_alpn_negotiated);
5196 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5197 response->connection_info);
5198}
5199
zhongyica364fbb2015-12-12 03:39:125200TEST_P(QuicNetworkTransactionTest,
5201 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485202 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125203 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525204 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365205 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435206 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5207 mock_quic_data.AddWrite(
5208 SYNCHRONOUS,
5209 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335210 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435211 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125212 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525213 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435214 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125215 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5216
5217 // The non-alternate protocol job needs to hang in order to guarantee that
5218 // the alternate-protocol job will "win".
5219 AddHangingNonAlternateProtocolSocketData();
5220
5221 // In order for a new QUIC session to be established via alternate-protocol
5222 // without racing an HTTP connection, we need the host resolution to happen
5223 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5224 // connection to the the server, in this test we require confirmation
5225 // before encrypting so the HTTP job will still start.
5226 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295227 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125228 "");
zhongyica364fbb2015-12-12 03:39:125229
rch3f4b8452016-02-23 16:59:325230 CreateSession();
zhongyica364fbb2015-12-12 03:39:125231 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275232 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125233
bnc691fda62016-08-12 00:43:165234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125235 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365236 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015237 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125238
5239 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525240 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015241 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125242
5243 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525244 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125245
bnc691fda62016-08-12 00:43:165246 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125247 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525248 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5249 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125250}
5251
5252TEST_P(QuicNetworkTransactionTest,
5253 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485254 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125255 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525256 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365257 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435258 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5259 mock_quic_data.AddWrite(
5260 SYNCHRONOUS,
5261 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335262 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435263 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215264 // Peer sending data from an non-existing stream causes this end to raise
5265 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335266 mock_quic_data.AddRead(
5267 ASYNC, ConstructServerRstPacket(
5268 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5269 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215270 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525271 mock_quic_data.AddWrite(
5272 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5273 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5274 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125275 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5276
5277 // The non-alternate protocol job needs to hang in order to guarantee that
5278 // the alternate-protocol job will "win".
5279 AddHangingNonAlternateProtocolSocketData();
5280
5281 // In order for a new QUIC session to be established via alternate-protocol
5282 // without racing an HTTP connection, we need the host resolution to happen
5283 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5284 // connection to the the server, in this test we require confirmation
5285 // before encrypting so the HTTP job will still start.
5286 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295287 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125288 "");
zhongyica364fbb2015-12-12 03:39:125289
rch3f4b8452016-02-23 16:59:325290 CreateSession();
zhongyica364fbb2015-12-12 03:39:125291 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275292 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125293
bnc691fda62016-08-12 00:43:165294 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125295 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365296 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015297 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125298
5299 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525300 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015301 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125302 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525303 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125304
bnc691fda62016-08-12 00:43:165305 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525306 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125307}
5308
rchcd5f1c62016-06-23 02:43:485309TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5310 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525311 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365312 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435313 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5314 mock_quic_data.AddWrite(
5315 SYNCHRONOUS,
5316 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335317 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435318 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485319 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335320 mock_quic_data.AddRead(
5321 ASYNC, ConstructServerResponseHeadersPacket(
5322 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5323 GetResponseHeaders("200 OK")));
5324 mock_quic_data.AddRead(
5325 ASYNC, ConstructServerRstPacket(
5326 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5327 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435328 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485329 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5330 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5331
5332 // The non-alternate protocol job needs to hang in order to guarantee that
5333 // the alternate-protocol job will "win".
5334 AddHangingNonAlternateProtocolSocketData();
5335
5336 // In order for a new QUIC session to be established via alternate-protocol
5337 // without racing an HTTP connection, we need the host resolution to happen
5338 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5339 // connection to the the server, in this test we require confirmation
5340 // before encrypting so the HTTP job will still start.
5341 host_resolver_.set_synchronous_mode(true);
5342 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5343 "");
rchcd5f1c62016-06-23 02:43:485344
5345 CreateSession();
5346 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275347 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485348
bnc691fda62016-08-12 00:43:165349 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485350 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365351 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015352 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485353
5354 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525355 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485356 // Read the headers.
robpercival214763f2016-07-01 23:27:015357 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485358
bnc691fda62016-08-12 00:43:165359 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485360 ASSERT_TRUE(response != nullptr);
5361 ASSERT_TRUE(response->headers.get() != nullptr);
5362 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5363 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525364 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445365 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5366 response->connection_info);
rchcd5f1c62016-06-23 02:43:485367
5368 std::string response_data;
bnc691fda62016-08-12 00:43:165369 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485370}
5371
5372TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485373 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485374 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525375 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365376 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435377 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5378 mock_quic_data.AddWrite(
5379 SYNCHRONOUS,
5380 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335381 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435382 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335383 mock_quic_data.AddRead(
5384 ASYNC, ConstructServerRstPacket(
5385 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5386 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485387 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5388 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5389
5390 // The non-alternate protocol job needs to hang in order to guarantee that
5391 // the alternate-protocol job will "win".
5392 AddHangingNonAlternateProtocolSocketData();
5393
5394 // In order for a new QUIC session to be established via alternate-protocol
5395 // without racing an HTTP connection, we need the host resolution to happen
5396 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5397 // connection to the the server, in this test we require confirmation
5398 // before encrypting so the HTTP job will still start.
5399 host_resolver_.set_synchronous_mode(true);
5400 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5401 "");
rchcd5f1c62016-06-23 02:43:485402
5403 CreateSession();
5404 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275405 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485406
bnc691fda62016-08-12 00:43:165407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485408 TestCompletionCallback callback;
Eric Orth608a2992019-02-20 19:29:365409 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485411
5412 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525413 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485414 // Read the headers.
robpercival214763f2016-07-01 23:27:015415 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485416}
5417
[email protected]1e960032013-12-20 19:00:205418TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305419 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525420 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585421 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305422 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505423 MockRead(ASYNC, close->data(), close->length()),
5424 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5425 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305426 };
Ryan Sleevib8d7ea02018-05-07 20:01:015427 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305428 socket_factory_.AddSocketDataProvider(&quic_data);
5429
5430 // Main job which will succeed even though the alternate job fails.
5431 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025432 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5433 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5434 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305435
Ryan Sleevib8d7ea02018-05-07 20:01:015436 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305437 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565438 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305439
rch3f4b8452016-02-23 16:59:325440 CreateSession();
David Schinazic8281052019-01-24 06:14:175441 AddQuicAlternateProtocolMapping(
5442 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]aa9b14d2013-05-10 23:45:195443 SendRequestAndExpectHttpResponse("hello from http");
5444 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305445}
5446
[email protected]1e960032013-12-20 19:00:205447TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595448 // Alternate-protocol job
5449 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025450 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595451 };
Ryan Sleevib8d7ea02018-05-07 20:01:015452 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595453 socket_factory_.AddSocketDataProvider(&quic_data);
5454
5455 // Main job which will succeed even though the alternate job fails.
5456 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025457 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5458 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5459 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595460
Ryan Sleevib8d7ea02018-05-07 20:01:015461 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595462 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565463 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595464
rch3f4b8452016-02-23 16:59:325465 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595466
Ryan Hamilton9835e662018-08-02 05:36:275467 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195468 SendRequestAndExpectHttpResponse("hello from http");
5469 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595470}
5471
[email protected]00c159f2014-05-21 22:38:165472TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535473 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165474 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025475 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165476 };
Ryan Sleevib8d7ea02018-05-07 20:01:015477 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165478 socket_factory_.AddSocketDataProvider(&quic_data);
5479
[email protected]eb71ab62014-05-23 07:57:535480 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165481 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025482 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165483 };
5484
Ryan Sleevib8d7ea02018-05-07 20:01:015485 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165486 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5487 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565488 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165489
rtennetib8e80fb2016-05-16 00:12:095490 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325491 CreateSession();
[email protected]00c159f2014-05-21 22:38:165492
Ryan Hamilton9835e662018-08-02 05:36:275493 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165494 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165495 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165496 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015497 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5498 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165499 ExpectQuicAlternateProtocolMapping();
5500}
5501
Zhongyi Shia0cef1082017-08-25 01:49:505502TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5503 // Tests that TCP job is delayed and QUIC job does not require confirmation
5504 // if QUIC was recently supported on the same IP on start.
5505
5506 // Set QUIC support on the last IP address, which is same with the local IP
5507 // address. Require confirmation mode will be turned off immediately when
5508 // local IP address is sorted out after we configure the UDP socket.
5509 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5510
5511 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525512 quic::QuicStreamOffset header_stream_offset = 0;
5513 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5514 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435515 mock_quic_data.AddWrite(
5516 SYNCHRONOUS,
5517 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335518 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435519 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435520 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335521 ASYNC, ConstructServerResponseHeadersPacket(
5522 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5523 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415524 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335525 mock_quic_data.AddRead(
5526 ASYNC, ConstructServerDataPacket(
5527 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415528 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435529 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505530 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5531 mock_quic_data.AddRead(ASYNC, 0); // EOF
5532
5533 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5534 // No HTTP data is mocked as TCP job never starts in this case.
5535
5536 CreateSession();
5537 // QuicStreamFactory by default requires confirmation on construction.
5538 session_->quic_stream_factory()->set_require_confirmation(true);
5539
Ryan Hamilton9835e662018-08-02 05:36:275540 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505541
5542 // Stall host resolution so that QUIC job will not succeed synchronously.
5543 // Socket will not be configured immediately and QUIC support is not sorted
5544 // out, TCP job will still be delayed as server properties indicates QUIC
5545 // support on last IP address.
5546 host_resolver_.set_synchronous_mode(false);
5547
5548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5549 TestCompletionCallback callback;
5550 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5551 IsError(ERR_IO_PENDING));
5552 // Complete host resolution in next message loop so that QUIC job could
5553 // proceed.
5554 base::RunLoop().RunUntilIdle();
5555 EXPECT_THAT(callback.WaitForResult(), IsOk());
5556
5557 CheckWasQuicResponse(&trans);
5558 CheckResponseData(&trans, "hello!");
5559}
5560
5561TEST_P(QuicNetworkTransactionTest,
5562 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5563 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5564 // was recently supported on a different IP address on start.
5565
5566 // Set QUIC support on the last IP address, which is different with the local
5567 // IP address. Require confirmation mode will remain when local IP address is
5568 // sorted out after we configure the UDP socket.
5569 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5570
5571 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525572 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505573 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435574 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5575 mock_quic_data.AddWrite(
5576 SYNCHRONOUS,
5577 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335578 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435579 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435580 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335581 ASYNC, ConstructServerResponseHeadersPacket(
5582 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5583 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415584 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335585 mock_quic_data.AddRead(
5586 ASYNC, ConstructServerDataPacket(
5587 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415588 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435589 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505590 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5591 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5592 // No HTTP data is mocked as TCP job will be delayed and never starts.
5593
5594 CreateSession();
5595 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275596 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505597
5598 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5599 // Socket will not be configured immediately and QUIC support is not sorted
5600 // out, TCP job will still be delayed as server properties indicates QUIC
5601 // support on last IP address.
5602 host_resolver_.set_synchronous_mode(false);
5603
5604 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5605 TestCompletionCallback callback;
5606 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5607 IsError(ERR_IO_PENDING));
5608
5609 // Complete host resolution in next message loop so that QUIC job could
5610 // proceed.
5611 base::RunLoop().RunUntilIdle();
5612 // Explicitly confirm the handshake so that QUIC job could succeed.
5613 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525614 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505615 EXPECT_THAT(callback.WaitForResult(), IsOk());
5616
5617 CheckWasQuicResponse(&trans);
5618 CheckResponseData(&trans, "hello!");
5619}
5620
Ryan Hamilton75f197262017-08-17 14:00:075621TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5622 // Test that NetErrorDetails is correctly populated, even if the
5623 // handshake has not yet been confirmed and no stream has been created.
5624
5625 // QUIC job will pause. When resumed, it will fail.
5626 MockQuicData mock_quic_data;
5627 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5628 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5629 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5630
5631 // Main job will also fail.
5632 MockRead http_reads[] = {
5633 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5634 };
5635
Ryan Sleevib8d7ea02018-05-07 20:01:015636 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075637 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5638 socket_factory_.AddSocketDataProvider(&http_data);
5639 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5640
5641 AddHangingNonAlternateProtocolSocketData();
5642 CreateSession();
5643 // Require handshake confirmation to ensure that no QUIC streams are
5644 // created, and to ensure that the TCP job does not wait for the QUIC
5645 // job to fail before it starts.
5646 session_->quic_stream_factory()->set_require_confirmation(true);
5647
Ryan Hamilton9835e662018-08-02 05:36:275648 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5650 TestCompletionCallback callback;
5651 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5653 // Allow the TCP job to fail.
5654 base::RunLoop().RunUntilIdle();
5655 // Now let the QUIC job fail.
5656 mock_quic_data.Resume();
5657 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5658 ExpectQuicAlternateProtocolMapping();
5659 NetErrorDetails details;
5660 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525661 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075662}
5663
[email protected]1e960032013-12-20 19:00:205664TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455665 // Alternate-protocol job
5666 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025667 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455668 };
Ryan Sleevib8d7ea02018-05-07 20:01:015669 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455670 socket_factory_.AddSocketDataProvider(&quic_data);
5671
[email protected]c92c1b52014-05-31 04:16:065672 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015673 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065674 socket_factory_.AddSocketDataProvider(&quic_data2);
5675
[email protected]4d283b32013-10-17 12:57:275676 // Final job that will proceed when the QUIC job fails.
5677 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025678 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5679 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5680 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275681
Ryan Sleevib8d7ea02018-05-07 20:01:015682 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275683 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565684 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275685
rtennetiafccbc062016-05-16 18:21:145686 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325687 CreateSession();
[email protected]77c6c162013-08-17 02:57:455688
Ryan Hamilton9835e662018-08-02 05:36:275689 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455690
[email protected]4d283b32013-10-17 12:57:275691 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455692
5693 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275694
rch37de576c2015-05-17 20:28:175695 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5696 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455697}
5698
[email protected]93b31772014-06-19 08:03:355699TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035700 // Alternate-protocol job
5701 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595702 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035703 };
Ryan Sleevib8d7ea02018-05-07 20:01:015704 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035705 socket_factory_.AddSocketDataProvider(&quic_data);
5706
5707 // Main job that will proceed when the QUIC job fails.
5708 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025709 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5710 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5711 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035712
Ryan Sleevib8d7ea02018-05-07 20:01:015713 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035714 socket_factory_.AddSocketDataProvider(&http_data);
5715
rtennetib8e80fb2016-05-16 00:12:095716 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325717 CreateSession();
[email protected]65768442014-06-06 23:37:035718
Ryan Hamilton9835e662018-08-02 05:36:275719 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035720
5721 SendRequestAndExpectHttpResponse("hello from http");
5722}
5723
[email protected]eb71ab62014-05-23 07:57:535724TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335725 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015726 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495727 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335728 socket_factory_.AddSocketDataProvider(&quic_data);
5729
5730 // Main job which will succeed even though the alternate job fails.
5731 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025732 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5733 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5734 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335735
Ryan Sleevib8d7ea02018-05-07 20:01:015736 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335737 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565738 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335739
rch3f4b8452016-02-23 16:59:325740 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275741 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335742 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535743
5744 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335745}
5746
[email protected]4fee9672014-01-08 14:47:155747TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155748 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175749 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5750 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
rcha5399e02015-04-21 19:32:045751 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155752
5753 // When the QUIC connection fails, we will try the request again over HTTP.
5754 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485755 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565756 MockRead("hello world"),
5757 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5758 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155759
Ryan Sleevib8d7ea02018-05-07 20:01:015760 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155761 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565762 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155763
5764 // In order for a new QUIC session to be established via alternate-protocol
5765 // without racing an HTTP connection, we need the host resolution to happen
5766 // synchronously.
5767 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295768 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565769 "");
[email protected]4fee9672014-01-08 14:47:155770
rch3f4b8452016-02-23 16:59:325771 CreateSession();
David Schinazic8281052019-01-24 06:14:175772 // TODO(rch): Check if we need a 0RTT version of ConnectionCloseDuringConnect
5773 AddQuicAlternateProtocolMapping(
5774 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
[email protected]4fee9672014-01-08 14:47:155775 SendRequestAndExpectHttpResponse("hello world");
5776}
5777
tbansalc3308d72016-08-27 10:25:045778// For an alternative proxy that supports QUIC, test that the request is
5779// successfully fetched by the main job when the alternate proxy job encounters
5780// an error.
5781TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5782 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5783}
5784TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5785 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5786}
5787TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5788 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5789}
5790TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5791 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5792}
5793TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5794 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5795}
5796TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5797 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5798}
5799TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5800 TestAlternativeProxy(ERR_IO_PENDING);
5801}
5802TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5803 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5804}
5805
5806TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5807 MockQuicData mock_quic_data;
David Schinazic8281052019-01-24 06:14:175808 mock_quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5809 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335810 mock_quic_data.AddWrite(
5811 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5812 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5813 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435814 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045815 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5816
5817 // When the QUIC connection fails, we will try the request again over HTTP.
5818 MockRead http_reads[] = {
5819 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5820 MockRead("hello world"),
5821 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5822 MockRead(ASYNC, OK)};
5823
Ryan Sleevib8d7ea02018-05-07 20:01:015824 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045825 socket_factory_.AddSocketDataProvider(&http_data);
5826 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5827
5828 TestProxyDelegate test_proxy_delegate;
5829 const HostPortPair host_port_pair("myproxy.org", 443);
5830 test_proxy_delegate.set_alternative_proxy_server(
5831 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5832 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5833
Ramin Halavatica8d5252018-03-12 05:33:495834 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5835 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525836 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045837 request_.url = GURL("http://mail.example.org/");
5838
5839 // In order for a new QUIC session to be established via alternate-protocol
5840 // without racing an HTTP connection, we need the host resolution to happen
5841 // synchronously.
5842 host_resolver_.set_synchronous_mode(true);
5843 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
tbansalc3308d72016-08-27 10:25:045844
5845 CreateSession();
David Schinazic8281052019-01-24 06:14:175846 crypto_client_stream_factory_.set_handshake_mode(
5847 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
tbansalc3308d72016-08-27 10:25:045848 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595849 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165850 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045851}
5852
bnc508835902015-05-12 20:10:295853TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585854 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385855 EXPECT_FALSE(
5856 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295857 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525858 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365859 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435860 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5861 mock_quic_data.AddWrite(
5862 SYNCHRONOUS,
5863 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335864 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435865 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435866 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335867 ASYNC, ConstructServerResponseHeadersPacket(
5868 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5869 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:415870 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:335871 mock_quic_data.AddRead(
5872 ASYNC, ConstructServerDataPacket(
5873 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:415874 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435875 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505876 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295877 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5878
bncb07c05532015-05-14 19:07:205879 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095880 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325881 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275882 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295883 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385884 EXPECT_TRUE(
5885 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295886}
5887
zhongyi363c91c2017-03-23 23:16:085888// TODO(zhongyi): disabled this broken test as it was not testing the correct
5889// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5890TEST_P(QuicNetworkTransactionTest,
5891 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275892 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595893 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495894 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045895
5896 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045897
5898 test_proxy_delegate.set_alternative_proxy_server(
5899 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525900 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045901
5902 request_.url = GURL("http://mail.example.org/");
5903
5904 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5905 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015906 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045907 socket_factory_.AddSocketDataProvider(&socket_data);
5908
5909 // The non-alternate protocol job needs to hang in order to guarantee that
5910 // the alternate-protocol job will "win".
5911 AddHangingNonAlternateProtocolSocketData();
5912
5913 CreateSession();
5914 request_.method = "POST";
5915 ChunkedUploadDataStream upload_data(0);
5916 upload_data.AppendData("1", 1, true);
5917
5918 request_.upload_data_stream = &upload_data;
5919
5920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5921 TestCompletionCallback callback;
5922 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5924 EXPECT_NE(OK, callback.WaitForResult());
5925
5926 // Verify that the alternative proxy server is not marked as broken.
5927 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5928
5929 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595930 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275931
5932 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5933 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5934 1);
tbansalc3308d72016-08-27 10:25:045935}
5936
rtenneti56977812016-01-15 19:26:565937TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415938 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575939 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565940
5941 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5942 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015943 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565944 socket_factory_.AddSocketDataProvider(&socket_data);
5945
rtennetib8e80fb2016-05-16 00:12:095946 // The non-alternate protocol job needs to hang in order to guarantee that
5947 // the alternate-protocol job will "win".
5948 AddHangingNonAlternateProtocolSocketData();
5949
rtenneti56977812016-01-15 19:26:565950 CreateSession();
5951 request_.method = "POST";
5952 ChunkedUploadDataStream upload_data(0);
5953 upload_data.AppendData("1", 1, true);
5954
5955 request_.upload_data_stream = &upload_data;
5956
bnc691fda62016-08-12 00:43:165957 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565958 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165959 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015960 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565961 EXPECT_NE(OK, callback.WaitForResult());
5962}
5963
rche11300ef2016-09-02 01:44:285964TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485965 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285966 ScopedMockNetworkChangeNotifier network_change_notifier;
5967 MockNetworkChangeNotifier* mock_ncn =
5968 network_change_notifier.mock_network_change_notifier();
5969 mock_ncn->ForceNetworkHandlesSupported();
5970 mock_ncn->SetConnectedNetworksList(
5971 {kDefaultNetworkForTests, kNewNetworkForTests});
5972
mmenke6ddfbea2017-05-31 21:48:415973 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285974 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315975 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285976
5977 MockQuicData socket_data;
5978 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525979 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435980 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:335981 socket_data.AddWrite(
5982 SYNCHRONOUS,
5983 ConstructClientRequestHeadersPacket(
5984 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
5985 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:285986 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5987 socket_data.AddSocketDataToFactory(&socket_factory_);
5988
5989 MockQuicData socket_data2;
5990 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5991 socket_data2.AddSocketDataToFactory(&socket_factory_);
5992
5993 // The non-alternate protocol job needs to hang in order to guarantee that
5994 // the alternate-protocol job will "win".
5995 AddHangingNonAlternateProtocolSocketData();
5996
5997 CreateSession();
5998 request_.method = "POST";
5999 ChunkedUploadDataStream upload_data(0);
6000
6001 request_.upload_data_stream = &upload_data;
6002
rdsmith1d343be52016-10-21 20:37:506003 std::unique_ptr<HttpNetworkTransaction> trans(
6004 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286005 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506006 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286007 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6008
6009 base::RunLoop().RunUntilIdle();
6010 upload_data.AppendData("1", 1, true);
6011 base::RunLoop().RunUntilIdle();
6012
6013 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506014 trans.reset();
rche11300ef2016-09-02 01:44:286015 session_.reset();
6016}
6017
Ryan Hamilton4b3574532017-10-30 20:17:256018TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6019 session_params_.origins_to_force_quic_on.insert(
6020 HostPortPair::FromString("mail.example.org:443"));
6021
6022 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526023 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436024 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256025 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336026 socket_data.AddWrite(
6027 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6028 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6029 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436030 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336031 ASYNC, ConstructServerResponseHeadersPacket(
6032 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6033 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416034 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336035 socket_data.AddRead(
6036 ASYNC, ConstructServerDataPacket(
6037 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416038 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436039 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256040 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166041 socket_data.AddWrite(
6042 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6043 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6044 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256045
6046 socket_data.AddSocketDataToFactory(&socket_factory_);
6047
6048 CreateSession();
6049
6050 SendRequestAndExpectQuicResponse("hello!");
6051 session_.reset();
6052}
6053
6054TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6055 session_params_.origins_to_force_quic_on.insert(
6056 HostPortPair::FromString("mail.example.org:443"));
6057
6058 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526059 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436060 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256061 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336062 socket_data.AddWrite(
6063 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6064 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6065 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436066 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336067 ASYNC, ConstructServerResponseHeadersPacket(
6068 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6069 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416070 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336071 socket_data.AddRead(
6072 ASYNC, ConstructServerDataPacket(
6073 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416074 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436075 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256076 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166077 socket_data.AddWrite(
6078 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6079 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6080 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256081
6082 socket_data.AddSocketDataToFactory(&socket_factory_);
6083
6084 CreateSession();
6085
6086 SendRequestAndExpectQuicResponse("hello!");
6087 session_.reset();
6088}
6089
Ryan Hamilton9edcf1a2017-11-22 05:55:176090TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486091 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256092 session_params_.origins_to_force_quic_on.insert(
6093 HostPortPair::FromString("mail.example.org:443"));
6094
6095 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526096 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256097 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436098 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176099 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256100 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6101 }
6102 socket_data.AddSocketDataToFactory(&socket_factory_);
6103
6104 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176105 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6106 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6107 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6108 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256109
Ryan Hamilton8d9ee76e2018-05-29 23:52:526110 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256111 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6112 TestCompletionCallback callback;
6113 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176115 while (!callback.have_result()) {
6116 base::RunLoop().RunUntilIdle();
6117 quic_task_runner_->RunUntilIdle();
6118 }
6119 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256120 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176121 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6122 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6123 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526124 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6125 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256126}
6127
Ryan Hamilton9edcf1a2017-11-22 05:55:176128TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486129 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256130 session_params_.origins_to_force_quic_on.insert(
6131 HostPortPair::FromString("mail.example.org:443"));
6132
6133 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526134 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256135 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436136 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176137 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256138 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6139 }
6140 socket_data.AddSocketDataToFactory(&socket_factory_);
6141
6142 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176143 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6144 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6145 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6146 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256147
Ryan Hamilton8d9ee76e2018-05-29 23:52:526148 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256149 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6150 TestCompletionCallback callback;
6151 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176153 while (!callback.have_result()) {
6154 base::RunLoop().RunUntilIdle();
6155 quic_task_runner_->RunUntilIdle();
6156 }
6157 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256158 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176159 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6160 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6161 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526162 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6163 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256164}
6165
Cherie Shi7596de632018-02-22 07:28:186166TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486167 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186168 session_params_.origins_to_force_quic_on.insert(
6169 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526170 const quic::QuicString error_details =
6171 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6172 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186173
6174 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526175 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186176 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436177 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186178 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6179 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526180 socket_data.AddWrite(
6181 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6182 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186183 socket_data.AddSocketDataToFactory(&socket_factory_);
6184
6185 CreateSession();
6186
6187 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6188 TestCompletionCallback callback;
6189 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6190 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6191 base::RunLoop().RunUntilIdle();
6192 ASSERT_TRUE(callback.have_result());
6193 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6194 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6195 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6196}
6197
ckrasic769733c2016-06-30 00:42:136198// Adds coverage to catch regression such as https://crbug.com/622043
6199TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416200 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136201 HostPortPair::FromString("mail.example.org:443"));
6202
6203 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526204 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236205 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436206 mock_quic_data.AddWrite(
6207 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6208 &header_stream_offset));
6209 mock_quic_data.AddWrite(
6210 SYNCHRONOUS,
6211 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336212 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6213 true, true, GetRequestHeaders("GET", "https", "/"),
6214 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526215 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436216 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336217 ASYNC, ConstructServerPushPromisePacket(
6218 1, GetNthClientInitiatedBidirectionalStreamId(0),
6219 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6220 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6221 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576222 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266223 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336224 mock_quic_data.AddWrite(SYNCHRONOUS,
6225 ConstructClientPriorityPacket(
6226 client_packet_number++, false,
6227 GetNthServerInitiatedUnidirectionalStreamId(0),
6228 GetNthClientInitiatedBidirectionalStreamId(0),
6229 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576230 }
Zhongyi Shi32f2fd02018-04-16 18:23:436231 mock_quic_data.AddRead(
6232 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336233 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436234 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576235 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436236 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6237 mock_quic_data.AddRead(
6238 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336239 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6240 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416241 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436242 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336243 ASYNC, ConstructServerDataPacket(
6244 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416245 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576246 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436247 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416248 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:436249 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336250 ASYNC, ConstructServerDataPacket(
6251 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416252 0, header2 + "and hello!"));
Fan Yang32c5a112018-12-10 20:06:336253 mock_quic_data.AddWrite(SYNCHRONOUS,
6254 ConstructClientAckAndRstPacket(
6255 client_packet_number++,
6256 GetNthServerInitiatedUnidirectionalStreamId(0),
6257 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136258 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6259 mock_quic_data.AddRead(ASYNC, 0); // EOF
6260 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6261
6262 // The non-alternate protocol job needs to hang in order to guarantee that
6263 // the alternate-protocol job will "win".
6264 AddHangingNonAlternateProtocolSocketData();
6265
6266 CreateSession();
6267
6268 // PUSH_PROMISE handling in the http layer gets exercised here.
6269 SendRequestAndExpectQuicResponse("hello!");
6270
6271 request_.url = GURL("https://mail.example.org/pushed.jpg");
6272 SendRequestAndExpectQuicResponse("and hello!");
6273
6274 // Check that the NetLog was filled reasonably.
6275 TestNetLogEntry::List entries;
6276 net_log_.GetEntries(&entries);
6277 EXPECT_LT(0u, entries.size());
6278
6279 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6280 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006281 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6282 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136283 EXPECT_LT(0, pos);
6284}
6285
rch56ec40a2017-06-23 14:48:446286// Regression test for http://crbug.com/719461 in which a promised stream
6287// is closed before the pushed headers arrive, but after the connection
6288// is closed and before the callbacks are executed.
6289TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486290 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446291 session_params_.origins_to_force_quic_on.insert(
6292 HostPortPair::FromString("mail.example.org:443"));
6293
6294 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526295 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236296 uint64_t client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446297 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436298 mock_quic_data.AddWrite(
6299 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6300 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446301 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436302 mock_quic_data.AddWrite(
6303 SYNCHRONOUS,
6304 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336305 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6306 true, true, GetRequestHeaders("GET", "https", "/"),
6307 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526308 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446309 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436310 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336311 ASYNC, ConstructServerPushPromisePacket(
6312 1, GetNthClientInitiatedBidirectionalStreamId(0),
6313 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6314 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6315 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576316 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266317 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336318 mock_quic_data.AddWrite(SYNCHRONOUS,
6319 ConstructClientPriorityPacket(
6320 client_packet_number++, false,
6321 GetNthServerInitiatedUnidirectionalStreamId(0),
6322 GetNthClientInitiatedBidirectionalStreamId(0),
6323 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576324 }
rch56ec40a2017-06-23 14:48:446325 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436326 mock_quic_data.AddRead(
6327 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336328 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436329 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446330 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576331 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436332 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446333 // Response body for first request.
Renjief49758b2019-01-11 23:32:416334 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:436335 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336336 ASYNC, ConstructServerDataPacket(
6337 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416338 0, header + "hello!"));
rch56ec40a2017-06-23 14:48:446339 // Write error for the third request.
6340 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6341 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6342 mock_quic_data.AddRead(ASYNC, 0); // EOF
6343 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6344
6345 CreateSession();
6346
6347 // Send a request which triggers a push promise from the server.
6348 SendRequestAndExpectQuicResponse("hello!");
6349
6350 // Start a push transaction that will be cancelled after the connection
6351 // is closed, but before the callback is executed.
6352 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196353 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446354 session_.get());
6355 TestCompletionCallback callback2;
6356 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6358 base::RunLoop().RunUntilIdle();
6359
6360 // Cause the connection to close on a write error.
6361 HttpRequestInfo request3;
6362 request3.method = "GET";
6363 request3.url = GURL("https://mail.example.org/");
6364 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106365 request3.traffic_annotation =
6366 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446367 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6368 TestCompletionCallback callback3;
6369 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6370 IsError(ERR_IO_PENDING));
6371
6372 base::RunLoop().RunUntilIdle();
6373
6374 // When |trans2| is destroyed, the underlying stream will be closed.
6375 EXPECT_FALSE(callback2.have_result());
6376 trans2 = nullptr;
6377
6378 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6379}
6380
ckrasicda193a82016-07-09 00:39:366381TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416382 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366383 HostPortPair::FromString("mail.example.org:443"));
6384
6385 MockQuicData mock_quic_data;
6386
Ryan Hamilton8d9ee76e2018-05-29 23:52:526387 quic::QuicStreamOffset offset = 0;
Renjief49758b2019-01-11 23:32:416388 int write_packet_index = 1;
6389 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
6390 write_packet_index++, &offset));
ckrasicda193a82016-07-09 00:39:366391
Renjief49758b2019-01-11 23:32:416392 quic::QuicString header = ConstructDataHeader(1);
6393 if (version_ != quic::QUIC_VERSION_99) {
6394 mock_quic_data.AddWrite(
6395 SYNCHRONOUS,
6396 ConstructClientRequestHeadersAndDataFramesPacket(
6397 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6398 true, true, DEFAULT_PRIORITY,
6399 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6400 {"1"}));
6401 } else {
6402 mock_quic_data.AddWrite(
6403 SYNCHRONOUS,
6404 ConstructClientRequestHeadersAndDataFramesPacket(
6405 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
6406 true, true, DEFAULT_PRIORITY,
6407 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr,
6408 {header, "1"}));
6409 }
ckrasicda193a82016-07-09 00:39:366410
Zhongyi Shi32f2fd02018-04-16 18:23:436411 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336412 ASYNC, ConstructServerResponseHeadersPacket(
6413 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6414 GetResponseHeaders("200 OK")));
6415
Renjief49758b2019-01-11 23:32:416416 quic::QuicString header2 = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336417 mock_quic_data.AddRead(
6418 ASYNC, ConstructServerDataPacket(
6419 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416420 0, header2 + "hello!"));
ckrasicda193a82016-07-09 00:39:366421
Renjief49758b2019-01-11 23:32:416422 mock_quic_data.AddWrite(
6423 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366424
6425 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6426 mock_quic_data.AddRead(ASYNC, 0); // EOF
6427 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6428
6429 // The non-alternate protocol job needs to hang in order to guarantee that
6430 // the alternate-protocol job will "win".
6431 AddHangingNonAlternateProtocolSocketData();
6432
6433 CreateSession();
6434 request_.method = "POST";
6435 ChunkedUploadDataStream upload_data(0);
6436 upload_data.AppendData("1", 1, true);
6437
6438 request_.upload_data_stream = &upload_data;
6439
6440 SendRequestAndExpectQuicResponse("hello!");
6441}
6442
allada71b2efb2016-09-09 04:57:486443class QuicURLRequestContext : public URLRequestContext {
6444 public:
6445 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6446 MockClientSocketFactory* socket_factory)
6447 : storage_(this) {
6448 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076449 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046450 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486451 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046452 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596453 storage_.set_proxy_resolution_service(
6454 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076455 storage_.set_ssl_config_service(
6456 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486457 storage_.set_http_auth_handler_factory(
6458 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6459 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076460 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046461 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486462 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046463 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6464 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6465 false));
allada71b2efb2016-09-09 04:57:486466 }
6467
6468 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6469
6470 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6471
6472 private:
6473 MockClientSocketFactory* socket_factory_;
6474 URLRequestContextStorage storage_;
6475};
6476
6477TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416478 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486479 HostPortPair::FromString("mail.example.org:443"));
6480
6481 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526482 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366483 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436484 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136485 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486486 headers["user-agent"] = "";
6487 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336488 mock_quic_data.AddWrite(
6489 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6490 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6491 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486492
Ryan Hamilton8d9ee76e2018-05-29 23:52:526493 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336494 mock_quic_data.AddRead(
6495 ASYNC,
6496 ConstructServerResponseHeadersPacket(
6497 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6498 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486499
Renjief49758b2019-01-11 23:32:416500 quic::QuicString header = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366501 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336502 ASYNC, ConstructServerDataPacket(
6503 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6504 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436505 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486506
6507 mock_quic_data.AddRead(ASYNC, 0); // EOF
6508
6509 CreateSession();
6510
6511 TestDelegate delegate;
6512 QuicURLRequestContext quic_url_request_context(std::move(session_),
6513 &socket_factory_);
6514
6515 mock_quic_data.AddSocketDataToFactory(
6516 &quic_url_request_context.socket_factory());
6517 TestNetworkDelegate network_delegate;
6518 quic_url_request_context.set_network_delegate(&network_delegate);
6519
6520 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296521 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6522 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486523 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6524 &ssl_data_);
6525
6526 request->Start();
Wez2a31b222018-06-07 22:07:156527 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486528
6529 EXPECT_LT(0, request->GetTotalSentBytes());
6530 EXPECT_LT(0, request->GetTotalReceivedBytes());
6531 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6532 request->GetTotalSentBytes());
6533 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6534 request->GetTotalReceivedBytes());
6535 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6536 request->raw_header_size());
Wez0e717112018-06-18 23:09:226537
6538 // Pump the message loop to allow all data to be consumed.
6539 base::RunLoop().RunUntilIdle();
6540
allada71b2efb2016-09-09 04:57:486541 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6542 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6543}
6544
6545TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416546 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486547 HostPortPair::FromString("mail.example.org:443"));
6548
6549 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526550 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:236551 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436552 mock_quic_data.AddWrite(
6553 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6554 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136555 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486556 headers["user-agent"] = "";
6557 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436558 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336559 SYNCHRONOUS,
6560 ConstructClientRequestHeadersPacket(
6561 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6562 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486563
Ryan Hamilton8d9ee76e2018-05-29 23:52:526564 quic::QuicStreamOffset server_header_offset = 0;
6565 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486566
Zhongyi Shi32f2fd02018-04-16 18:23:436567 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336568 ASYNC, ConstructServerPushPromisePacket(
6569 1, GetNthClientInitiatedBidirectionalStreamId(0),
6570 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6571 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6572 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486573
Yixin Wangb470bc882018-02-15 18:43:576574 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266575 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336576 mock_quic_data.AddWrite(SYNCHRONOUS,
6577 ConstructClientPriorityPacket(
6578 client_packet_number++, false,
6579 GetNthServerInitiatedUnidirectionalStreamId(0),
6580 GetNthClientInitiatedBidirectionalStreamId(0),
6581 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576582 }
6583
allada71b2efb2016-09-09 04:57:486584 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436585 mock_quic_data.AddRead(
6586 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336587 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436588 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486589 expected_raw_header_response_size =
6590 server_header_offset - expected_raw_header_response_size;
6591
Yixin Wangb470bc882018-02-15 18:43:576592 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436593 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486594
ckrasicbf2f59c2017-05-04 23:54:366595 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436596 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336597 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6598 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:416599 quic::QuicString header = ConstructDataHeader(20);
Zhongyi Shi32f2fd02018-04-16 18:23:436600 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336601 ASYNC, ConstructServerDataPacket(
6602 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416603 0, header + "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486604
Yixin Wangb470bc882018-02-15 18:43:576605 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436606 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:416607 quic::QuicString header2 = ConstructDataHeader(18);
ckrasicbf2f59c2017-05-04 23:54:366608 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336609 ASYNC, ConstructServerDataPacket(
6610 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416611 0, header2 + "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486612
Zhongyi Shi32f2fd02018-04-16 18:23:436613 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486614
6615 CreateSession();
6616
6617 TestDelegate delegate;
6618 QuicURLRequestContext quic_url_request_context(std::move(session_),
6619 &socket_factory_);
6620
6621 mock_quic_data.AddSocketDataToFactory(
6622 &quic_url_request_context.socket_factory());
6623 TestNetworkDelegate network_delegate;
6624 quic_url_request_context.set_network_delegate(&network_delegate);
6625
6626 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296627 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6628 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486629 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6630 &ssl_data_);
6631
6632 request->Start();
Wez2a31b222018-06-07 22:07:156633 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486634
6635 EXPECT_LT(0, request->GetTotalSentBytes());
6636 EXPECT_LT(0, request->GetTotalReceivedBytes());
6637 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6638 request->GetTotalSentBytes());
6639 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6640 request->GetTotalReceivedBytes());
6641 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6642 request->raw_header_size());
Wez0e717112018-06-18 23:09:226643
6644 // Pump the message loop to allow all data to be consumed.
6645 base::RunLoop().RunUntilIdle();
6646
allada71b2efb2016-09-09 04:57:486647 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6648 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6649}
6650
Yixin Wang10f477ed2017-11-21 04:20:206651TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6652 session_params_.quic_host_whitelist.insert("mail.example.org");
6653
6654 MockRead http_reads[] = {
6655 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6656 MockRead("hello world"),
6657 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6658 MockRead(ASYNC, OK)};
6659
Ryan Sleevib8d7ea02018-05-07 20:01:016660 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206661 socket_factory_.AddSocketDataProvider(&http_data);
6662 AddCertificate(&ssl_data_);
6663 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6664
6665 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526666 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206667 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436668 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6669 mock_quic_data.AddWrite(
6670 SYNCHRONOUS,
6671 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336672 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436673 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436674 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336675 ASYNC, ConstructServerResponseHeadersPacket(
6676 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6677 GetResponseHeaders("200 OK")));
Renjief49758b2019-01-11 23:32:416678 quic::QuicString header = ConstructDataHeader(6);
Fan Yang32c5a112018-12-10 20:06:336679 mock_quic_data.AddRead(
6680 ASYNC, ConstructServerDataPacket(
6681 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:416682 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436683 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206684 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6685 mock_quic_data.AddRead(ASYNC, 0); // EOF
6686
6687 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6688
6689 AddHangingNonAlternateProtocolSocketData();
6690 CreateSession();
6691
6692 SendRequestAndExpectHttpResponse("hello world");
6693 SendRequestAndExpectQuicResponse("hello!");
6694}
6695
6696TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6697 session_params_.quic_host_whitelist.insert("mail.example.com");
6698
6699 MockRead http_reads[] = {
6700 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6701 MockRead("hello world"),
6702 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6703 MockRead(ASYNC, OK)};
6704
Ryan Sleevib8d7ea02018-05-07 20:01:016705 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206706 socket_factory_.AddSocketDataProvider(&http_data);
6707 AddCertificate(&ssl_data_);
6708 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6709 socket_factory_.AddSocketDataProvider(&http_data);
6710 AddCertificate(&ssl_data_);
6711 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6712
6713 AddHangingNonAlternateProtocolSocketData();
6714 CreateSession();
6715
6716 SendRequestAndExpectHttpResponse("hello world");
6717 SendRequestAndExpectHttpResponse("hello world");
6718}
6719
bnc359ed2a2016-04-29 20:43:456720class QuicNetworkTransactionWithDestinationTest
6721 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016722 public ::testing::WithParamInterface<PoolingTestParams>,
6723 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456724 protected:
6725 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556726 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056727 client_headers_include_h2_stream_dependency_(
6728 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526729 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456730 destination_type_(GetParam().destination_type),
6731 cert_transparency_verifier_(new MultiLogCTVerifier()),
6732 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596733 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456734 auth_handler_factory_(
6735 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6736 random_generator_(0),
6737 ssl_data_(ASYNC, OK) {}
6738
6739 void SetUp() override {
6740 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556741 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456742
mmenke6ddfbea2017-05-31 21:48:416743 HttpNetworkSession::Params session_params;
6744 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346745 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446746 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056747 session_params.quic_headers_include_h2_stream_dependency =
6748 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416749
6750 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456751
Ryan Hamilton8d9ee76e2018-05-29 23:52:526752 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416753 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456754
6755 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276756 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416757 session_context.quic_crypto_client_stream_factory =
6758 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456759
mmenke6ddfbea2017-05-31 21:48:416760 session_context.quic_random = &random_generator_;
6761 session_context.client_socket_factory = &socket_factory_;
6762 session_context.host_resolver = &host_resolver_;
6763 session_context.cert_verifier = &cert_verifier_;
6764 session_context.transport_security_state = &transport_security_state_;
6765 session_context.cert_transparency_verifier =
6766 cert_transparency_verifier_.get();
6767 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6768 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456769 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416770 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596771 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416772 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6773 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456774
mmenke6ddfbea2017-05-31 21:48:416775 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456776 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456777 }
6778
6779 void TearDown() override {
6780 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6781 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556782 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456783 PlatformTest::TearDown();
6784 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556785 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406786 session_.reset();
bnc359ed2a2016-04-29 20:43:456787 }
6788
zhongyie537a002017-06-27 16:48:216789 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456790 HostPortPair destination;
6791 switch (destination_type_) {
6792 case SAME_AS_FIRST:
6793 destination = HostPortPair(origin1_, 443);
6794 break;
6795 case SAME_AS_SECOND:
6796 destination = HostPortPair(origin2_, 443);
6797 break;
6798 case DIFFERENT:
6799 destination = HostPortPair(kDifferentHostname, 443);
6800 break;
6801 }
bnc3472afd2016-11-17 15:27:216802 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456803 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216804 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456805 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446806 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456807 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526808 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236809 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526810 quic::QuicStreamId stream_id,
6811 bool should_include_version,
6812 quic::QuicStreamOffset* offset,
6813 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486814 return ConstructClientRequestHeadersPacket(
6815 packet_number, stream_id, should_include_version, 0, offset, maker);
6816 }
bnc359ed2a2016-04-29 20:43:456817
Ryan Hamilton8d9ee76e2018-05-29 23:52:526818 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236819 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526820 quic::QuicStreamId stream_id,
6821 bool should_include_version,
6822 quic::QuicStreamId parent_stream_id,
6823 quic::QuicStreamOffset* offset,
6824 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136825 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456826 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136827 spdy::SpdyHeaderBlock headers(
6828 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456829 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6830 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486831 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456832 }
6833
Ryan Hamilton8d9ee76e2018-05-29 23:52:526834 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236835 ConstructClientRequestHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526836 quic::QuicStreamId stream_id,
6837 bool should_include_version,
6838 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586839 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456840 packet_number, stream_id, should_include_version, nullptr, maker);
6841 }
6842
Ryan Hamilton8d9ee76e2018-05-29 23:52:526843 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236844 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526845 quic::QuicStreamId stream_id,
6846 quic::QuicStreamOffset* offset,
6847 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136848 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456849 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266850 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456851 }
6852
Ryan Hamilton8d9ee76e2018-05-29 23:52:526853 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:236854 ConstructServerResponseHeadersPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526855 quic::QuicStreamId stream_id,
6856 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586857 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6858 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456859 }
6860
Ryan Hamilton8d9ee76e2018-05-29 23:52:526861 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
Fan Yangac867502019-01-28 21:10:236862 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526863 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456864 QuicTestPacketMaker* maker) {
Renjief49758b2019-01-11 23:32:416865 quic::QuicString header = "";
6866 if (version_ == quic::QUIC_VERSION_99) {
6867 quic::HttpEncoder encoder;
6868 std::unique_ptr<char[]> buffer;
6869 auto header_length = encoder.SerializeDataFrameHeader(5, &buffer);
6870 header = quic::QuicString(buffer.get(), header_length);
6871 }
bnc359ed2a2016-04-29 20:43:456872 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
Renjief49758b2019-01-11 23:32:416873 header + "hello");
bnc359ed2a2016-04-29 20:43:456874 }
6875
Ryan Hamilton8d9ee76e2018-05-29 23:52:526876 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
Fan Yangac867502019-01-28 21:10:236877 uint64_t packet_number,
6878 uint64_t largest_received,
6879 uint64_t smallest_received,
6880 uint64_t least_unacked,
bnc359ed2a2016-04-29 20:43:456881 QuicTestPacketMaker* maker) {
6882 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496883 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456884 }
6885
Ryan Hamilton8d9ee76e2018-05-29 23:52:526886 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:236887 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:526888 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376889 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366890 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376891 }
6892
bnc359ed2a2016-04-29 20:43:456893 void AddRefusedSocketData() {
6894 std::unique_ptr<StaticSocketDataProvider> refused_data(
6895 new StaticSocketDataProvider());
6896 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6897 refused_data->set_connect_data(refused_connect);
6898 socket_factory_.AddSocketDataProvider(refused_data.get());
6899 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6900 }
6901
6902 void AddHangingSocketData() {
6903 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6904 new StaticSocketDataProvider());
6905 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6906 hanging_data->set_connect_data(hanging_connect);
6907 socket_factory_.AddSocketDataProvider(hanging_data.get());
6908 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6909 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6910 }
6911
6912 bool AllDataConsumed() {
6913 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6914 if (!socket_data_ptr->AllReadDataConsumed() ||
6915 !socket_data_ptr->AllWriteDataConsumed()) {
6916 return false;
6917 }
6918 }
6919 return true;
6920 }
6921
6922 void SendRequestAndExpectQuicResponse(const std::string& host) {
6923 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6924 HttpRequestInfo request;
6925 std::string url("https://");
6926 url.append(host);
6927 request.url = GURL(url);
6928 request.load_flags = 0;
6929 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106930 request.traffic_annotation =
6931 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456932 TestCompletionCallback callback;
6933 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016934 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456935
6936 std::string response_data;
robpercival214763f2016-07-01 23:27:016937 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456938 EXPECT_EQ("hello", response_data);
6939
6940 const HttpResponseInfo* response = trans.GetResponseInfo();
6941 ASSERT_TRUE(response != nullptr);
6942 ASSERT_TRUE(response->headers.get() != nullptr);
6943 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6944 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526945 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446946 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456947 response->connection_info);
Tsuyoshi Horo01faed62019-02-20 22:11:376948 EXPECT_EQ(443, response->remote_endpoint.port());
bnc359ed2a2016-04-29 20:43:456949 }
6950
Fan Yang32c5a112018-12-10 20:06:336951 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
6952 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366953 }
6954
Ryan Hamilton8d9ee76e2018-05-29 23:52:526955 quic::MockClock clock_;
6956 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056957 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526958 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456959 DestinationType destination_type_;
6960 std::string origin1_;
6961 std::string origin2_;
6962 std::unique_ptr<HttpNetworkSession> session_;
6963 MockClientSocketFactory socket_factory_;
6964 MockHostResolver host_resolver_;
6965 MockCertVerifier cert_verifier_;
6966 TransportSecurityState transport_security_state_;
6967 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236968 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456969 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076970 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596971 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456972 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526973 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456974 HttpServerPropertiesImpl http_server_properties_;
6975 BoundTestNetLog net_log_;
6976 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6977 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6978 static_socket_data_provider_vector_;
6979 SSLSocketDataProvider ssl_data_;
6980};
6981
Victor Costane635086f2019-01-27 05:20:306982INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
6983 QuicNetworkTransactionWithDestinationTest,
6984 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:456985
6986// A single QUIC request fails because the certificate does not match the origin
6987// hostname, regardless of whether it matches the alternative service hostname.
6988TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6989 if (destination_type_ == DIFFERENT)
6990 return;
6991
6992 GURL url("https://mail.example.com/");
6993 origin1_ = url.host();
6994
6995 // Not used for requests, but this provides a test case where the certificate
6996 // is valid for the hostname of the alternative service.
6997 origin2_ = "mail.example.org";
6998
zhongyie537a002017-06-27 16:48:216999 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457000
7001 scoped_refptr<X509Certificate> cert(
7002 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247003 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7004 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457005
7006 ProofVerifyDetailsChromium verify_details;
7007 verify_details.cert_verify_result.verified_cert = cert;
7008 verify_details.cert_verify_result.is_issued_by_known_root = true;
7009 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7010
7011 MockQuicData mock_quic_data;
7012 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7013 mock_quic_data.AddRead(ASYNC, 0);
7014
7015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7016
7017 AddRefusedSocketData();
7018
7019 HttpRequestInfo request;
7020 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107021 request.traffic_annotation =
7022 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457023
7024 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7025 TestCompletionCallback callback;
7026 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017027 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457028
7029 EXPECT_TRUE(AllDataConsumed());
7030}
7031
7032// First request opens QUIC session to alternative service. Second request
7033// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527034// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457035TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7036 origin1_ = "mail.example.org";
7037 origin2_ = "news.example.org";
7038
zhongyie537a002017-06-27 16:48:217039 SetQuicAlternativeService(origin1_);
7040 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457041
7042 scoped_refptr<X509Certificate> cert(
7043 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247044 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7045 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7046 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457047
7048 ProofVerifyDetailsChromium verify_details;
7049 verify_details.cert_verify_result.verified_cert = cert;
7050 verify_details.cert_verify_result.is_issued_by_known_root = true;
7051 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7052
Yixin Wang079ad542018-01-11 04:06:057053 QuicTestPacketMaker client_maker(
David Schinazic8281052019-01-24 06:14:177054 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7055 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057056 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177057 QuicTestPacketMaker server_maker(
7058 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7059 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457060
Ryan Hamilton8d9ee76e2018-05-29 23:52:527061 quic::QuicStreamOffset request_header_offset(0);
7062 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457063
7064 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057065 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437066 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057067 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337068 mock_quic_data.AddWrite(
7069 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7070 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7071 &request_header_offset, &client_maker));
7072 mock_quic_data.AddRead(ASYNC,
7073 ConstructServerResponseHeadersPacket(
7074 1, GetNthClientInitiatedBidirectionalStreamId(0),
7075 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437076 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337077 ASYNC,
7078 ConstructServerDataPacket(
7079 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437080 mock_quic_data.AddWrite(SYNCHRONOUS,
7081 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457082
Yixin Wang079ad542018-01-11 04:06:057083 client_maker.set_hostname(origin2_);
7084 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457085
Zhongyi Shi32f2fd02018-04-16 18:23:437086 mock_quic_data.AddWrite(
7087 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337088 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7089 GetNthClientInitiatedBidirectionalStreamId(0),
7090 &request_header_offset, &client_maker));
7091 mock_quic_data.AddRead(ASYNC,
7092 ConstructServerResponseHeadersPacket(
7093 3, GetNthClientInitiatedBidirectionalStreamId(1),
7094 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437095 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337096 ASYNC,
7097 ConstructServerDataPacket(
7098 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437099 mock_quic_data.AddWrite(SYNCHRONOUS,
7100 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457101 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7102 mock_quic_data.AddRead(ASYNC, 0); // EOF
7103
7104 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7105
7106 AddHangingSocketData();
7107 AddHangingSocketData();
7108
Fan Yangc9e00dc2018-10-09 14:17:567109 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7110 QuicStreamFactoryPeer::SetAlarmFactory(
7111 session_->quic_stream_factory(),
7112 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7113 &clock_));
7114
bnc359ed2a2016-04-29 20:43:457115 SendRequestAndExpectQuicResponse(origin1_);
7116 SendRequestAndExpectQuicResponse(origin2_);
7117
7118 EXPECT_TRUE(AllDataConsumed());
7119}
7120
7121// First request opens QUIC session to alternative service. Second request does
7122// not pool to it, even though destination matches, because certificate is not
7123// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527124// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457125TEST_P(QuicNetworkTransactionWithDestinationTest,
7126 DoNotPoolIfCertificateInvalid) {
7127 origin1_ = "news.example.org";
7128 origin2_ = "mail.example.com";
7129
zhongyie537a002017-06-27 16:48:217130 SetQuicAlternativeService(origin1_);
7131 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457132
7133 scoped_refptr<X509Certificate> cert1(
7134 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247135 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7136 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7137 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457138
7139 scoped_refptr<X509Certificate> cert2(
7140 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247141 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7142 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457143
7144 ProofVerifyDetailsChromium verify_details1;
7145 verify_details1.cert_verify_result.verified_cert = cert1;
7146 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7147 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7148
7149 ProofVerifyDetailsChromium verify_details2;
7150 verify_details2.cert_verify_result.verified_cert = cert2;
7151 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7152 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7153
Yixin Wang079ad542018-01-11 04:06:057154 QuicTestPacketMaker client_maker1(
David Schinazic8281052019-01-24 06:14:177155 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7156 &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057157 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177158 QuicTestPacketMaker server_maker1(
7159 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7160 &clock_, origin1_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457161
7162 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527163 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457164 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437165 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7166 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337167 mock_quic_data1.AddWrite(
7168 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7169 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7170 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437171 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337172 ASYNC,
7173 ConstructServerResponseHeadersPacket(
7174 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437175 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337176 ASYNC,
7177 ConstructServerDataPacket(
7178 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437179 mock_quic_data1.AddWrite(
7180 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457181 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7182 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7183
7184 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7185
Yixin Wang079ad542018-01-11 04:06:057186 QuicTestPacketMaker client_maker2(
David Schinazic8281052019-01-24 06:14:177187 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7188 &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057189 client_headers_include_h2_stream_dependency_);
David Schinazic8281052019-01-24 06:14:177190 QuicTestPacketMaker server_maker2(
7191 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
7192 &clock_, origin2_, quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457193
7194 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527195 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457196 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437197 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7198 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337199 mock_quic_data2.AddWrite(
7200 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7201 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7202 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437203 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337204 ASYNC,
7205 ConstructServerResponseHeadersPacket(
7206 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437207 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337208 ASYNC,
7209 ConstructServerDataPacket(
7210 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437211 mock_quic_data2.AddWrite(
7212 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457213 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7214 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7215
7216 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7217
bnc359ed2a2016-04-29 20:43:457218 SendRequestAndExpectQuicResponse(origin1_);
7219 SendRequestAndExpectQuicResponse(origin2_);
7220
7221 EXPECT_TRUE(AllDataConsumed());
7222}
7223
ckrasicdee37572017-04-06 22:42:277224// crbug.com/705109 - this confirms that matching request with a body
7225// triggers a crash (pre-fix).
7226TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417227 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277228 HostPortPair::FromString("mail.example.org:443"));
7229
7230 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527231 quic::QuicStreamOffset header_stream_offset = 0;
Fan Yangac867502019-01-28 21:10:237232 uint64_t client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437233 mock_quic_data.AddWrite(
7234 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7235 &header_stream_offset));
7236 mock_quic_data.AddWrite(
7237 SYNCHRONOUS,
7238 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337239 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7240 true, true, GetRequestHeaders("GET", "https", "/"),
7241 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527242 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437243 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337244 ASYNC, ConstructServerPushPromisePacket(
7245 1, GetNthClientInitiatedBidirectionalStreamId(0),
7246 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7247 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7248 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577249 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267250 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337251 mock_quic_data.AddWrite(SYNCHRONOUS,
7252 ConstructClientPriorityPacket(
7253 client_packet_number++, false,
7254 GetNthServerInitiatedUnidirectionalStreamId(0),
7255 GetNthClientInitiatedBidirectionalStreamId(0),
7256 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577257 }
Zhongyi Shi32f2fd02018-04-16 18:23:437258 mock_quic_data.AddRead(
7259 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337260 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437261 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577262 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437263 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7264 mock_quic_data.AddRead(
7265 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337266 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7267 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417268 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437269 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337270 ASYNC, ConstructServerDataPacket(
7271 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417272 0, header + "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577273 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437274 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
Renjief49758b2019-01-11 23:32:417275
7276 quic::QuicString header2 = ConstructDataHeader(10);
Zhongyi Shi32f2fd02018-04-16 18:23:437277 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337278 ASYNC, ConstructServerDataPacket(
7279 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417280 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277281
7282 // Because the matching request has a body, we will see the push
7283 // stream get cancelled, and the matching request go out on the
7284 // wire.
Fan Yang32c5a112018-12-10 20:06:337285 mock_quic_data.AddWrite(SYNCHRONOUS,
7286 ConstructClientAckAndRstPacket(
7287 client_packet_number++,
7288 GetNthServerInitiatedUnidirectionalStreamId(0),
7289 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277290 const char kBody[] = "1";
Renjief49758b2019-01-11 23:32:417291 quic::QuicString header3 = ConstructDataHeader(1);
7292 if (version_ != quic::QUIC_VERSION_99) {
7293 mock_quic_data.AddWrite(
7294 SYNCHRONOUS,
7295 ConstructClientRequestHeadersAndDataFramesPacket(
7296 client_packet_number++,
7297 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7298 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7299 GetNthServerInitiatedUnidirectionalStreamId(0),
7300 &header_stream_offset, nullptr, {kBody}));
7301 } else {
7302 mock_quic_data.AddWrite(
7303 SYNCHRONOUS,
7304 ConstructClientRequestHeadersAndDataFramesPacket(
7305 client_packet_number++,
7306 GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7307 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7308 GetNthServerInitiatedUnidirectionalStreamId(0),
7309 &header_stream_offset, nullptr, {header3, kBody}));
7310 }
ckrasicdee37572017-04-06 22:42:277311
7312 // We see the same response as for the earlier pushed and cancelled
7313 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437314 mock_quic_data.AddRead(
7315 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337316 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437317 GetResponseHeaders("200 OK"), &server_header_offset));
7318 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337319 ASYNC, ConstructServerDataPacket(
7320 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Renjief49758b2019-01-11 23:32:417321 0, header2 + "and hello!"));
ckrasicdee37572017-04-06 22:42:277322
Yixin Wangb470bc882018-02-15 18:43:577323 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437324 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277325 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7326 mock_quic_data.AddRead(ASYNC, 0); // EOF
7327 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7328
7329 // The non-alternate protocol job needs to hang in order to guarantee that
7330 // the alternate-protocol job will "win".
7331 AddHangingNonAlternateProtocolSocketData();
7332
7333 CreateSession();
7334
7335 // PUSH_PROMISE handling in the http layer gets exercised here.
7336 SendRequestAndExpectQuicResponse("hello!");
7337
7338 request_.url = GURL("https://mail.example.org/pushed.jpg");
7339 ChunkedUploadDataStream upload_data(0);
7340 upload_data.AppendData("1", 1, true);
7341 request_.upload_data_stream = &upload_data;
7342 SendRequestAndExpectQuicResponse("and hello!");
7343}
7344
Bence Béky7538a952018-02-01 16:59:527345// Regression test for https://crbug.com/797825: If pushed headers describe a
7346// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7347// not be called (otherwise a DCHECK fails).
7348TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137349 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527350 pushed_request_headers[":authority"] = "";
7351 pushed_request_headers[":method"] = "GET";
7352 pushed_request_headers[":path"] = "/";
7353 pushed_request_headers[":scheme"] = "nosuchscheme";
7354
7355 session_params_.origins_to_force_quic_on.insert(
7356 HostPortPair::FromString("mail.example.org:443"));
7357
7358 MockQuicData mock_quic_data;
7359
Ryan Hamilton8d9ee76e2018-05-29 23:52:527360 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527361 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437362 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7363 mock_quic_data.AddWrite(
7364 SYNCHRONOUS,
7365 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337366 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437367 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527368
Ryan Hamilton8d9ee76e2018-05-29 23:52:527369 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337370 mock_quic_data.AddRead(
7371 ASYNC, ConstructServerPushPromisePacket(
7372 1, GetNthClientInitiatedBidirectionalStreamId(0),
7373 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7374 std::move(pushed_request_headers), &server_header_offset,
7375 &server_maker_));
7376 mock_quic_data.AddWrite(SYNCHRONOUS,
7377 ConstructClientRstPacket(
7378 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7379 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527380
Zhongyi Shi32f2fd02018-04-16 18:23:437381 mock_quic_data.AddRead(
7382 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337383 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437384 GetResponseHeaders("200 OK"), &server_header_offset));
7385 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527386
Zhongyi Shi32f2fd02018-04-16 18:23:437387 mock_quic_data.AddRead(
7388 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337389 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7390 false, GetResponseHeaders("200 OK"), &server_header_offset));
Renjief49758b2019-01-11 23:32:417391 quic::QuicString header = ConstructDataHeader(6);
Zhongyi Shi32f2fd02018-04-16 18:23:437392 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337393 ASYNC, ConstructServerDataPacket(
7394 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
Renjief49758b2019-01-11 23:32:417395 0, header + "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437396 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527397
7398 mock_quic_data.AddRead(ASYNC, 0);
7399 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7400
7401 // The non-alternate protocol job needs to hang in order to guarantee that
7402 // the alternate-protocol job will "win".
7403 AddHangingNonAlternateProtocolSocketData();
7404
7405 CreateSession();
7406
7407 // PUSH_PROMISE handling in the http layer gets exercised here.
7408 SendRequestAndExpectQuicResponse("hello!");
7409
7410 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7411 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7412}
7413
Yixin Wang46a273ec302018-01-23 17:59:567414// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147415TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
Yixin Wang46a273ec302018-01-23 17:59:567416 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147417 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567418 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497419 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567420
7421 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527422 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567423 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357424 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337425 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357426 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7427 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7428 false, ConnectRequestHeaders("mail.example.org:443"),
7429 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337430 mock_quic_data.AddRead(
7431 ASYNC, ConstructServerResponseHeadersPacket(
7432 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7433 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567434
7435 const char get_request[] =
7436 "GET / HTTP/1.1\r\n"
7437 "Host: mail.example.org\r\n"
7438 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417439 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7440 if (version_ != quic::QUIC_VERSION_99) {
7441 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357442 SYNCHRONOUS,
7443 ConstructClientAckAndDataPacket(
7444 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7445 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417446 } else {
7447 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417448 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357449 ConstructClientAckAndMultipleDataFramesPacket(
7450 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7451 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417452 }
7453
Yixin Wang46a273ec302018-01-23 17:59:567454 const char get_response[] =
7455 "HTTP/1.1 200 OK\r\n"
7456 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417457 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:437458 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337459 ASYNC, ConstructServerDataPacket(
7460 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417461 0, header2 + quic::QuicString(get_response)));
7462 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337463 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417464 SYNCHRONOUS, ConstructServerDataPacket(
7465 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7466 false, strlen(get_response) + header2.length(),
7467 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357468 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567469 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7470
7471 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417472 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357473 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7474 quic::QUIC_STREAM_CANCELLED,
7475 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567476
7477 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7478
7479 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7480
7481 CreateSession();
7482
7483 request_.url = GURL("https://mail.example.org/");
Brad Lasseye62461e2018-12-13 04:21:097484 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
Yixin Wang46a273ec302018-01-23 17:59:567485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7486 HeadersHandler headers_handler;
7487 trans.SetBeforeHeadersSentCallback(
7488 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7489 base::Unretained(&headers_handler)));
7490 RunTransaction(&trans);
7491 CheckWasHttpResponse(&trans);
7492 CheckResponsePort(&trans, 70);
7493 CheckResponseData(&trans, "0123456789");
7494 EXPECT_TRUE(headers_handler.was_proxied());
7495 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7496
7497 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7498 // proxy socket to disconnect.
7499 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7500
7501 base::RunLoop().RunUntilIdle();
7502 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7503 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7504}
7505
7506// Performs an HTTP/2 request over QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:147507TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
Yixin Wang46a273ec302018-01-23 17:59:567508 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147509 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567510 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497511 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567512
7513 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527514 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567515 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357516 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337517 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357518 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7519 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7520 false, ConnectRequestHeaders("mail.example.org:443"),
7521 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337522 mock_quic_data.AddRead(
7523 ASYNC, ConstructServerResponseHeadersPacket(
7524 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7525 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567526
7527 SpdyTestUtil spdy_util;
7528
Ryan Hamilton0239aac2018-05-19 00:03:137529 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567530 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417531 quic::QuicString header = ConstructDataHeader(get_frame.size());
7532 if (version_ != quic::QUIC_VERSION_99) {
7533 mock_quic_data.AddWrite(
7534 SYNCHRONOUS,
7535 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357536 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7537 false, 0,
Renjief49758b2019-01-11 23:32:417538 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7539 } else {
7540 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417541 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357542 ConstructClientAckAndMultipleDataFramesPacket(
7543 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7544 false, 0,
7545 {header, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417546 }
Ryan Hamilton0239aac2018-05-19 00:03:137547 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567548 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417549 quic::QuicString header2 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437550 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337551 ASYNC,
7552 ConstructServerDataPacket(
7553 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
Renjief49758b2019-01-11 23:32:417554 header2 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567555
Ryan Hamilton0239aac2018-05-19 00:03:137556 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197557 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Renjief49758b2019-01-11 23:32:417558 quic::QuicString header3 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437559 mock_quic_data.AddRead(
7560 SYNCHRONOUS,
7561 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337562 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417563 resp_frame.size() + header2.length(),
7564 header3 + quic::QuicString(data_frame.data(), data_frame.size())));
Renjied172e812019-01-16 05:12:357565 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567566 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7567
7568 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437569 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357570 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
7571 quic::QUIC_STREAM_CANCELLED,
7572 get_frame.size() + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567573
7574 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7575
7576 SSLSocketDataProvider ssl_data(ASYNC, OK);
7577 ssl_data.next_proto = kProtoHTTP2;
7578 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7579
7580 CreateSession();
7581
7582 request_.url = GURL("https://mail.example.org/");
7583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7584 HeadersHandler headers_handler;
7585 trans.SetBeforeHeadersSentCallback(
7586 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7587 base::Unretained(&headers_handler)));
7588 RunTransaction(&trans);
7589 CheckWasSpdyResponse(&trans);
7590 CheckResponsePort(&trans, 70);
7591 CheckResponseData(&trans, "0123456789");
7592 EXPECT_TRUE(headers_handler.was_proxied());
7593 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7594
Wez0e717112018-06-18 23:09:227595 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7596 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567597 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7598
7599 base::RunLoop().RunUntilIdle();
7600 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7601 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7602}
7603
7604// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7605// check that the proxy socket is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147606TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
Yixin Wang46a273ec302018-01-23 17:59:567607 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147608 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567609 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497610 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567611
7612 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527613 quic::QuicStreamOffset header_stream_offset = 0;
Renjief49758b2019-01-11 23:32:417614 int write_packet_index = 1;
Yixin Wang46a273ec302018-01-23 17:59:567615 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417616 SYNCHRONOUS, ConstructInitialSettingsPacket(write_packet_index++,
7617 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337618 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417619 SYNCHRONOUS,
7620 ConstructClientRequestHeadersPacket(
7621 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7622 true, false, ConnectRequestHeaders("mail.example.org:443"),
7623 &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337624 mock_quic_data.AddRead(
7625 ASYNC, ConstructServerResponseHeadersPacket(
7626 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7627 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567628
Ryan Hamilton8d9ee76e2018-05-29 23:52:527629 quic::QuicStreamOffset client_data_offset = 0;
7630 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567631 const char get_request_1[] =
7632 "GET / HTTP/1.1\r\n"
7633 "Host: mail.example.org\r\n"
7634 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417635 quic::QuicString header = ConstructDataHeader(strlen(get_request_1));
7636 if (version_ != quic::QUIC_VERSION_99) {
7637 mock_quic_data.AddWrite(
7638 SYNCHRONOUS,
7639 ConstructClientAckAndDataPacket(
7640 write_packet_index++, false,
7641 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7642 client_data_offset, quic::QuicStringPiece(get_request_1)));
7643 } else {
7644 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417645 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357646 ConstructClientAckAndMultipleDataFramesPacket(
7647 write_packet_index++, false,
7648 GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1, false,
7649 client_data_offset, {header, quic::QuicString(get_request_1)}));
Renjief49758b2019-01-11 23:32:417650 }
7651
7652 client_data_offset += strlen(get_request_1) + header.length();
Yixin Wang46a273ec302018-01-23 17:59:567653
7654 const char get_response_1[] =
7655 "HTTP/1.1 200 OK\r\n"
7656 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417657 quic::QuicString header2 = ConstructDataHeader(strlen(get_response_1));
Zhongyi Shi32f2fd02018-04-16 18:23:437658 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417659 ASYNC,
7660 ConstructServerDataPacket(
7661 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7662 server_data_offset, header2 + quic::QuicString(get_response_1)));
7663 server_data_offset += strlen(get_response_1) + header2.length();
Yixin Wang46a273ec302018-01-23 17:59:567664
Renjief49758b2019-01-11 23:32:417665 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337666 mock_quic_data.AddRead(
7667 SYNCHRONOUS,
7668 ConstructServerDataPacket(
7669 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417670 server_data_offset, header3 + quic::QuicString("0123456789")));
7671 server_data_offset += 10 + header3.length();
Yixin Wang46a273ec302018-01-23 17:59:567672
Renjief49758b2019-01-11 23:32:417673 mock_quic_data.AddWrite(
7674 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567675
7676 const char get_request_2[] =
7677 "GET /2 HTTP/1.1\r\n"
7678 "Host: mail.example.org\r\n"
7679 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417680 quic::QuicString header4 = ConstructDataHeader(strlen(get_request_2));
7681 if (version_ == quic::QUIC_VERSION_99) {
7682 mock_quic_data.AddWrite(
7683 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357684 ConstructClientMultipleDataFramesPacket(
7685 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7686 false, false, client_data_offset,
7687 {header4, quic::QuicString(get_request_2)}));
7688 client_data_offset += header4.length() + strlen(get_request_2);
7689 } else {
7690 mock_quic_data.AddWrite(
7691 SYNCHRONOUS,
Renjief49758b2019-01-11 23:32:417692 ConstructClientDataPacket(write_packet_index++,
7693 GetNthClientInitiatedBidirectionalStreamId(0),
Renjied172e812019-01-16 05:12:357694 false, false, client_data_offset,
7695 quic::QuicStringPiece(get_request_2)));
7696 client_data_offset += strlen(get_request_2);
Renjief49758b2019-01-11 23:32:417697 }
Yixin Wang46a273ec302018-01-23 17:59:567698
7699 const char get_response_2[] =
7700 "HTTP/1.1 200 OK\r\n"
7701 "Content-Length: 7\r\n\r\n";
Renjief49758b2019-01-11 23:32:417702 quic::QuicString header5 = ConstructDataHeader(strlen(get_response_2));
Zhongyi Shi32f2fd02018-04-16 18:23:437703 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417704 ASYNC,
7705 ConstructServerDataPacket(
7706 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7707 server_data_offset, header5 + quic::QuicString(get_response_2)));
7708 server_data_offset += strlen(get_response_2) + header5.length();
Yixin Wang46a273ec302018-01-23 17:59:567709
Renjief49758b2019-01-11 23:32:417710 quic::QuicString header6 = ConstructDataHeader(7);
Ryan Hamilton8d9ee76e2018-05-29 23:52:527711 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337712 SYNCHRONOUS,
7713 ConstructServerDataPacket(
7714 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417715 server_data_offset, header6 + quic::QuicString("0123456")));
7716 server_data_offset += 7 + header6.length();
Yixin Wang46a273ec302018-01-23 17:59:567717
Renjief49758b2019-01-11 23:32:417718 mock_quic_data.AddWrite(
7719 SYNCHRONOUS, ConstructClientAckPacket(write_packet_index++, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567720 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7721
Renjief49758b2019-01-11 23:32:417722 mock_quic_data.AddWrite(
7723 SYNCHRONOUS,
7724 ConstructClientRstPacket(
7725 write_packet_index++, GetNthClientInitiatedBidirectionalStreamId(0),
7726 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567727
7728 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7729
7730 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7731
7732 CreateSession();
7733
7734 request_.url = GURL("https://mail.example.org/");
7735 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7736 HeadersHandler headers_handler_1;
7737 trans_1.SetBeforeHeadersSentCallback(
7738 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7739 base::Unretained(&headers_handler_1)));
7740 RunTransaction(&trans_1);
7741 CheckWasHttpResponse(&trans_1);
7742 CheckResponsePort(&trans_1, 70);
7743 CheckResponseData(&trans_1, "0123456789");
7744 EXPECT_TRUE(headers_handler_1.was_proxied());
7745 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7746
7747 request_.url = GURL("https://mail.example.org/2");
7748 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7749 HeadersHandler headers_handler_2;
7750 trans_2.SetBeforeHeadersSentCallback(
7751 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7752 base::Unretained(&headers_handler_2)));
7753 RunTransaction(&trans_2);
7754 CheckWasHttpResponse(&trans_2);
7755 CheckResponsePort(&trans_2, 70);
7756 CheckResponseData(&trans_2, "0123456");
7757 EXPECT_TRUE(headers_handler_2.was_proxied());
7758 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7759
7760 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7761 // proxy socket to disconnect.
7762 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7763
7764 base::RunLoop().RunUntilIdle();
7765 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7766 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7767}
7768
7769// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7770// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7771// server is reused for the second request.
Ryan Hamilton4cbcbf12018-12-15 05:16:147772TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
Yixin Wang46a273ec302018-01-23 17:59:567773 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147774 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567775 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497776 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567777
7778 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527779 quic::QuicStreamOffset client_header_stream_offset = 0;
7780 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:357781 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7782 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567783
7784 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337785 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357786 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7787 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7788 false, ConnectRequestHeaders("mail.example.org:443"),
7789 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437790 mock_quic_data.AddRead(
7791 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337792 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437793 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567794
7795 // GET request, response, and data over QUIC tunnel for first request
7796 const char get_request[] =
7797 "GET / HTTP/1.1\r\n"
7798 "Host: mail.example.org\r\n"
7799 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:417800 quic::QuicString header = ConstructDataHeader(strlen(get_request));
7801 if (version_ != quic::QUIC_VERSION_99) {
7802 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:357803 SYNCHRONOUS,
7804 ConstructClientAckAndDataPacket(
7805 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7806 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:417807 } else {
7808 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417809 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357810 ConstructClientAckAndMultipleDataFramesPacket(
7811 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7812 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:417813 }
7814
Yixin Wang46a273ec302018-01-23 17:59:567815 const char get_response[] =
7816 "HTTP/1.1 200 OK\r\n"
7817 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:417818 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Yixin Wang46a273ec302018-01-23 17:59:567819 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337820 ASYNC, ConstructServerDataPacket(
7821 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Renjief49758b2019-01-11 23:32:417822 0, header2 + quic::QuicString(get_response)));
7823 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:337824 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417825 SYNCHRONOUS, ConstructServerDataPacket(
7826 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
7827 false, strlen(get_response) + header2.length(),
7828 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:357829 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567830
7831 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437832 mock_quic_data.AddWrite(
7833 SYNCHRONOUS,
7834 ConstructClientRequestHeadersPacket(
Renjied172e812019-01-16 05:12:357835 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7836 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:337837 GetNthClientInitiatedBidirectionalStreamId(0),
7838 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437839 mock_quic_data.AddRead(
7840 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337841 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437842 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567843
7844 // GET request, response, and data over QUIC tunnel for second request
7845 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137846 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567847 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Renjief49758b2019-01-11 23:32:417848 quic::QuicString header4 = ConstructDataHeader(get_frame.size());
7849 if (version_ != quic::QUIC_VERSION_99) {
7850 mock_quic_data.AddWrite(
7851 SYNCHRONOUS,
7852 ConstructClientAckAndDataPacket(
Renjied172e812019-01-16 05:12:357853 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7854 false, 0,
Renjief49758b2019-01-11 23:32:417855 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
7856 } else {
7857 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417858 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357859 ConstructClientAckAndMultipleDataFramesPacket(
7860 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7861 false, 0,
7862 {header4, quic::QuicString(get_frame.data(), get_frame.size())}));
Renjief49758b2019-01-11 23:32:417863 }
Yixin Wang46a273ec302018-01-23 17:59:567864
Ryan Hamilton0239aac2018-05-19 00:03:137865 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567866 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Renjief49758b2019-01-11 23:32:417867 quic::QuicString header5 = ConstructDataHeader(resp_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437868 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337869 ASYNC,
7870 ConstructServerDataPacket(
7871 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
Renjief49758b2019-01-11 23:32:417872 header5 + quic::QuicString(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567873
Ryan Hamilton0239aac2018-05-19 00:03:137874 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197875 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Renjief49758b2019-01-11 23:32:417876 quic::QuicString header6 = ConstructDataHeader(data_frame.size());
Zhongyi Shi32f2fd02018-04-16 18:23:437877 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:417878 ASYNC,
7879 ConstructServerDataPacket(
7880 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7881 resp_frame.size() + header5.length(),
7882 header6 + quic::QuicString(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567883
Renjied172e812019-01-16 05:12:357884 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567885 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7886
7887 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:417888 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357889 ConstructClientRstPacket(8, GetNthClientInitiatedBidirectionalStreamId(0),
7890 quic::QUIC_STREAM_CANCELLED,
7891 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:567892 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437893 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:357894 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
7895 quic::QUIC_STREAM_CANCELLED,
7896 get_frame.size() + header4.length()));
Yixin Wang46a273ec302018-01-23 17:59:567897
7898 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7899
7900 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7901
7902 SSLSocketDataProvider ssl_data(ASYNC, OK);
7903 ssl_data.next_proto = kProtoHTTP2;
7904 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7905
7906 CreateSession();
7907
7908 request_.url = GURL("https://mail.example.org/");
7909 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7910 HeadersHandler headers_handler_1;
7911 trans_1.SetBeforeHeadersSentCallback(
7912 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7913 base::Unretained(&headers_handler_1)));
7914 RunTransaction(&trans_1);
7915 CheckWasHttpResponse(&trans_1);
7916 CheckResponsePort(&trans_1, 70);
7917 CheckResponseData(&trans_1, "0123456789");
7918 EXPECT_TRUE(headers_handler_1.was_proxied());
7919 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7920
7921 request_.url = GURL("https://different.example.org/");
7922 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7923 HeadersHandler headers_handler_2;
7924 trans_2.SetBeforeHeadersSentCallback(
7925 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7926 base::Unretained(&headers_handler_2)));
7927 RunTransaction(&trans_2);
7928 CheckWasSpdyResponse(&trans_2);
7929 CheckResponsePort(&trans_2, 70);
7930 CheckResponseData(&trans_2, "0123456");
7931 EXPECT_TRUE(headers_handler_2.was_proxied());
7932 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7933
7934 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7935 // proxy socket to disconnect.
7936 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7937
7938 base::RunLoop().RunUntilIdle();
7939 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7940 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7941}
7942
7943// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
Ryan Hamilton4cbcbf12018-12-15 05:16:147944TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
Yixin Wang46a273ec302018-01-23 17:59:567945 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147946 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567947 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497948 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567949
7950 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527951 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567952 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437953 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527954 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337955 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7956 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7957 false, ConnectRequestHeaders("mail.example.org:443"),
7958 &header_stream_offset));
7959 mock_quic_data.AddRead(
7960 ASYNC, ConstructServerResponseHeadersPacket(
7961 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7962 GetResponseHeaders("500")));
7963 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7964 mock_quic_data.AddWrite(SYNCHRONOUS,
7965 ConstructClientAckAndRstPacket(
7966 3, GetNthClientInitiatedBidirectionalStreamId(0),
7967 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567968
7969 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7970
7971 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7972
7973 CreateSession();
7974
7975 request_.url = GURL("https://mail.example.org/");
7976 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7977 HeadersHandler headers_handler;
7978 trans.SetBeforeHeadersSentCallback(
7979 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7980 base::Unretained(&headers_handler)));
7981 TestCompletionCallback callback;
7982 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7983 EXPECT_EQ(ERR_IO_PENDING, rv);
7984 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7985 EXPECT_EQ(false, headers_handler.was_proxied());
7986
7987 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7988 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7989}
7990
7991// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
Ryan Hamilton4cbcbf12018-12-15 05:16:147992TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
Yixin Wang46a273ec302018-01-23 17:59:567993 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:147994 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:567995 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497996 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567997
7998 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527999 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568000 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438001 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338002 mock_quic_data.AddWrite(
8003 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8004 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8005 false, ConnectRequestHeaders("mail.example.org:443"),
8006 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568007 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8008
8009 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8010
8011 CreateSession();
8012
8013 request_.url = GURL("https://mail.example.org/");
8014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8015 HeadersHandler headers_handler;
8016 trans.SetBeforeHeadersSentCallback(
8017 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8018 base::Unretained(&headers_handler)));
8019 TestCompletionCallback callback;
8020 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8021 EXPECT_EQ(ERR_IO_PENDING, rv);
8022 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8023
8024 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8025 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8026}
8027
8028// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
8029// host. Retries request and succeeds.
Ryan Hamilton4cbcbf12018-12-15 05:16:148030TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
Yixin Wang46a273ec302018-01-23 17:59:568031 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148032 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568033 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498034 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568035
8036 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528037 quic::QuicStreamOffset client_header_stream_offset = 0;
8038 quic::QuicStreamOffset server_header_stream_offset = 0;
Renjied172e812019-01-16 05:12:358039 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
8040 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338041 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358042 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8043 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8044 false, ConnectRequestHeaders("mail.example.org:443"),
8045 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438046 mock_quic_data.AddRead(
8047 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338048 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438049 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Renjied172e812019-01-16 05:12:358050 mock_quic_data.AddWrite(SYNCHRONOUS,
8051 ConstructClientAckAndRstPacket(
8052 3, GetNthClientInitiatedBidirectionalStreamId(0),
8053 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568054
Zhongyi Shi32f2fd02018-04-16 18:23:438055 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358056 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8057 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8058 false, ConnectRequestHeaders("mail.example.org:443"),
8059 GetNthClientInitiatedBidirectionalStreamId(0),
8060 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438061 mock_quic_data.AddRead(
8062 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338063 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438064 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568065
8066 const char get_request[] =
8067 "GET / HTTP/1.1\r\n"
8068 "Host: mail.example.org\r\n"
8069 "Connection: keep-alive\r\n\r\n";
Renjief49758b2019-01-11 23:32:418070 quic::QuicString header = ConstructDataHeader(strlen(get_request));
8071 if (version_ != quic::QUIC_VERSION_99) {
8072 mock_quic_data.AddWrite(
Renjied172e812019-01-16 05:12:358073 SYNCHRONOUS,
8074 ConstructClientAckAndDataPacket(
8075 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8076 false, 0, quic::QuicStringPiece(get_request)));
Renjief49758b2019-01-11 23:32:418077 } else {
8078 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418079 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358080 ConstructClientAckAndMultipleDataFramesPacket(
8081 5, false, GetNthClientInitiatedBidirectionalStreamId(1), 2, 2, 1,
8082 false, 0, {header, quic::QuicString(get_request)}));
Renjief49758b2019-01-11 23:32:418083 }
Yixin Wang46a273ec302018-01-23 17:59:568084 const char get_response[] =
8085 "HTTP/1.1 200 OK\r\n"
8086 "Content-Length: 10\r\n\r\n";
Renjief49758b2019-01-11 23:32:418087 quic::QuicString header2 = ConstructDataHeader(strlen(get_response));
Zhongyi Shi32f2fd02018-04-16 18:23:438088 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338089 ASYNC, ConstructServerDataPacket(
8090 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Renjief49758b2019-01-11 23:32:418091 0, header2 + quic::QuicString(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528092
Renjief49758b2019-01-11 23:32:418093 quic::QuicString header3 = ConstructDataHeader(10);
Fan Yang32c5a112018-12-10 20:06:338094 mock_quic_data.AddRead(
Renjief49758b2019-01-11 23:32:418095 SYNCHRONOUS, ConstructServerDataPacket(
8096 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8097 false, strlen(get_response) + header2.length(),
8098 header3 + quic::QuicString("0123456789")));
Renjied172e812019-01-16 05:12:358099 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568100 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8101
8102 mock_quic_data.AddWrite(
Renjief49758b2019-01-11 23:32:418103 SYNCHRONOUS,
Renjied172e812019-01-16 05:12:358104 ConstructClientRstPacket(7, GetNthClientInitiatedBidirectionalStreamId(1),
8105 quic::QUIC_STREAM_CANCELLED,
8106 strlen(get_request) + header.length()));
Yixin Wang46a273ec302018-01-23 17:59:568107
8108 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8109
8110 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8111 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8112
8113 SSLSocketDataProvider ssl_data(ASYNC, OK);
8114 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8115
8116 CreateSession();
8117
8118 request_.url = GURL("https://mail.example.org/");
8119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8120 HeadersHandler headers_handler;
8121 trans.SetBeforeHeadersSentCallback(
8122 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8123 base::Unretained(&headers_handler)));
8124 TestCompletionCallback callback;
8125 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8126 EXPECT_EQ(ERR_IO_PENDING, rv);
8127 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8128
8129 rv = trans.RestartIgnoringLastError(callback.callback());
8130 EXPECT_EQ(ERR_IO_PENDING, rv);
8131 EXPECT_EQ(OK, callback.WaitForResult());
8132
8133 CheckWasHttpResponse(&trans);
8134 CheckResponsePort(&trans, 70);
8135 CheckResponseData(&trans, "0123456789");
8136 EXPECT_EQ(true, headers_handler.was_proxied());
8137 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8138
8139 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8140 // proxy socket to disconnect.
8141 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8142
8143 base::RunLoop().RunUntilIdle();
8144 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8145 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8146}
8147
8148// Checks if a request's specified "user-agent" header shows up correctly in the
8149// CONNECT request to a QUIC proxy.
Ryan Hamilton4cbcbf12018-12-15 05:16:148150TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
Yixin Wang46a273ec302018-01-23 17:59:568151 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148152 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568153 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498154 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568155
8156 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528157 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568158 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438159 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568160
Ryan Hamilton0239aac2018-05-19 00:03:138161 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568162 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338163 mock_quic_data.AddWrite(
8164 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8165 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8166 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568167 // Return an error, so the transaction stops here (this test isn't interested
8168 // in the rest).
8169 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8170
8171 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8172
8173 CreateSession();
8174
8175 request_.url = GURL("https://mail.example.org/");
8176 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8177 "Chromium Ultra Awesome X Edition");
8178 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8179 HeadersHandler headers_handler;
8180 trans.SetBeforeHeadersSentCallback(
8181 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8182 base::Unretained(&headers_handler)));
8183 TestCompletionCallback callback;
8184 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8185 EXPECT_EQ(ERR_IO_PENDING, rv);
8186 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8187
8188 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8189 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8190}
8191
Yixin Wang00fc44c2018-01-23 21:12:208192// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8193// HTTP/2 stream dependency and weights given the request priority.
Ryan Hamilton4cbcbf12018-12-15 05:16:148194TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
Yixin Wang00fc44c2018-01-23 21:12:208195 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148196 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang00fc44c2018-01-23 21:12:208197 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498198 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208199
8200 const RequestPriority request_priority = MEDIUM;
8201
8202 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528203 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208204 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438205 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8206 mock_quic_data.AddWrite(
8207 SYNCHRONOUS,
8208 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338209 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8210 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438211 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208212 // Return an error, so the transaction stops here (this test isn't interested
8213 // in the rest).
8214 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8215
8216 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8217
8218 CreateSession();
8219
8220 request_.url = GURL("https://mail.example.org/");
8221 HttpNetworkTransaction trans(request_priority, session_.get());
8222 TestCompletionCallback callback;
8223 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8224 EXPECT_EQ(ERR_IO_PENDING, rv);
8225 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8226
8227 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8228 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8229}
8230
Yixin Wang46a273ec302018-01-23 17:59:568231// Test the request-challenge-retry sequence for basic auth, over a QUIC
8232// connection when setting up a QUIC proxy tunnel.
Ryan Hamilton4cbcbf12018-12-15 05:16:148233TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
Yixin Wang46a273ec302018-01-23 17:59:568234 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8235 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138236 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568237 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8238
8239 std::unique_ptr<QuicTestPacketMaker> client_maker;
8240 std::unique_ptr<QuicTestPacketMaker> server_maker;
8241
8242 // On the second pass, the body read of the auth challenge is synchronous, so
8243 // IsConnectedAndIdle returns false. The socket should still be drained and
8244 // reused. See http://crbug.com/544255.
8245 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338246 client_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178247 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8248 &clock_, kDefaultServerHostName, quic::Perspective::IS_CLIENT,
Fan Yang32c5a112018-12-10 20:06:338249 client_headers_include_h2_stream_dependency_));
8250 server_maker.reset(new QuicTestPacketMaker(
David Schinazic8281052019-01-24 06:14:178251 version_, quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
8252 &clock_, kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568253
8254 session_params_.enable_quic = true;
Ryan Hamilton4cbcbf12018-12-15 05:16:148255 session_params_.enable_quic_proxies_for_https_urls = true;
Yixin Wang46a273ec302018-01-23 17:59:568256 proxy_resolution_service_ =
8257 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498258 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568259
8260 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528261 quic::QuicStreamOffset client_header_stream_offset = 0;
8262 quic::QuicStreamOffset server_header_stream_offset = 0;
8263 quic::QuicStreamOffset client_data_offset = 0;
8264 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568265
Zhongyi Shi32f2fd02018-04-16 18:23:438266 mock_quic_data.AddWrite(SYNCHRONOUS,
8267 client_maker->MakeInitialSettingsPacket(
8268 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568269
8270 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438271 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568272 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338273 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8274 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568275 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8276 &client_header_stream_offset));
8277
Ryan Hamilton0239aac2018-05-19 00:03:138278 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568279 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8280 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8281 headers["content-length"] = "10";
8282 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438283 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338284 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8285 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568286
8287 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438288 mock_quic_data.AddRead(
8289 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338290 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8291 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568292 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438293 mock_quic_data.AddRead(
8294 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338295 2, GetNthClientInitiatedBidirectionalStreamId(0),
8296 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568297 }
8298 server_data_offset += 10;
8299
Zhongyi Shi32f2fd02018-04-16 18:23:438300 mock_quic_data.AddWrite(SYNCHRONOUS,
8301 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568302
8303 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338304 SYNCHRONOUS,
8305 client_maker->MakeRstPacket(
8306 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:188307 quic::QUIC_STREAM_CANCELLED, client_data_offset,
8308 /*include_stop_sending_if_v99=*/true));
Yixin Wang46a273ec302018-01-23 17:59:568309
8310 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8311 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8312 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338313 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8314 5, GetNthClientInitiatedBidirectionalStreamId(1),
8315 false, false, default_priority, std::move(headers),
8316 GetNthClientInitiatedBidirectionalStreamId(0),
8317 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568318
8319 // Response to wrong password
8320 headers =
8321 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8322 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8323 headers["content-length"] = "10";
8324 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438325 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338326 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8327 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568328 mock_quic_data.AddRead(SYNCHRONOUS,
8329 ERR_IO_PENDING); // No more data to read
8330
Fan Yang32c5a112018-12-10 20:06:338331 mock_quic_data.AddWrite(
8332 SYNCHRONOUS,
8333 client_maker->MakeAckAndRstPacket(
8334 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8335 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568336
8337 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8338 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8339
8340 CreateSession();
8341
8342 request_.url = GURL("https://mail.example.org/");
8343 // Ensure that proxy authentication is attempted even
8344 // when the no authentication data flag is set.
8345 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8346 {
8347 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8348 HeadersHandler headers_handler;
8349 trans.SetBeforeHeadersSentCallback(
8350 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8351 base::Unretained(&headers_handler)));
8352 RunTransaction(&trans);
8353
8354 const HttpResponseInfo* response = trans.GetResponseInfo();
8355 ASSERT_TRUE(response != nullptr);
8356 ASSERT_TRUE(response->headers.get() != nullptr);
8357 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8358 response->headers->GetStatusLine());
8359 EXPECT_TRUE(response->headers->IsKeepAlive());
8360 EXPECT_EQ(407, response->headers->response_code());
8361 EXPECT_EQ(10, response->headers->GetContentLength());
8362 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8363 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8364 ASSERT_TRUE(auth_challenge != nullptr);
8365 EXPECT_TRUE(auth_challenge->is_proxy);
8366 EXPECT_EQ("https://proxy.example.org:70",
8367 auth_challenge->challenger.Serialize());
8368 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8369 EXPECT_EQ("basic", auth_challenge->scheme);
8370
8371 TestCompletionCallback callback;
8372 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8373 callback.callback());
8374 EXPECT_EQ(ERR_IO_PENDING, rv);
8375 EXPECT_EQ(OK, callback.WaitForResult());
8376
8377 response = trans.GetResponseInfo();
8378 ASSERT_TRUE(response != nullptr);
8379 ASSERT_TRUE(response->headers.get() != nullptr);
8380 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8381 response->headers->GetStatusLine());
8382 EXPECT_TRUE(response->headers->IsKeepAlive());
8383 EXPECT_EQ(407, response->headers->response_code());
8384 EXPECT_EQ(10, response->headers->GetContentLength());
8385 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8386 auth_challenge = response->auth_challenge.get();
8387 ASSERT_TRUE(auth_challenge != nullptr);
8388 EXPECT_TRUE(auth_challenge->is_proxy);
8389 EXPECT_EQ("https://proxy.example.org:70",
8390 auth_challenge->challenger.Serialize());
8391 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8392 EXPECT_EQ("basic", auth_challenge->scheme);
8393 }
8394 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8395 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8396 // reused because it's not connected).
8397 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8398 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8399 }
8400}
8401
Yixin Wang385652a2018-02-16 02:37:238402TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8403 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8404 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268405 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238406 !client_headers_include_h2_stream_dependency_) {
8407 return;
8408 }
8409
8410 session_params_.origins_to_force_quic_on.insert(
8411 HostPortPair::FromString("mail.example.org:443"));
8412
Fan Yang32c5a112018-12-10 20:06:338413 const quic::QuicStreamId client_stream_0 =
8414 GetNthClientInitiatedBidirectionalStreamId(0);
8415 const quic::QuicStreamId client_stream_1 =
8416 GetNthClientInitiatedBidirectionalStreamId(1);
8417 const quic::QuicStreamId client_stream_2 =
8418 GetNthClientInitiatedBidirectionalStreamId(2);
8419 const quic::QuicStreamId push_stream_0 =
8420 GetNthServerInitiatedUnidirectionalStreamId(0);
8421 const quic::QuicStreamId push_stream_1 =
8422 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238423
8424 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528425 quic::QuicStreamOffset header_stream_offset = 0;
8426 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238427 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438428 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238429
8430 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438431 mock_quic_data.AddWrite(SYNCHRONOUS,
8432 ConstructClientRequestHeadersPacket(
8433 2, client_stream_0, true, true, HIGHEST,
8434 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8435 &header_stream_offset));
8436 mock_quic_data.AddWrite(SYNCHRONOUS,
8437 ConstructClientRequestHeadersPacket(
8438 3, client_stream_1, true, true, MEDIUM,
8439 GetRequestHeaders("GET", "https", "/1.jpg"),
8440 client_stream_0, &header_stream_offset));
8441 mock_quic_data.AddWrite(SYNCHRONOUS,
8442 ConstructClientRequestHeadersPacket(
8443 4, client_stream_2, true, true, MEDIUM,
8444 GetRequestHeaders("GET", "https", "/2.jpg"),
8445 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238446
8447 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438448 mock_quic_data.AddRead(
8449 ASYNC, ConstructServerResponseHeadersPacket(
8450 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8451 &server_header_offset));
8452 mock_quic_data.AddRead(
8453 ASYNC, ConstructServerResponseHeadersPacket(
8454 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8455 &server_header_offset));
8456 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8457 mock_quic_data.AddRead(
8458 ASYNC, ConstructServerResponseHeadersPacket(
8459 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8460 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238461
8462 // Server sends two push promises associated with |client_stream_0|; client
8463 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8464 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438465 mock_quic_data.AddRead(ASYNC,
8466 ConstructServerPushPromisePacket(
8467 4, client_stream_0, push_stream_0, false,
8468 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8469 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238470 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438471 SYNCHRONOUS,
8472 ConstructClientAckAndPriorityFramesPacket(
8473 6, false, 4, 3, 1,
8474 {{push_stream_0, client_stream_2,
8475 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8476 &header_stream_offset));
8477 mock_quic_data.AddRead(ASYNC,
8478 ConstructServerPushPromisePacket(
8479 5, client_stream_0, push_stream_1, false,
8480 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8481 &server_header_offset, &server_maker_));
8482 mock_quic_data.AddWrite(
8483 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238484 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8485 DEFAULT_PRIORITY, &header_stream_offset));
8486
8487 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438488 mock_quic_data.AddRead(
8489 ASYNC, ConstructServerResponseHeadersPacket(
8490 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8491 &server_header_offset));
8492 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8493 mock_quic_data.AddRead(
8494 ASYNC, ConstructServerResponseHeadersPacket(
8495 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8496 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238497
8498 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8499 // priority updates to match the request's priority. Client sends PRIORITY
8500 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438501 mock_quic_data.AddWrite(
8502 SYNCHRONOUS,
8503 ConstructClientAckAndPriorityFramesPacket(
8504 9, false, 7, 7, 1,
8505 {{push_stream_1, client_stream_2,
8506 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8507 {push_stream_0, client_stream_0,
8508 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8509 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238510
8511 // Server sends data for the three requests and the two push promises.
Renjief49758b2019-01-11 23:32:418512 quic::QuicString header = ConstructDataHeader(8);
Zhongyi Shi32f2fd02018-04-16 18:23:438513 mock_quic_data.AddRead(
8514 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418515 header + "hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438516 mock_quic_data.AddRead(
8517 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418518 header + "hello 1!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438519 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8520 mock_quic_data.AddRead(
8521 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
Renjief49758b2019-01-11 23:32:418522 header + "hello 2!"));
8523 quic::QuicString header2 = ConstructDataHeader(12);
Zhongyi Shi32f2fd02018-04-16 18:23:438524 mock_quic_data.AddRead(
8525 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
Renjief49758b2019-01-11 23:32:418526 header2 + "and hello 0!"));
Zhongyi Shi32f2fd02018-04-16 18:23:438527 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8528 mock_quic_data.AddRead(
8529 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
Renjief49758b2019-01-11 23:32:418530 header2 + "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238531
Yixin Wang385652a2018-02-16 02:37:238532 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8533 mock_quic_data.AddRead(ASYNC, 0); // EOF
8534 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8535
8536 // The non-alternate protocol job needs to hang in order to guarantee that
8537 // the alternate-protocol job will "win".
8538 AddHangingNonAlternateProtocolSocketData();
8539
8540 CreateSession();
8541
8542 request_.url = GURL("https://mail.example.org/0.jpg");
8543 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8544 TestCompletionCallback callback_0;
8545 EXPECT_EQ(ERR_IO_PENDING,
8546 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8547 base::RunLoop().RunUntilIdle();
8548
8549 request_.url = GURL("https://mail.example.org/1.jpg");
8550 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8551 TestCompletionCallback callback_1;
8552 EXPECT_EQ(ERR_IO_PENDING,
8553 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8554 base::RunLoop().RunUntilIdle();
8555
8556 request_.url = GURL("https://mail.example.org/2.jpg");
8557 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8558 TestCompletionCallback callback_2;
8559 EXPECT_EQ(ERR_IO_PENDING,
8560 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8561 base::RunLoop().RunUntilIdle();
8562
8563 // Client makes request that matches resource pushed in |pushed_stream_0|.
8564 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8565 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8566 TestCompletionCallback callback_3;
8567 EXPECT_EQ(ERR_IO_PENDING,
8568 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8569 base::RunLoop().RunUntilIdle();
8570
8571 EXPECT_TRUE(callback_0.have_result());
8572 EXPECT_EQ(OK, callback_0.WaitForResult());
8573 EXPECT_TRUE(callback_1.have_result());
8574 EXPECT_EQ(OK, callback_1.WaitForResult());
8575 EXPECT_TRUE(callback_2.have_result());
8576 EXPECT_EQ(OK, callback_2.WaitForResult());
8577
8578 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8579 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8580 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8581 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8582
8583 mock_quic_data.Resume();
8584 base::RunLoop().RunUntilIdle();
8585 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8586 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8587}
8588
[email protected]61a527782013-02-21 03:58:008589} // namespace test
8590} // namespace net