blob: cd4ef88ae6b389014a0a53b0fafa1aed27daf8b1 [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
[email protected]61a527782013-02-21 03:58:0011#include "base/compiler_specific.h"
Avi Drissman13fc8932015-12-20 04:40:4612#include "base/macros.h"
mmenke651bae7f2015-12-18 21:26:4513#include "base/run_loop.h"
[email protected]98b20ce2013-05-10 05:55:2614#include "base/stl_util.h"
zhongyie537a002017-06-27 16:48:2115#include "base/strings/string_number_conversions.h"
Bence Békyd74f4382018-02-20 18:26:1916#include "base/strings/string_piece.h"
bnc8be55ebb2015-10-30 14:12:0717#include "base/strings/stringprintf.h"
Devlin Cronine4bcb40e2018-06-05 18:02:4718#include "base/test/metrics/histogram_tester.h"
rtenneti56977812016-01-15 19:26:5619#include "net/base/chunked_upload_data_stream.h"
Bence Békyd8a21fc32018-06-27 18:29:5820#include "net/base/completion_once_callback.h"
mgershaf9a9232017-04-13 20:19:0321#include "net/base/mock_network_change_notifier.h"
[email protected]61a527782013-02-21 03:58:0022#include "net/base/test_completion_callback.h"
tbansalc3308d72016-08-27 10:25:0423#include "net/base/test_proxy_delegate.h"
rsleevid6de8302016-06-21 01:33:2024#include "net/cert/ct_policy_enforcer.h"
[email protected]6e7845ae2013-03-29 21:48:1125#include "net/cert/mock_cert_verifier.h"
rtenneti052774e2015-11-24 21:00:1226#include "net/cert/multi_log_ct_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5327#include "net/dns/mock_host_resolver.h"
[email protected]61a527782013-02-21 03:58:0028#include "net/http/http_auth_handler_factory.h"
29#include "net/http/http_network_session.h"
30#include "net/http/http_network_transaction.h"
31#include "net/http/http_server_properties_impl.h"
32#include "net/http/http_stream.h"
33#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1934#include "net/http/http_transaction_test_util.h"
[email protected]b1c988b2013-06-13 06:48:1135#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0036#include "net/log/net_log_event_type.h"
vishal.b62985ca92015-04-17 08:45:5137#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4638#include "net/log/test_net_log_entry.h"
39#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4040#include "net/proxy_resolution/proxy_config_service_fixed.h"
Lily Houghtonffe89daa02018-03-09 18:30:0341#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/proxy_resolution/proxy_resolver.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0843#include "net/quic/crypto/proof_verifier_chromium.h"
44#include "net/quic/mock_crypto_client_stream_factory.h"
45#include "net/quic/mock_quic_data.h"
46#include "net/quic/quic_chromium_alarm_factory.h"
47#include "net/quic/quic_http_stream.h"
48#include "net/quic/quic_http_utils.h"
49#include "net/quic/quic_stream_factory_peer.h"
50#include "net/quic/quic_test_packet_maker.h"
51#include "net/quic/test_task_runner.h"
[email protected]61a527782013-02-21 03:58:0052#include "net/socket/client_socket_factory.h"
53#include "net/socket/mock_client_socket_pool_manager.h"
bnc3472afd2016-11-17 15:27:2154#include "net/socket/next_proto.h"
tbansalca83c002016-04-28 20:56:2855#include "net/socket/socket_performance_watcher.h"
56#include "net/socket/socket_performance_watcher_factory.h"
[email protected]61a527782013-02-21 03:58:0057#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5858#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5759#include "net/ssl/ssl_config_service_defaults.h"
bnc508835902015-05-12 20:10:2960#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0161#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4362#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0163#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1664#include "net/third_party/quic/core/crypto/quic_decrypter.h"
65#include "net/third_party/quic/core/crypto/quic_encrypter.h"
66#include "net/third_party/quic/core/quic_framer.h"
Ryan Hamilton47cf9d12018-10-17 04:33:0967#include "net/third_party/quic/core/quic_utils.h"
Ryan Hamilton56b10c5d2018-05-11 13:40:1668#include "net/third_party/quic/platform/api/quic_str_cat.h"
69#include "net/third_party/quic/platform/api/quic_string_piece.h"
70#include "net/third_party/quic/platform/api/quic_test.h"
71#include "net/third_party/quic/test_tools/crypto_test_utils.h"
72#include "net/third_party/quic/test_tools/mock_clock.h"
73#include "net/third_party/quic/test_tools/mock_random.h"
74#include "net/third_party/quic/test_tools/quic_spdy_session_peer.h"
75#include "net/third_party/quic/test_tools/quic_test_utils.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2976#include "net/third_party/spdy/core/spdy_frame_builder.h"
77#include "net/third_party/spdy/core/spdy_framer.h"
rhalavati9ebaba7e2017-04-27 06:16:2978#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
allada71b2efb2016-09-09 04:57:4879#include "net/url_request/url_request.h"
80#include "net/url_request/url_request_job_factory_impl.h"
81#include "net/url_request/url_request_test_util.h"
robpercival214763f2016-07-01 23:27:0182#include "testing/gmock/include/gmock/gmock.h"
[email protected]61a527782013-02-21 03:58:0083#include "testing/gtest/include/gtest/gtest.h"
84#include "testing/platform_test.h"
zhongyi3d4a55e72016-04-22 20:36:4685#include "url/gurl.h"
[email protected]61a527782013-02-21 03:58:0086
Reilly Grant89a7e512018-01-20 01:57:1687using ::testing::ElementsAre;
88using ::testing::Key;
89
bnc508835902015-05-12 20:10:2990namespace net {
91namespace test {
[email protected]61a527782013-02-21 03:58:0092
93namespace {
94
bnc359ed2a2016-04-29 20:43:4595enum DestinationType {
96 // In pooling tests with two requests for different origins to the same
97 // destination, the destination should be
98 SAME_AS_FIRST, // the same as the first origin,
99 SAME_AS_SECOND, // the same as the second origin, or
100 DIFFERENT, // different from both.
101};
102
rchf114d982015-10-21 01:34:56103static const char kQuicAlternativeServiceHeader[] =
bncc958faa2015-07-31 18:14:52104 "Alt-Svc: quic=\":443\"\r\n\r\n";
rchf47265dc2016-03-21 21:33:12105static const char kQuicAlternativeServiceWithProbabilityHeader[] =
106 "Alt-Svc: quic=\":443\";p=\".5\"\r\n\r\n";
rchf114d982015-10-21 01:34:56107static const char kQuicAlternativeServiceDifferentPortHeader[] =
108 "Alt-Svc: quic=\":137\"\r\n\r\n";
[email protected]1e960032013-12-20 19:00:20109
rch9ae5b3b2016-02-11 00:36:29110const char kDefaultServerHostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45111const char kDifferentHostname[] = "different.example.com";
112
113// Run QuicNetworkTransactionWithDestinationTest instances with all value
114// combinations of version and destination_type.
115struct PoolingTestParams {
116 friend std::ostream& operator<<(std::ostream& os,
117 const PoolingTestParams& p) {
118 os << "{ version: " << QuicVersionToString(p.version)
119 << ", destination_type: ";
120 switch (p.destination_type) {
121 case SAME_AS_FIRST:
122 os << "SAME_AS_FIRST";
123 break;
124 case SAME_AS_SECOND:
125 os << "SAME_AS_SECOND";
126 break;
127 case DIFFERENT:
128 os << "DIFFERENT";
129 break;
130 }
Yixin Wang079ad542018-01-11 04:06:05131 os << ", client_headers_include_h2_stream_dependency: "
132 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45133 os << " }";
134 return os;
135 }
136
Ryan Hamilton8d9ee76e2018-05-29 23:52:52137 quic::QuicTransportVersion version;
bnc359ed2a2016-04-29 20:43:45138 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05139 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45140};
141
zhongyie537a002017-06-27 16:48:21142std::string GenerateQuicVersionsListForAltSvcHeader(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52143 const quic::QuicTransportVersionVector& versions) {
zhongyie537a002017-06-27 16:48:21144 std::string result = "";
Ryan Hamilton8d9ee76e2018-05-29 23:52:52145 for (const quic::QuicTransportVersion& version : versions) {
zhongyie537a002017-06-27 16:48:21146 if (!result.empty())
147 result.append(",");
148 result.append(base::IntToString(version));
149 }
150 return result;
151}
152
bnc359ed2a2016-04-29 20:43:45153std::vector<PoolingTestParams> GetPoolingTestParams() {
154 std::vector<PoolingTestParams> params;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52155 quic::QuicTransportVersionVector all_supported_versions =
156 quic::AllSupportedTransportVersions();
157 for (const quic::QuicTransportVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05158 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
159 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
160 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
161 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
162 params.push_back(PoolingTestParams{version, DIFFERENT, false});
163 params.push_back(PoolingTestParams{version, DIFFERENT, true});
bnc359ed2a2016-04-29 20:43:45164 }
165 return params;
166}
bncb07c05532015-05-14 19:07:20167
[email protected]61a527782013-02-21 03:58:00168} // namespace
169
ryansturm49a8cb12016-06-15 16:51:09170class HeadersHandler {
tbansal7cec3812015-02-05 21:25:12171 public:
ryansturm49a8cb12016-06-15 16:51:09172 HeadersHandler() : was_proxied_(false) {}
tbansal7cec3812015-02-05 21:25:12173
ryansturm49a8cb12016-06-15 16:51:09174 bool was_proxied() { return was_proxied_; }
tbansal7cec3812015-02-05 21:25:12175
ryansturm49a8cb12016-06-15 16:51:09176 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
177 HttpRequestHeaders* request_headers) {
178 if (!proxy_info.is_http() && !proxy_info.is_https() &&
179 !proxy_info.is_quic()) {
180 return;
181 }
182 was_proxied_ = true;
tbansal7cec3812015-02-05 21:25:12183 }
184
185 private:
ryansturm49a8cb12016-06-15 16:51:09186 bool was_proxied_;
tbansal7cec3812015-02-05 21:25:12187};
188
tbansal0f56a39a2016-04-07 22:03:38189class TestSocketPerformanceWatcher : public SocketPerformanceWatcher {
tbansalfdf5665b2015-09-21 22:46:40190 public:
tbansal180587c2017-02-16 15:13:23191 TestSocketPerformanceWatcher(bool* should_notify_updated_rtt,
192 bool* rtt_notification_received)
193 : should_notify_updated_rtt_(should_notify_updated_rtt),
194 rtt_notification_received_(rtt_notification_received) {}
tbansal0f56a39a2016-04-07 22:03:38195 ~TestSocketPerformanceWatcher() override {}
tbansalfdf5665b2015-09-21 22:46:40196
tbansal180587c2017-02-16 15:13:23197 bool ShouldNotifyUpdatedRTT() const override {
198 return *should_notify_updated_rtt_;
199 }
tbansalfdf5665b2015-09-21 22:46:40200
tbansal0f56a39a2016-04-07 22:03:38201 void OnUpdatedRTTAvailable(const base::TimeDelta& rtt) override {
202 *rtt_notification_received_ = true;
203 }
204
205 void OnConnectionChanged() override {}
206
207 private:
tbansal180587c2017-02-16 15:13:23208 bool* should_notify_updated_rtt_;
tbansal0f56a39a2016-04-07 22:03:38209 bool* rtt_notification_received_;
210
211 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcher);
212};
213
214class TestSocketPerformanceWatcherFactory
215 : public SocketPerformanceWatcherFactory {
216 public:
217 TestSocketPerformanceWatcherFactory()
tbansal180587c2017-02-16 15:13:23218 : watcher_count_(0u),
219 should_notify_updated_rtt_(true),
220 rtt_notification_received_(false) {}
tbansal0f56a39a2016-04-07 22:03:38221 ~TestSocketPerformanceWatcherFactory() override {}
222
223 // SocketPerformanceWatcherFactory implementation:
danakjad1777e2016-04-16 00:56:42224 std::unique_ptr<SocketPerformanceWatcher> CreateSocketPerformanceWatcher(
Tarun Bansal73a04372017-07-27 16:28:41225 const Protocol protocol,
226 const AddressList& /* address_list */) override {
tbansalc8a94ea2015-11-02 23:58:51227 if (protocol != PROTOCOL_QUIC) {
tbansal0f56a39a2016-04-07 22:03:38228 return nullptr;
tbansalc8a94ea2015-11-02 23:58:51229 }
230 ++watcher_count_;
danakjad1777e2016-04-16 00:56:42231 return std::unique_ptr<SocketPerformanceWatcher>(
tbansal180587c2017-02-16 15:13:23232 new TestSocketPerformanceWatcher(&should_notify_updated_rtt_,
233 &rtt_notification_received_));
tbansalfdf5665b2015-09-21 22:46:40234 }
235
tbansalc8a94ea2015-11-02 23:58:51236 size_t watcher_count() const { return watcher_count_; }
tbansalfdf5665b2015-09-21 22:46:40237
tbansalc8a94ea2015-11-02 23:58:51238 bool rtt_notification_received() const { return rtt_notification_received_; }
239
tbansal180587c2017-02-16 15:13:23240 void set_should_notify_updated_rtt(bool should_notify_updated_rtt) {
241 should_notify_updated_rtt_ = should_notify_updated_rtt;
242 }
243
tbansalc8a94ea2015-11-02 23:58:51244 private:
tbansal0f56a39a2016-04-07 22:03:38245 size_t watcher_count_;
tbansal180587c2017-02-16 15:13:23246 bool should_notify_updated_rtt_;
tbansalc8a94ea2015-11-02 23:58:51247 bool rtt_notification_received_;
tbansal0f56a39a2016-04-07 22:03:38248
249 DISALLOW_COPY_AND_ASSIGN(TestSocketPerformanceWatcherFactory);
tbansalc8a94ea2015-11-02 23:58:51250};
251
Ryan Hamilton8d9ee76e2018-05-29 23:52:52252class QuicNetworkTransactionTest
253 : public PlatformTest,
254 public ::testing::WithParamInterface<
255 std::tuple<quic::QuicTransportVersion, bool>>,
256 public WithScopedTaskEnvironment {
[email protected]61a527782013-02-21 03:58:00257 protected:
[email protected]1c04f9522013-02-21 20:32:43258 QuicNetworkTransactionTest()
Yixin Wang079ad542018-01-11 04:06:05259 : version_(std::get<0>(GetParam())),
260 client_headers_include_h2_stream_dependency_(std::get<1>(GetParam())),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52261 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc90be5dd782016-11-09 16:28:44262 client_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58263 0,
rchbf4c26d2017-04-16 23:17:55264 &clock_,
alyssar2adf3ac2016-05-03 17:12:58265 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52266 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:05267 client_headers_include_h2_stream_dependency_),
bnc90be5dd782016-11-09 16:28:44268 server_maker_(version_,
alyssar2adf3ac2016-05-03 17:12:58269 0,
rchbf4c26d2017-04-16 23:17:55270 &clock_,
alyssar2adf3ac2016-05-03 17:12:58271 kDefaultServerHostName,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52272 quic::Perspective::IS_SERVER,
Yixin Wang079ad542018-01-11 04:06:05273 false),
rtenneti052774e2015-11-24 21:00:12274 cert_transparency_verifier_(new MultiLogCTVerifier()),
[email protected]1c04f9522013-02-21 20:32:43275 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:59276 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
[email protected]1c04f9522013-02-21 20:32:43277 auth_handler_factory_(
[email protected]dda75ab2013-06-22 22:43:30278 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
[email protected]457d6952013-12-13 09:24:58279 random_generator_(0),
rchf114d982015-10-21 01:34:56280 ssl_data_(ASYNC, OK) {
[email protected]aa9b14d2013-05-10 23:45:19281 request_.method = "GET";
rchf114d982015-10-21 01:34:56282 std::string url("https://");
bncb07c05532015-05-14 19:07:20283 url.append(kDefaultServerHostName);
284 request_.url = GURL(url);
[email protected]aa9b14d2013-05-10 23:45:19285 request_.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:10286 request_.traffic_annotation =
287 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52288 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
rchf114d982015-10-21 01:34:56289
290 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:29291 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
rchf114d982015-10-21 01:34:56292 verify_details_.cert_verify_result.verified_cert = cert;
293 verify_details_.cert_verify_result.is_issued_by_known_root = true;
294 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
[email protected]1c04f9522013-02-21 20:32:43295 }
[email protected]61a527782013-02-21 03:58:00296
dcheng67be2b1f2014-10-27 21:47:29297 void SetUp() override {
[email protected]61a527782013-02-21 03:58:00298 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55299 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00300 }
301
dcheng67be2b1f2014-10-27 21:47:29302 void TearDown() override {
[email protected]61a527782013-02-21 03:58:00303 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
304 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55305 base::RunLoop().RunUntilIdle();
[email protected]61a527782013-02-21 03:58:00306 PlatformTest::TearDown();
307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55308 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:40309 session_.reset();
[email protected]61a527782013-02-21 03:58:00310 }
311
Ryan Hamilton8d9ee76e2018-05-29 23:52:52312 std::unique_ptr<quic::QuicEncryptedPacket>
313 ConstructClientConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03314 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52315 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
[email protected]3316d422013-05-03 21:45:30316 }
317
Ryan Hamilton8d9ee76e2018-05-29 23:52:52318 std::unique_ptr<quic::QuicEncryptedPacket>
319 ConstructServerConnectionClosePacket(quic::QuicPacketNumber num) {
Bin Wu5311aca2018-01-22 01:19:03320 return server_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52321 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
alyssar2adf3ac2016-05-03 17:12:58322 }
323
Ryan Hamilton8d9ee76e2018-05-29 23:52:52324 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
325 quic::QuicPacketNumber num,
326 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20327 std::string reason_phrase) {
alyssar2adf3ac2016-05-03 17:12:58328 return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
zhongyi6b5a3892016-03-12 04:46:20329 }
330
Ryan Hamilton8d9ee76e2018-05-29 23:52:52331 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
332 quic::QuicPacketNumber packet_number,
333 quic::QuicPacketNumber largest_received,
334 quic::QuicPacketNumber smallest_received,
335 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37336 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49337 smallest_received, least_unacked, true);
fayang3bcb8b502016-12-07 21:44:37338 }
339
Ryan Hamilton8d9ee76e2018-05-29 23:52:52340 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
341 quic::QuicPacketNumber packet_number,
342 quic::QuicPacketNumber largest_received,
343 quic::QuicPacketNumber smallest_received,
344 quic::QuicPacketNumber least_unacked,
345 quic::QuicTime::Delta ack_delay_time) {
rch9ecde09b2017-04-08 00:18:23346 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49347 smallest_received, least_unacked, true,
rch9ecde09b2017-04-08 00:18:23348 ack_delay_time);
349 }
350
Ryan Hamilton8d9ee76e2018-05-29 23:52:52351 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
352 quic::QuicPacketNumber num,
353 quic::QuicStreamId stream_id,
354 quic::QuicRstStreamErrorCode error_code,
355 quic::QuicPacketNumber largest_received,
356 quic::QuicPacketNumber smallest_received,
357 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58358 return client_maker_.MakeAckAndRstPacket(
wangyix6444ffe2017-04-25 17:49:49359 num, false, stream_id, error_code, largest_received, smallest_received,
360 least_unacked, true);
zhongyi6b5a3892016-03-12 04:46:20361 }
362
Ryan Hamilton8d9ee76e2018-05-29 23:52:52363 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
364 quic::QuicPacketNumber num,
365 quic::QuicStreamId stream_id,
366 quic::QuicRstStreamErrorCode error_code,
Yixin Wang46a273ec302018-01-23 17:59:56367 size_t bytes_written) {
368 return client_maker_.MakeRstPacket(num, false, stream_id, error_code,
369 bytes_written);
370 }
371
Ryan Hamilton8d9ee76e2018-05-29 23:52:52372 std::unique_ptr<quic::QuicEncryptedPacket>
373 ConstructClientAckAndConnectionClosePacket(
374 quic::QuicPacketNumber packet_number,
375 quic::QuicPacketNumber largest_received,
376 quic::QuicPacketNumber smallest_received,
377 quic::QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58378 return client_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49379 smallest_received, least_unacked, true);
[email protected]1e960032013-12-20 19:00:20380 }
[email protected]61a527782013-02-21 03:58:00381
Ryan Hamilton8d9ee76e2018-05-29 23:52:52382 std::unique_ptr<quic::QuicEncryptedPacket>
alyssar2adf3ac2016-05-03 17:12:58383 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52384 quic::QuicPacketNumber num,
385 quic::QuicTime::Delta delta_time_largest_observed,
386 quic::QuicPacketNumber largest_received,
387 quic::QuicPacketNumber smallest_received,
388 quic::QuicPacketNumber least_unacked,
389 quic::QuicErrorCode quic_error,
bnc912a04b2016-04-20 14:19:50390 const std::string& quic_error_details) {
alyssar2adf3ac2016-05-03 17:12:58391 return client_maker_.MakeAckAndConnectionClosePacket(
zhongyica364fbb2015-12-12 03:39:12392 num, false, delta_time_largest_observed, largest_received,
wangyix6444ffe2017-04-25 17:49:49393 smallest_received, least_unacked, quic_error, quic_error_details);
zhongyica364fbb2015-12-12 03:39:12394 }
395
Ryan Hamilton8d9ee76e2018-05-29 23:52:52396 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
397 quic::QuicPacketNumber num,
zhongyica364fbb2015-12-12 03:39:12398 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52399 quic::QuicStreamId stream_id,
400 quic::QuicRstStreamErrorCode error_code) {
alyssar2adf3ac2016-05-03 17:12:58401 return server_maker_.MakeRstPacket(num, include_version, stream_id,
402 error_code);
zhongyica364fbb2015-12-12 03:39:12403 }
404
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
406 quic::QuicPacketNumber packet_number,
407 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36408 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37409 }
410
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
412 quic::QuicPacketNumber packet_number,
413 quic::QuicPacketNumber largest_received,
414 quic::QuicPacketNumber smallest_received,
415 quic::QuicPacketNumber least_unacked) {
fayang3bcb8b502016-12-07 21:44:37416 return server_maker_.MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:49417 smallest_received, least_unacked, false);
fayang3bcb8b502016-12-07 21:44:37418 }
419
Ryan Hamilton8d9ee76e2018-05-29 23:52:52420 std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
421 quic::QuicPacketNumber packet_number,
Yixin Wangb470bc882018-02-15 18:43:57422 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 quic::QuicStreamId id,
424 quic::QuicStreamId parent_stream_id,
Yixin Wangb470bc882018-02-15 18:43:57425 RequestPriority request_priority,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 quic::QuicStreamOffset* offset) {
Yixin Wangb470bc882018-02-15 18:43:57427 return client_maker_.MakePriorityPacket(
428 packet_number, should_include_version, id, parent_stream_id,
Yixin Wang385652a2018-02-16 02:37:23429 ConvertRequestPriorityToQuicPriority(request_priority), offset);
430 }
431
Ryan Hamilton8d9ee76e2018-05-29 23:52:52432 std::unique_ptr<quic::QuicEncryptedPacket>
Yixin Wange7ecc472018-03-06 19:00:25433 ConstructClientAckAndPriorityFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52434 quic::QuicPacketNumber packet_number,
Yixin Wang385652a2018-02-16 02:37:23435 bool should_include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52436 quic::QuicPacketNumber largest_received,
437 quic::QuicPacketNumber smallest_received,
438 quic::QuicPacketNumber least_unacked,
Yixin Wange7ecc472018-03-06 19:00:25439 const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
440 priority_frames,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52441 quic::QuicStreamOffset* offset) {
Yixin Wange7ecc472018-03-06 19:00:25442 return client_maker_.MakeAckAndMultiplePriorityFramesPacket(
Yixin Wang385652a2018-02-16 02:37:23443 packet_number, should_include_version, largest_received,
Yixin Wange7ecc472018-03-06 19:00:25444 smallest_received, least_unacked, priority_frames, offset);
Yixin Wangb470bc882018-02-15 18:43:57445 }
446
zhongyi32569c62016-01-08 02:54:30447 // Uses default QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13448 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
449 const std::string& scheme,
450 const std::string& path) {
alyssar2adf3ac2016-05-03 17:12:58451 return GetRequestHeaders(method, scheme, path, &client_maker_);
zhongyi32569c62016-01-08 02:54:30452 }
453
454 // Uses customized QuicTestPacketMaker.
Ryan Hamilton0239aac2018-05-19 00:03:13455 spdy::SpdyHeaderBlock GetRequestHeaders(const std::string& method,
456 const std::string& scheme,
457 const std::string& path,
458 QuicTestPacketMaker* maker) {
bnc912a04b2016-04-20 14:19:50459 return maker->GetRequestHeaders(method, scheme, path);
[email protected]61a527782013-02-21 03:58:00460 }
461
Ryan Hamilton0239aac2018-05-19 00:03:13462 spdy::SpdyHeaderBlock ConnectRequestHeaders(const std::string& host_port) {
Yixin Wang46a273ec302018-01-23 17:59:56463 return client_maker_.ConnectRequestHeaders(host_port);
464 }
465
Ryan Hamilton0239aac2018-05-19 00:03:13466 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
alyssar2adf3ac2016-05-03 17:12:58467 return server_maker_.GetResponseHeaders(status);
[email protected]61a527782013-02-21 03:58:00468 }
469
zhongyi32569c62016-01-08 02:54:30470 // Appends alt_svc headers in the response headers.
Ryan Hamilton0239aac2018-05-19 00:03:13471 spdy::SpdyHeaderBlock GetResponseHeaders(const std::string& status,
472 const std::string& alt_svc) {
alyssar2adf3ac2016-05-03 17:12:58473 return server_maker_.GetResponseHeaders(status, alt_svc);
zhongyi32569c62016-01-08 02:54:30474 }
475
Ryan Hamilton8d9ee76e2018-05-29 23:52:52476 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
477 quic::QuicPacketNumber packet_number,
478 quic::QuicStreamId stream_id,
[email protected]e8ff26842013-03-22 21:02:05479 bool should_include_version,
[email protected]61a527782013-02-21 03:58:00480 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52481 quic::QuicStreamOffset offset,
482 quic::QuicStringPiece data) {
alyssar2adf3ac2016-05-03 17:12:58483 return server_maker_.MakeDataPacket(
484 packet_number, stream_id, should_include_version, fin, offset, data);
[email protected]61a527782013-02-21 03:58:00485 }
486
Ryan Hamilton8d9ee76e2018-05-29 23:52:52487 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
488 quic::QuicPacketNumber packet_number,
489 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36490 bool should_include_version,
491 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52492 quic::QuicStreamOffset offset,
493 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36494 return client_maker_.MakeDataPacket(
495 packet_number, stream_id, should_include_version, fin, offset, data);
496 }
497
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
499 quic::QuicPacketNumber packet_number,
Yixin Wang46a273ec302018-01-23 17:59:56500 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52501 quic::QuicStreamId stream_id,
502 quic::QuicPacketNumber largest_received,
503 quic::QuicPacketNumber smallest_received,
504 quic::QuicPacketNumber least_unacked,
Yixin Wang46a273ec302018-01-23 17:59:56505 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52506 quic::QuicStreamOffset offset,
507 quic::QuicStringPiece data) {
Yixin Wang46a273ec302018-01-23 17:59:56508 return client_maker_.MakeAckAndDataPacket(
509 packet_number, include_version, stream_id, largest_received,
510 smallest_received, least_unacked, fin, offset, data);
511 }
512
Ryan Hamilton8d9ee76e2018-05-29 23:52:52513 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
514 quic::QuicPacketNumber packet_number,
515 quic::QuicStreamId stream_id,
ckrasicda193a82016-07-09 00:39:36516 bool should_include_version,
517 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52518 quic::QuicStreamOffset* offset,
519 quic::QuicStringPiece data) {
ckrasicda193a82016-07-09 00:39:36520 return client_maker_.MakeForceHolDataPacket(
521 packet_number, stream_id, should_include_version, fin, offset, data);
522 }
523
Ryan Hamilton8d9ee76e2018-05-29 23:52:52524 std::unique_ptr<quic::QuicEncryptedPacket>
525 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
526 quic::QuicStreamId stream_id,
527 bool should_include_version,
528 bool fin,
529 spdy::SpdyHeaderBlock headers) {
Yixin Wang46a273ec302018-01-23 17:59:56530 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
531 should_include_version, fin,
532 std::move(headers), nullptr);
533 }
534
Ryan Hamilton8d9ee76e2018-05-29 23:52:52535 std::unique_ptr<quic::QuicEncryptedPacket>
536 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
537 quic::QuicStreamId stream_id,
538 bool should_include_version,
539 bool fin,
540 spdy::SpdyHeaderBlock headers,
541 quic::QuicStreamOffset* offset) {
Yixin Wang7a3f1b8d2018-01-17 21:40:48542 return ConstructClientRequestHeadersPacket(packet_number, stream_id,
543 should_include_version, fin,
544 std::move(headers), 0, offset);
545 }
546
Ryan Hamilton8d9ee76e2018-05-29 23:52:52547 std::unique_ptr<quic::QuicEncryptedPacket>
548 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
549 quic::QuicStreamId stream_id,
550 bool should_include_version,
551 bool fin,
552 spdy::SpdyHeaderBlock headers,
553 quic::QuicStreamId parent_stream_id,
554 quic::QuicStreamOffset* offset) {
Yixin Wang46a273ec302018-01-23 17:59:56555 return ConstructClientRequestHeadersPacket(
556 packet_number, stream_id, should_include_version, fin, DEFAULT_PRIORITY,
Yixin Wang7a3f1b8d2018-01-17 21:40:48557 std::move(headers), parent_stream_id, offset);
zhongyi32569c62016-01-08 02:54:30558 }
559
Ryan Hamilton8d9ee76e2018-05-29 23:52:52560 std::unique_ptr<quic::QuicEncryptedPacket>
561 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
562 quic::QuicStreamId stream_id,
563 bool should_include_version,
564 bool fin,
565 RequestPriority request_priority,
566 spdy::SpdyHeaderBlock headers,
567 quic::QuicStreamId parent_stream_id,
568 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13569 spdy::SpdyPriority priority =
Yixin Wang46a273ec302018-01-23 17:59:56570 ConvertRequestPriorityToQuicPriority(request_priority);
571 return client_maker_.MakeRequestHeadersPacketWithOffsetTracking(
572 packet_number, stream_id, should_include_version, fin, priority,
573 std::move(headers), parent_stream_id, offset);
[email protected]61a527782013-02-21 03:58:00574 }
575
Ryan Hamilton8d9ee76e2018-05-29 23:52:52576 std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25577 ConstructClientRequestHeadersAndDataFramesPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52578 quic::QuicPacketNumber packet_number,
579 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25580 bool should_include_version,
581 bool fin,
582 RequestPriority request_priority,
Ryan Hamilton0239aac2018-05-19 00:03:13583 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52584 quic::QuicStreamId parent_stream_id,
585 quic::QuicStreamOffset* offset,
Yixin Wange7ecc472018-03-06 19:00:25586 size_t* spdy_headers_frame_length,
587 const std::vector<std::string>& data_writes) {
Ryan Hamilton0239aac2018-05-19 00:03:13588 spdy::SpdyPriority priority =
Yixin Wange7ecc472018-03-06 19:00:25589 ConvertRequestPriorityToQuicPriority(request_priority);
590 return client_maker_.MakeRequestHeadersAndMultipleDataFramesPacket(
591 packet_number, stream_id, should_include_version, fin, priority,
592 std::move(headers), parent_stream_id, offset, spdy_headers_frame_length,
593 data_writes);
594 }
595
Ryan Hamilton8d9ee76e2018-05-29 23:52:52596 std::unique_ptr<quic::QuicEncryptedPacket>
597 ConstructClientMultipleDataFramesPacket(quic::QuicPacketNumber packet_number,
598 quic::QuicStreamId stream_id,
599 bool should_include_version,
600 bool fin,
601 const std::vector<std::string>& data,
602 quic::QuicStreamOffset offset) {
ckrasicdee37572017-04-06 22:42:27603 return client_maker_.MakeMultipleDataFramesPacket(
604 packet_number, stream_id, should_include_version, fin, offset, data);
605 }
606
Ryan Hamilton8d9ee76e2018-05-29 23:52:52607 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
608 quic::QuicPacketNumber packet_number,
609 quic::QuicStreamId stream_id,
610 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13611 bool should_include_version,
Ryan Hamilton0239aac2018-05-19 00:03:13612 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52613 quic::QuicStreamOffset* offset,
ckrasic769733c2016-06-30 00:42:13614 QuicTestPacketMaker* maker) {
615 return maker->MakePushPromisePacket(
616 packet_number, stream_id, promised_stream_id, should_include_version,
617 false, std::move(headers), nullptr, offset);
618 }
619
Ryan Hamilton8d9ee76e2018-05-29 23:52:52620 std::unique_ptr<quic::QuicEncryptedPacket>
621 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
622 quic::QuicStreamId stream_id,
623 bool should_include_version,
624 bool fin,
625 spdy::SpdyHeaderBlock headers) {
zhongyi76cfa7602016-07-12 19:56:27626 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
627 should_include_version, fin,
628 std::move(headers), nullptr);
zhongyi32569c62016-01-08 02:54:30629 }
630
Ryan Hamilton8d9ee76e2018-05-29 23:52:52631 std::unique_ptr<quic::QuicEncryptedPacket>
632 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
633 quic::QuicStreamId stream_id,
634 bool should_include_version,
635 bool fin,
636 spdy::SpdyHeaderBlock headers,
637 quic::QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58638 return server_maker_.MakeResponseHeadersPacketWithOffsetTracking(
bnc94893a72016-06-30 13:45:25639 packet_number, stream_id, should_include_version, fin,
640 std::move(headers), offset);
zhongyi32569c62016-01-08 02:54:30641 }
642
Ryan Hamilton8d9ee76e2018-05-29 23:52:52643 void CreateSession(
644 const quic::QuicTransportVersionVector& supported_versions) {
mmenke6ddfbea2017-05-31 21:48:41645 session_params_.enable_quic = true;
zhongyie537a002017-06-27 16:48:21646 session_params_.quic_supported_versions = supported_versions;
Yixin Wang079ad542018-01-11 04:06:05647 session_params_.quic_headers_include_h2_stream_dependency =
648 client_headers_include_h2_stream_dependency_;
[email protected]61a527782013-02-21 03:58:00649
mmenke6ddfbea2017-05-31 21:48:41650 session_context_.quic_clock = &clock_;
651 session_context_.quic_random = &random_generator_;
652 session_context_.client_socket_factory = &socket_factory_;
653 session_context_.quic_crypto_client_stream_factory =
654 &crypto_client_stream_factory_;
655 session_context_.host_resolver = &host_resolver_;
656 session_context_.cert_verifier = &cert_verifier_;
657 session_context_.transport_security_state = &transport_security_state_;
658 session_context_.cert_transparency_verifier =
659 cert_transparency_verifier_.get();
660 session_context_.ct_policy_enforcer = &ct_policy_enforcer_;
661 session_context_.socket_performance_watcher_factory =
662 &test_socket_performance_watcher_factory_;
Lily Houghton8c2f97d2018-01-22 05:06:59663 session_context_.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:41664 session_context_.ssl_config_service = ssl_config_service_.get();
665 session_context_.http_auth_handler_factory = auth_handler_factory_.get();
666 session_context_.http_server_properties = &http_server_properties_;
667 session_context_.net_log = net_log_.bound().net_log();
668
669 session_.reset(new HttpNetworkSession(session_params_, session_context_));
[email protected]11c05872013-08-20 02:04:12670 session_->quic_stream_factory()->set_require_confirmation(false);
Yixin Wang46a273ec302018-01-23 17:59:56671 SpdySessionPoolPeer spdy_pool_peer(session_->spdy_session_pool());
672 spdy_pool_peer.SetEnableSendingInitialData(false);
[email protected]61a527782013-02-21 03:58:00673 }
674
zhongyi86838d52017-06-30 01:19:44675 void CreateSession() { return CreateSession(supported_versions_); }
zhongyie537a002017-06-27 16:48:21676
bnc691fda62016-08-12 00:43:16677 void CheckWasQuicResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19678 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42679 ASSERT_TRUE(response != nullptr);
680 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19681 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
682 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52683 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:44684 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
[email protected]aa9b14d2013-05-10 23:45:19685 response->connection_info);
686 }
687
bnc691fda62016-08-12 00:43:16688 void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) {
bnc62a44f022015-04-02 15:59:41689 const HttpResponseInfo* response = trans->GetResponseInfo();
690 ASSERT_TRUE(response != nullptr);
691 EXPECT_EQ(port, response->socket_address.port());
692 }
693
bnc691fda62016-08-12 00:43:16694 void CheckWasHttpResponse(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19695 const HttpResponseInfo* response = trans->GetResponseInfo();
rtennetibe635732014-10-02 22:51:42696 ASSERT_TRUE(response != nullptr);
697 ASSERT_TRUE(response->headers.get() != nullptr);
[email protected]aa9b14d2013-05-10 23:45:19698 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
699 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:52700 EXPECT_FALSE(response->was_alpn_negotiated);
mmenke8210acc2016-07-11 16:34:52701 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1_1,
[email protected]aa9b14d2013-05-10 23:45:19702 response->connection_info);
703 }
704
Yixin Wang46a273ec302018-01-23 17:59:56705 void CheckWasSpdyResponse(HttpNetworkTransaction* trans) {
706 const HttpResponseInfo* response = trans->GetResponseInfo();
707 ASSERT_TRUE(response != nullptr);
708 ASSERT_TRUE(response->headers.get() != nullptr);
709 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
710 EXPECT_TRUE(response->was_fetched_via_spdy);
711 EXPECT_TRUE(response->was_alpn_negotiated);
712 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP2,
713 response->connection_info);
714 }
715
bnc691fda62016-08-12 00:43:16716 void CheckResponseData(HttpNetworkTransaction* trans,
[email protected]aa9b14d2013-05-10 23:45:19717 const std::string& expected) {
718 std::string response_data;
bnc691fda62016-08-12 00:43:16719 ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19720 EXPECT_EQ(expected, response_data);
721 }
722
bnc691fda62016-08-12 00:43:16723 void RunTransaction(HttpNetworkTransaction* trans) {
[email protected]aa9b14d2013-05-10 23:45:19724 TestCompletionCallback callback;
725 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:01726 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
727 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]aa9b14d2013-05-10 23:45:19728 }
729
730 void SendRequestAndExpectHttpResponse(const std::string& expected) {
bnc691fda62016-08-12 00:43:16731 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
732 RunTransaction(&trans);
733 CheckWasHttpResponse(&trans);
734 CheckResponseData(&trans, expected);
[email protected]aa9b14d2013-05-10 23:45:19735 }
736
tbansalc3308d72016-08-27 10:25:04737 void SendRequestAndExpectHttpResponseFromProxy(const std::string& expected,
738 bool used_proxy,
739 uint16_t port) {
740 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
741 HeadersHandler headers_handler;
742 trans.SetBeforeHeadersSentCallback(
743 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
744 base::Unretained(&headers_handler)));
745 RunTransaction(&trans);
746 CheckWasHttpResponse(&trans);
747 CheckResponsePort(&trans, port);
748 CheckResponseData(&trans, expected);
749 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47750 if (used_proxy) {
751 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_https());
752 } else {
753 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
754 }
tbansalc3308d72016-08-27 10:25:04755 }
756
[email protected]aa9b14d2013-05-10 23:45:19757 void SendRequestAndExpectQuicResponse(const std::string& expected) {
rchf114d982015-10-21 01:34:56758 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, 443);
tbansal7cec3812015-02-05 21:25:12759 }
760
bnc62a44f022015-04-02 15:59:41761 void SendRequestAndExpectQuicResponseFromProxyOnPort(
762 const std::string& expected,
Avi Drissman13fc8932015-12-20 04:40:46763 uint16_t port) {
bnc62a44f022015-04-02 15:59:41764 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, true, port);
[email protected]aa9b14d2013-05-10 23:45:19765 }
766
767 void AddQuicAlternateProtocolMapping(
Ryan Hamilton9835e662018-08-02 05:36:27768 MockCryptoClientStream::HandshakeMode handshake_mode) {
[email protected]aa9b14d2013-05-10 23:45:19769 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46770 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21771 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
bnc7dc7e1b42015-07-28 14:43:12772 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21773 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44774 server, alternative_service, expiration, supported_versions_);
[email protected]aa9b14d2013-05-10 23:45:19775 }
776
rchbe69cb902016-02-11 01:10:48777 void AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:27778 MockCryptoClientStream::HandshakeMode handshake_mode,
rchbe69cb902016-02-11 01:10:48779 const HostPortPair& alternative) {
780 crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
zhongyi3d4a55e72016-04-22 20:36:46781 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:21782 AlternativeService alternative_service(kProtoQUIC, alternative.host(),
rchbe69cb902016-02-11 01:10:48783 alternative.port());
784 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:21785 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:44786 server, alternative_service, expiration, supported_versions_);
rchbe69cb902016-02-11 01:10:48787 }
788
[email protected]aa9b14d2013-05-10 23:45:19789 void ExpectBrokenAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46790 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34791 const AlternativeServiceInfoVector alternative_service_info_vector =
792 http_server_properties_.GetAlternativeServiceInfos(server);
793 EXPECT_EQ(1u, alternative_service_info_vector.size());
bnc6be245c12015-05-15 11:24:07794 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54795 alternative_service_info_vector[0].alternative_service()));
[email protected]aa9b14d2013-05-10 23:45:19796 }
797
[email protected]4d590c9c2014-05-02 05:14:33798 void ExpectQuicAlternateProtocolMapping() {
zhongyi3d4a55e72016-04-22 20:36:46799 const url::SchemeHostPort server(request_.url);
zhongyic4de03032017-05-19 04:07:34800 const AlternativeServiceInfoVector alternative_service_info_vector =
801 http_server_properties_.GetAlternativeServiceInfos(server);
802 EXPECT_EQ(1u, alternative_service_info_vector.size());
zhongyi422ce352017-06-09 23:28:54803 EXPECT_EQ(
804 kProtoQUIC,
805 alternative_service_info_vector[0].alternative_service().protocol);
rch9ecde09b2017-04-08 00:18:23806 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(
zhongyi422ce352017-06-09 23:28:54807 alternative_service_info_vector[0].alternative_service()));
[email protected]4d590c9c2014-05-02 05:14:33808 }
809
[email protected]aa9b14d2013-05-10 23:45:19810 void AddHangingNonAlternateProtocolSocketData() {
danakjad1777e2016-04-16 00:56:42811 std::unique_ptr<StaticSocketDataProvider> hanging_data;
zhongyi32569c62016-01-08 02:54:30812 hanging_data.reset(new StaticSocketDataProvider());
[email protected]dda75ab2013-06-22 22:43:30813 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
zhongyi32569c62016-01-08 02:54:30814 hanging_data->set_connect_data(hanging_connect);
815 hanging_data_.push_back(std::move(hanging_data));
816 socket_factory_.AddSocketDataProvider(hanging_data_.back().get());
rchf114d982015-10-21 01:34:56817 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]aa9b14d2013-05-10 23:45:19818 }
819
Zhongyi Shia6b68d112018-09-24 07:49:03820 void SetUpTestForRetryConnectionOnAlternateNetwork() {
821 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
822 session_params_.quic_migrate_sessions_early_v2 = true;
823 session_params_.quic_retry_on_alternate_network_before_handshake = true;
824 scoped_mock_change_notifier_.reset(new ScopedMockNetworkChangeNotifier());
825 MockNetworkChangeNotifier* mock_ncn =
826 scoped_mock_change_notifier_->mock_network_change_notifier();
827 mock_ncn->ForceNetworkHandlesSupported();
828 mock_ncn->SetConnectedNetworksList(
829 {kDefaultNetworkForTests, kNewNetworkForTests});
830 }
831
tbansalc3308d72016-08-27 10:25:04832 // Fetches two non-cryptographic URL requests via a HTTPS proxy with a QUIC
833 // alternative proxy. Verifies that if the alternative proxy job returns
834 // |error_code|, the request is fetched successfully by the main job.
835 void TestAlternativeProxy(int error_code) {
836 // Use a non-cryptographic scheme for the request URL since this request
837 // will be fetched via proxy with QUIC as the alternative service.
838 request_.url = GURL("http://example.org/");
839 // Data for the alternative proxy server job.
tbansal6490783c2016-09-20 17:55:27840 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
tbansalc3308d72016-08-27 10:25:04841 MockRead quic_reads[] = {
tbansal6490783c2016-09-20 17:55:27842 MockRead(SYNCHRONOUS, error_code, 0),
tbansalc3308d72016-08-27 10:25:04843 };
844
Ryan Sleevib8d7ea02018-05-07 20:01:01845 SequencedSocketData quic_data(quic_reads, quic_writes);
tbansalc3308d72016-08-27 10:25:04846 socket_factory_.AddSocketDataProvider(&quic_data);
847
848 // Main job succeeds and the alternative job fails.
849 // Add data for two requests that will be read by the main job.
850 MockRead http_reads_1[] = {
851 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
852 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
853 MockRead(ASYNC, OK)};
854
855 MockRead http_reads_2[] = {
856 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
857 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
858 MockRead(ASYNC, OK)};
859
Ryan Sleevib8d7ea02018-05-07 20:01:01860 StaticSocketDataProvider http_data_1(http_reads_1, base::span<MockWrite>());
861 StaticSocketDataProvider http_data_2(http_reads_2, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:04862 socket_factory_.AddSocketDataProvider(&http_data_1);
863 socket_factory_.AddSocketDataProvider(&http_data_2);
864 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
865 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
866
867 TestProxyDelegate test_proxy_delegate;
868 // Proxy URL is different from the request URL.
869 test_proxy_delegate.set_alternative_proxy_server(
870 ProxyServer::FromPacString("QUIC myproxy.org:443"));
871
Lily Houghton8c2f97d2018-01-22 05:06:59872 proxy_resolution_service_ =
873 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:49874 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:52875 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:04876
877 CreateSession();
878 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
879
880 // The first request should be fetched via the HTTPS proxy.
881 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
882
Reilly Grant89a7e512018-01-20 01:57:16883 // Since the main job succeeded only the alternative proxy server should be
884 // marked as bad.
Lily Houghton8c2f97d2018-01-22 05:06:59885 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:16886 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:04887
888 // Verify that the second request completes successfully, and the
889 // alternative proxy server job is not started.
890 SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
891 }
892
Ryan Hamilton8d9ee76e2018-05-29 23:52:52893 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
894 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36895 }
896
Ryan Hamilton8d9ee76e2018-05-29 23:52:52897 quic::QuicStreamId GetNthServerInitiatedStreamId(int n) {
898 return quic::test::GetNthServerInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36899 }
900
Bence Béky230ac612017-08-30 19:17:08901 static void AddCertificate(SSLSocketDataProvider* ssl_data) {
Ryan Sleevi4f832092017-11-21 23:25:49902 ssl_data->ssl_info.cert =
Bence Béky230ac612017-08-30 19:17:08903 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
Ryan Sleevi4f832092017-11-21 23:25:49904 ASSERT_TRUE(ssl_data->ssl_info.cert);
Bence Béky230ac612017-08-30 19:17:08905 }
906
Ryan Hamilton8d9ee76e2018-05-29 23:52:52907 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:05908 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52909 quic::QuicTransportVersionVector supported_versions_;
rchb1c56982016-09-03 00:06:01910 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52911 quic::MockClock clock_;
alyssar2adf3ac2016-05-03 17:12:58912 QuicTestPacketMaker client_maker_;
913 QuicTestPacketMaker server_maker_;
danakjad1777e2016-04-16 00:56:42914 std::unique_ptr<HttpNetworkSession> session_;
[email protected]61a527782013-02-21 03:58:00915 MockClientSocketFactory socket_factory_;
rchf114d982015-10-21 01:34:56916 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05917 MockCryptoClientStreamFactory crypto_client_stream_factory_;
[email protected]1c04f9522013-02-21 20:32:43918 MockHostResolver host_resolver_;
919 MockCertVerifier cert_verifier_;
[email protected]b1c988b2013-06-13 06:48:11920 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42921 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23922 DefaultCTPolicyEnforcer ct_policy_enforcer_;
tbansal0f56a39a2016-04-07 22:03:38923 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:07924 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:59925 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
danakjad1777e2016-04-16 00:56:42926 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52927 quic::test::MockRandom random_generator_;
bnc6be245c12015-05-15 11:24:07928 HttpServerPropertiesImpl http_server_properties_;
mmenke6ddfbea2017-05-31 21:48:41929 HttpNetworkSession::Params session_params_;
930 HttpNetworkSession::Context session_context_;
[email protected]aa9b14d2013-05-10 23:45:19931 HttpRequestInfo request_;
vishal.b62985ca92015-04-17 08:45:51932 BoundTestNetLog net_log_;
danakjad1777e2016-04-16 00:56:42933 std::vector<std::unique_ptr<StaticSocketDataProvider>> hanging_data_;
rchf114d982015-10-21 01:34:56934 SSLSocketDataProvider ssl_data_;
Zhongyi Shia6b68d112018-09-24 07:49:03935 std::unique_ptr<ScopedMockNetworkChangeNotifier> scoped_mock_change_notifier_;
tbansal7cec3812015-02-05 21:25:12936
937 private:
938 void SendRequestAndExpectQuicResponseMaybeFromProxy(
939 const std::string& expected,
bnc62a44f022015-04-02 15:59:41940 bool used_proxy,
Avi Drissman13fc8932015-12-20 04:40:46941 uint16_t port) {
bnc691fda62016-08-12 00:43:16942 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
ryansturm49a8cb12016-06-15 16:51:09943 HeadersHandler headers_handler;
bnc691fda62016-08-12 00:43:16944 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:09945 base::Bind(&HeadersHandler::OnBeforeHeadersSent,
946 base::Unretained(&headers_handler)));
bnc691fda62016-08-12 00:43:16947 RunTransaction(&trans);
948 CheckWasQuicResponse(&trans);
949 CheckResponsePort(&trans, port);
950 CheckResponseData(&trans, expected);
ryansturm49a8cb12016-06-15 16:51:09951 EXPECT_EQ(used_proxy, headers_handler.was_proxied());
tbansal2ecbbc72016-10-06 17:15:47952 if (used_proxy) {
953 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
954 } else {
955 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_direct());
956 }
tbansal7cec3812015-02-05 21:25:12957 }
[email protected]61a527782013-02-21 03:58:00958};
959
Yixin Wang079ad542018-01-11 04:06:05960INSTANTIATE_TEST_CASE_P(
Yixin Wang385652a2018-02-16 02:37:23961 VersionIncludeStreamDependencySequence,
Yixin Wang079ad542018-01-11 04:06:05962 QuicNetworkTransactionTest,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52963 ::testing::Combine(
964 ::testing::ValuesIn(quic::AllSupportedTransportVersions()),
965 ::testing::Bool()));
[email protected]1e960032013-12-20 19:00:20966
Ryan Hamiltona64a5bcf2017-11-30 07:35:28967TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:48968 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28969 base::HistogramTester histograms;
970 session_params_.origins_to_force_quic_on.insert(
971 HostPortPair::FromString("mail.example.org:443"));
972 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27973 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:28974
975 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52976 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:28977 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43978 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:28979 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
980 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
981 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
982
983 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
984
985 CreateSession();
986
987 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
988 TestCompletionCallback callback;
989 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
991 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
992
993 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
994 -ERR_INTERNET_DISCONNECTED, 1);
995 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
996 -ERR_INTERNET_DISCONNECTED, 1);
997}
998
999TEST_P(QuicNetworkTransactionTest, WriteErrorHandshakeConfirmedAsync) {
Ryan Hamiltonb3827e882018-03-27 03:07:481000 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281001 base::HistogramTester histograms;
1002 session_params_.origins_to_force_quic_on.insert(
1003 HostPortPair::FromString("mail.example.org:443"));
1004 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271005 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Ryan Hamiltona64a5bcf2017-11-30 07:35:281006
1007 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521008 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamiltona64a5bcf2017-11-30 07:35:281009 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431010 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamiltona64a5bcf2017-11-30 07:35:281011 mock_quic_data.AddWrite(ASYNC, ERR_INTERNET_DISCONNECTED);
1012 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
1013 mock_quic_data.AddRead(ASYNC, OK); // No more data to read
1014
1015 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1016
1017 CreateSession();
1018
1019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1020 TestCompletionCallback callback;
1021 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1022 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1023 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1024
1025 histograms.ExpectBucketCount("Net.QuicSession.WriteError",
1026 -ERR_INTERNET_DISCONNECTED, 1);
1027 histograms.ExpectBucketCount("Net.QuicSession.WriteError.HandshakeConfirmed",
1028 -ERR_INTERNET_DISCONNECTED, 1);
1029}
1030
tbansal180587c2017-02-16 15:13:231031TEST_P(QuicNetworkTransactionTest, SocketWatcherEnabled) {
mmenke6ddfbea2017-05-31 21:48:411032 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231033 HostPortPair::FromString("mail.example.org:443"));
1034
1035 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521036 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361037 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431038 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1039 mock_quic_data.AddWrite(
1040 SYNCHRONOUS,
1041 ConstructClientRequestHeadersPacket(
1042 2, GetNthClientInitiatedStreamId(0), true, true,
1043 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1044 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1045 1, GetNthClientInitiatedStreamId(0), false,
1046 false, GetResponseHeaders("200 OK")));
1047 mock_quic_data.AddRead(
1048 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1049 false, true, 0, "hello!"));
1050 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231051 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1052
1053 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1054
1055 CreateSession();
1056 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1057
1058 EXPECT_FALSE(
1059 test_socket_performance_watcher_factory_.rtt_notification_received());
1060 SendRequestAndExpectQuicResponse("hello!");
1061 EXPECT_TRUE(
1062 test_socket_performance_watcher_factory_.rtt_notification_received());
1063}
1064
1065TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411066 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231067 HostPortPair::FromString("mail.example.org:443"));
1068
1069 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521070 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361071 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431072 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1073 mock_quic_data.AddWrite(
1074 SYNCHRONOUS,
1075 ConstructClientRequestHeadersPacket(
1076 2, GetNthClientInitiatedStreamId(0), true, true,
1077 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1078 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1079 1, GetNthClientInitiatedStreamId(0), false,
1080 false, GetResponseHeaders("200 OK")));
1081 mock_quic_data.AddRead(
1082 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1083 false, true, 0, "hello!"));
1084 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231085 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1086
1087 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1088
1089 CreateSession();
1090 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1091
1092 EXPECT_FALSE(
1093 test_socket_performance_watcher_factory_.rtt_notification_received());
1094 SendRequestAndExpectQuicResponse("hello!");
1095 EXPECT_FALSE(
1096 test_socket_performance_watcher_factory_.rtt_notification_received());
1097}
1098
[email protected]1e960032013-12-20 19:00:201099TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411100 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571101 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471102
[email protected]1e960032013-12-20 19:00:201103 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521104 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361105 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431106 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1107 mock_quic_data.AddWrite(
1108 SYNCHRONOUS,
1109 ConstructClientRequestHeadersPacket(
1110 2, GetNthClientInitiatedStreamId(0), true, true,
1111 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1112 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1113 1, GetNthClientInitiatedStreamId(0), false,
1114 false, GetResponseHeaders("200 OK")));
1115 mock_quic_data.AddRead(
1116 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1117 false, true, 0, "hello!"));
1118 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591119 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471120
rcha5399e02015-04-21 19:32:041121 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471122
[email protected]4dca587c2013-03-07 16:54:471123 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471124
[email protected]aa9b14d2013-05-10 23:45:191125 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471126
[email protected]98b20ce2013-05-10 05:55:261127 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461128 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191129 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261130 EXPECT_LT(0u, entries.size());
1131
1132 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291133 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001134 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1135 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261136 EXPECT_LT(0, pos);
1137
rchfd527212015-08-25 00:41:261138 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291139 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261140 entries, 0,
mikecirone8b85c432016-09-08 19:11:001141 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1142 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261143 EXPECT_LT(0, pos);
1144
rtennetia004d332015-08-28 06:44:571145 std::string packet_number;
1146 ASSERT_TRUE(entries[pos].GetStringValue("packet_number", &packet_number));
1147 EXPECT_EQ("1", packet_number);
[email protected]98b20ce2013-05-10 05:55:261148
rchfd527212015-08-25 00:41:261149 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1150 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001151 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1152 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261153 EXPECT_LT(0, pos);
1154
[email protected]98b20ce2013-05-10 05:55:261155 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291156 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001157 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1158 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261159 EXPECT_LT(0, pos);
1160
1161 int log_stream_id;
1162 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381163 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1164 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471165}
1166
rchbd089ab2017-05-26 23:05:041167TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411168 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041169 HostPortPair::FromString("mail.example.org:443"));
1170
1171 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521172 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041173 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431174 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1175 mock_quic_data.AddWrite(
1176 SYNCHRONOUS,
1177 ConstructClientRequestHeadersPacket(
1178 2, GetNthClientInitiatedStreamId(0), true, true,
1179 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131180 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041181 response_headers["key1"] = std::string(30000, 'A');
1182 response_headers["key2"] = std::string(30000, 'A');
1183 response_headers["key3"] = std::string(30000, 'A');
1184 response_headers["key4"] = std::string(30000, 'A');
1185 response_headers["key5"] = std::string(30000, 'A');
1186 response_headers["key6"] = std::string(30000, 'A');
1187 response_headers["key7"] = std::string(30000, 'A');
1188 response_headers["key8"] = std::string(30000, 'A');
Ryan Hamilton0239aac2018-05-19 00:03:131189 spdy::SpdyHeadersIR headers_frame(GetNthClientInitiatedStreamId(0),
1190 std::move(response_headers));
1191 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1192 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041193 response_framer.SerializeFrame(headers_frame);
1194
Ryan Hamilton8d9ee76e2018-05-29 23:52:521195 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041196 size_t chunk_size = 1200;
1197 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1198 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431199 mock_quic_data.AddRead(
1200 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091201 packet_number++,
1202 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521203 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041204 }
1205
1206 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:431207 ASYNC,
rchbd089ab2017-05-26 23:05:041208 ConstructServerDataPacket(packet_number, GetNthClientInitiatedStreamId(0),
1209 false, true, 0, "hello!"));
1210 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431211 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1212 mock_quic_data.AddWrite(ASYNC,
1213 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041214
1215 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1216
1217 CreateSession();
1218
1219 SendRequestAndExpectQuicResponse("hello!");
1220}
1221
1222TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481223 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411224 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041225 HostPortPair::FromString("mail.example.org:443"));
1226
1227 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521228 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041229 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431230 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1231 mock_quic_data.AddWrite(
1232 SYNCHRONOUS,
1233 ConstructClientRequestHeadersPacket(
1234 2, GetNthClientInitiatedStreamId(0), true, true,
1235 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131236 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041237 response_headers["key1"] = std::string(30000, 'A');
1238 response_headers["key2"] = std::string(30000, 'A');
1239 response_headers["key3"] = std::string(30000, 'A');
1240 response_headers["key4"] = std::string(30000, 'A');
1241 response_headers["key5"] = std::string(30000, 'A');
1242 response_headers["key6"] = std::string(30000, 'A');
1243 response_headers["key7"] = std::string(30000, 'A');
1244 response_headers["key8"] = std::string(30000, 'A');
1245 response_headers["key9"] = std::string(30000, 'A');
Ryan Hamilton0239aac2018-05-19 00:03:131246 spdy::SpdyHeadersIR headers_frame(GetNthClientInitiatedStreamId(0),
1247 std::move(response_headers));
1248 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1249 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041250 response_framer.SerializeFrame(headers_frame);
1251
Ryan Hamilton8d9ee76e2018-05-29 23:52:521252 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041253 size_t chunk_size = 1200;
1254 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1255 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431256 mock_quic_data.AddRead(
1257 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091258 packet_number++,
1259 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521260 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041261 }
1262
1263 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:431264 ASYNC,
rchbd089ab2017-05-26 23:05:041265 ConstructServerDataPacket(packet_number, GetNthClientInitiatedStreamId(0),
1266 false, true, 0, "hello!"));
1267 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431268 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1269 mock_quic_data.AddWrite(
1270 ASYNC, ConstructClientAckAndRstPacket(4, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:521271 quic::QUIC_HEADERS_TOO_LARGE,
Zhongyi Shi32f2fd02018-04-16 18:23:431272 packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041273
1274 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1275
1276 CreateSession();
1277
1278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1279 TestCompletionCallback callback;
1280 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1281 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1282 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1283}
1284
rcha2bd44b2016-07-02 00:42:551285TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411286 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551287
Ryan Hamilton9835e662018-08-02 05:36:271288 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551289
1290 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521291 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361292 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431293 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1294 mock_quic_data.AddWrite(
1295 SYNCHRONOUS,
1296 ConstructClientRequestHeadersPacket(
1297 2, GetNthClientInitiatedStreamId(0), true, true,
1298 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1299 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1300 1, GetNthClientInitiatedStreamId(0), false,
1301 false, GetResponseHeaders("200 OK")));
1302 mock_quic_data.AddRead(
1303 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1304 false, true, 0, "hello!"));
1305 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551306 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1307
1308 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1309
1310 CreateSession();
1311
1312 SendRequestAndExpectQuicResponse("hello!");
1313 EXPECT_TRUE(
1314 test_socket_performance_watcher_factory_.rtt_notification_received());
1315}
1316
[email protected]cf3e3cd62014-02-05 16:16:161317TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411318 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591319 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491320 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161321
[email protected]cf3e3cd62014-02-05 16:16:161322 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521323 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361324 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431325 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1326 mock_quic_data.AddWrite(
1327 SYNCHRONOUS,
1328 ConstructClientRequestHeadersPacket(
1329 2, GetNthClientInitiatedStreamId(0), true, true,
1330 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
1331 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1332 1, GetNthClientInitiatedStreamId(0), false,
1333 false, GetResponseHeaders("200 OK")));
1334 mock_quic_data.AddRead(
1335 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1336 false, true, 0, "hello!"));
1337 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501338 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591339 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161340
rcha5399e02015-04-21 19:32:041341 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161342
tbansal0f56a39a2016-04-07 22:03:381343 EXPECT_FALSE(
1344 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161345 // There is no need to set up an alternate protocol job, because
1346 // no attempt will be made to speak to the proxy over TCP.
1347
rch9ae5b3b2016-02-11 00:36:291348 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161349 CreateSession();
1350
bnc62a44f022015-04-02 15:59:411351 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381352 EXPECT_TRUE(
1353 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161354}
1355
bnc313ba9c2015-06-11 15:42:311356// Regression test for https://crbug.com/492458. Test that for an HTTP
1357// connection through a QUIC proxy, the certificate exhibited by the proxy is
1358// checked against the proxy hostname, not the origin hostname.
1359TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291360 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311361 const std::string proxy_host = "www.example.org";
1362
mmenke6ddfbea2017-05-31 21:48:411363 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591364 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491365 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311366
alyssar2adf3ac2016-05-03 17:12:581367 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311368 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521369 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361370 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431371 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1372 mock_quic_data.AddWrite(
1373 SYNCHRONOUS,
1374 ConstructClientRequestHeadersPacket(
1375 2, GetNthClientInitiatedStreamId(0), true, true,
1376 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
1377 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1378 1, GetNthClientInitiatedStreamId(0), false,
1379 false, GetResponseHeaders("200 OK")));
1380 mock_quic_data.AddRead(
1381 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1382 false, true, 0, "hello!"));
1383 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501384 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591385 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311386 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1387
1388 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291389 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311390 ASSERT_TRUE(cert.get());
1391 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241392 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1393 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311394 ProofVerifyDetailsChromium verify_details;
1395 verify_details.cert_verify_result.verified_cert = cert;
1396 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561397 ProofVerifyDetailsChromium verify_details2;
1398 verify_details2.cert_verify_result.verified_cert = cert;
1399 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311400
1401 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091402 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321403 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271404 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311405 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1406}
1407
rchbe69cb902016-02-11 01:10:481408TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341409 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481410 HostPortPair origin("www.example.org", 443);
1411 HostPortPair alternative("mail.example.org", 443);
1412
1413 base::FilePath certs_dir = GetTestCertsDirectory();
1414 scoped_refptr<X509Certificate> cert(
1415 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1416 ASSERT_TRUE(cert.get());
1417 // TODO(rch): the connection should be "to" the origin, so if the cert is
1418 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241419 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1420 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481421 ProofVerifyDetailsChromium verify_details;
1422 verify_details.cert_verify_result.verified_cert = cert;
1423 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1424
alyssar2adf3ac2016-05-03 17:12:581425 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481426 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521427 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361428 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431429 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1430 mock_quic_data.AddWrite(
1431 SYNCHRONOUS,
1432 ConstructClientRequestHeadersPacket(
1433 2, GetNthClientInitiatedStreamId(0), true, true,
1434 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1435 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1436 1, GetNthClientInitiatedStreamId(0), false,
1437 false, GetResponseHeaders("200 OK")));
1438 mock_quic_data.AddRead(
1439 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1440 false, true, 0, "hello!"));
1441 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481442 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1443 mock_quic_data.AddRead(ASYNC, 0);
1444 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1445
1446 request_.url = GURL("https://" + origin.host());
1447 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271448 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091449 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321450 CreateSession();
rchbe69cb902016-02-11 01:10:481451
1452 SendRequestAndExpectQuicResponse("hello!");
1453}
1454
zhongyief3f4ce52017-07-05 23:53:281455TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521456 quic::QuicTransportVersion unsupported_version =
1457 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281458 // Add support for another QUIC version besides |version_|. Also find a
1459 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521460 for (const quic::QuicTransportVersion& version :
1461 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281462 if (version == version_)
1463 continue;
1464 if (supported_versions_.size() != 2) {
1465 supported_versions_.push_back(version);
1466 continue;
1467 }
1468 unsupported_version = version;
1469 break;
1470 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521471 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281472
1473 // Set up alternative service to use QUIC with a version that is not
1474 // supported.
1475 url::SchemeHostPort server(request_.url);
1476 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1477 443);
1478 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1479 http_server_properties_.SetQuicAlternativeService(
1480 server, alternative_service, expiration, {unsupported_version});
1481
1482 AlternativeServiceInfoVector alt_svc_info_vector =
1483 http_server_properties_.GetAlternativeServiceInfos(server);
1484 EXPECT_EQ(1u, alt_svc_info_vector.size());
1485 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1486 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1487 EXPECT_EQ(unsupported_version,
1488 alt_svc_info_vector[0].advertised_versions()[0]);
1489
1490 // First request should still be sent via TCP as the QUIC version advertised
1491 // in the stored AlternativeService is not supported by the client. However,
1492 // the response from the server will advertise new Alt-Svc with supported
1493 // versions.
1494 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521495 GenerateQuicVersionsListForAltSvcHeader(
1496 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281497 std::string altsvc_header =
1498 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1499 advertised_versions_list_str.c_str());
1500 MockRead http_reads[] = {
1501 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1502 MockRead("hello world"),
1503 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1504 MockRead(ASYNC, OK)};
1505
Ryan Sleevib8d7ea02018-05-07 20:01:011506 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281507 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081508 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281509 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1510
1511 // Second request should be sent via QUIC as a new list of verions supported
1512 // by the client has been advertised by the server.
1513 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521514 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281515 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431516 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1517 mock_quic_data.AddWrite(
1518 SYNCHRONOUS,
1519 ConstructClientRequestHeadersPacket(
1520 2, GetNthClientInitiatedStreamId(0), true, true,
1521 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1522 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1523 1, GetNthClientInitiatedStreamId(0), false,
1524 false, GetResponseHeaders("200 OK")));
1525 mock_quic_data.AddRead(
1526 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1527 false, true, 0, "hello!"));
1528 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281529 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1530 mock_quic_data.AddRead(ASYNC, 0); // EOF
1531
1532 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1533
1534 AddHangingNonAlternateProtocolSocketData();
1535
1536 CreateSession(supported_versions_);
1537
1538 SendRequestAndExpectHttpResponse("hello world");
1539 SendRequestAndExpectQuicResponse("hello!");
1540
1541 // Check alternative service list is updated with new versions.
1542 alt_svc_info_vector =
1543 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1544 EXPECT_EQ(1u, alt_svc_info_vector.size());
1545 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1546 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1547 // Advertised versions will be lised in a sorted order.
1548 std::sort(supported_versions_.begin(), supported_versions_.end());
1549 EXPECT_EQ(supported_versions_[0],
1550 alt_svc_info_vector[0].advertised_versions()[0]);
1551 EXPECT_EQ(supported_versions_[1],
1552 alt_svc_info_vector[0].advertised_versions()[1]);
1553}
1554
bncaccd4962017-04-06 21:00:261555// Regression test for https://crbug.com/546991.
1556// The server might not be able to serve a request on an alternative connection,
1557// and might send a 421 Misdirected Request response status to indicate this.
1558// HttpNetworkTransaction should reset the request and retry without using
1559// alternative services.
1560TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1561 // Set up alternative service to use QUIC.
1562 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1563 // that overrides |enable_alternative_services|.
1564 url::SchemeHostPort server(request_.url);
1565 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1566 443);
1567 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211568 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441569 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261570
davidbena4449722017-05-05 23:30:531571 // First try: The alternative job uses QUIC and reports an HTTP 421
1572 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1573 // paused at Connect(), so it will never exit the socket pool. This ensures
1574 // that the alternate job always wins the race and keeps whether the
1575 // |http_data| exits the socket pool before the main job is aborted
1576 // deterministic. The first main job gets aborted without the socket pool ever
1577 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261578 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521579 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361580 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431581 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1582 mock_quic_data.AddWrite(
1583 SYNCHRONOUS,
1584 ConstructClientRequestHeadersPacket(
1585 2, GetNthClientInitiatedStreamId(0), true, true,
1586 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
1587 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1588 1, GetNthClientInitiatedStreamId(0), false,
1589 true, GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261590 mock_quic_data.AddRead(ASYNC, OK);
1591 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1592
davidbena4449722017-05-05 23:30:531593 // Second try: The main job uses TCP, and there is no alternate job. Once the
1594 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1595 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261596 // Note that if there was an alternative QUIC Job created for the second try,
1597 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1598 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531599 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1600 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1601 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1602 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1603 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1604 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011605 reads, writes);
bncaccd4962017-04-06 21:00:261606 socket_factory_.AddSocketDataProvider(&http_data);
1607 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1608
bncaccd4962017-04-06 21:00:261609 CreateSession();
1610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531611
1612 // Run until |mock_quic_data| has failed and |http_data| has paused.
1613 TestCompletionCallback callback;
1614 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1615 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1616 base::RunLoop().RunUntilIdle();
1617
1618 // |mock_quic_data| must have run to completion.
1619 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1620 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1621
1622 // Now that the QUIC data has been consumed, unblock |http_data|.
1623 http_data.socket()->OnConnectComplete(MockConnect());
1624
1625 // The retry logic must hide the 421 status. The transaction succeeds on
1626 // |http_data|.
1627 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261628 CheckWasHttpResponse(&trans);
1629 CheckResponsePort(&trans, 443);
1630 CheckResponseData(&trans, "hello!");
1631}
1632
[email protected]1e960032013-12-20 19:00:201633TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411634 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571635 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301636
tbansalfdf5665b2015-09-21 22:46:401637 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521638 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361639 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431640 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401641 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401642 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371643 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361644 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431645 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301646 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401647 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431648 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401649
1650 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1651 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301652
1653 CreateSession();
1654
tbansal0f56a39a2016-04-07 22:03:381655 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401656 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161657 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401658 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161659 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011660 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1661 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381662 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531663
1664 NetErrorDetails details;
1665 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521666 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401667 }
[email protected]cebe3282013-05-22 23:49:301668}
1669
tbansalc8a94ea2015-11-02 23:58:511670TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1671 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411672 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571673 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511674
1675 MockRead http_reads[] = {
1676 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1677 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1678 MockRead(ASYNC, OK)};
1679
Ryan Sleevib8d7ea02018-05-07 20:01:011680 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511681 socket_factory_.AddSocketDataProvider(&data);
1682 SSLSocketDataProvider ssl(ASYNC, OK);
1683 socket_factory_.AddSSLSocketDataProvider(&ssl);
1684
1685 CreateSession();
1686
1687 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381688 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511689}
1690
bncc958faa2015-07-31 18:14:521691TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521692 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561693 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1694 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521695 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1696 MockRead(ASYNC, OK)};
1697
Ryan Sleevib8d7ea02018-05-07 20:01:011698 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521699 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081700 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561701 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521702
1703 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521704 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361705 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431706 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1707 mock_quic_data.AddWrite(
1708 SYNCHRONOUS,
1709 ConstructClientRequestHeadersPacket(
1710 2, GetNthClientInitiatedStreamId(0), true, true,
1711 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1712 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1713 1, GetNthClientInitiatedStreamId(0), false,
1714 false, GetResponseHeaders("200 OK")));
1715 mock_quic_data.AddRead(
1716 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1717 false, true, 0, "hello!"));
1718 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521719 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591720 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521721
1722 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1723
rtennetib8e80fb2016-05-16 00:12:091724 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321725 CreateSession();
bncc958faa2015-07-31 18:14:521726
1727 SendRequestAndExpectHttpResponse("hello world");
1728 SendRequestAndExpectQuicResponse("hello!");
1729}
1730
zhongyia00ca012017-07-06 23:36:391731TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1732 // Both server advertises and client supports two QUIC versions.
1733 // Only |version_| is advertised and supported.
1734 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1735 // PacketMakers are using |version_|.
1736
1737 // Add support for another QUIC version besides |version_| on the client side.
1738 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521739 quic::QuicTransportVersion advertised_version_2 =
1740 quic::QUIC_VERSION_UNSUPPORTED;
1741 for (const quic::QuicTransportVersion& version :
1742 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391743 if (version == version_)
1744 continue;
1745 if (supported_versions_.size() != 2) {
1746 supported_versions_.push_back(version);
1747 continue;
1748 }
1749 advertised_version_2 = version;
1750 break;
1751 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521752 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391753
1754 std::string QuicAltSvcWithVersionHeader =
1755 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1756 advertised_version_2, version_);
1757
1758 MockRead http_reads[] = {
1759 MockRead("HTTP/1.1 200 OK\r\n"),
1760 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1761 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1762 MockRead(ASYNC, OK)};
1763
Ryan Sleevib8d7ea02018-05-07 20:01:011764 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391765 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081766 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391767 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1768
1769 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521770 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391771 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431772 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1773 mock_quic_data.AddWrite(
1774 SYNCHRONOUS,
1775 ConstructClientRequestHeadersPacket(
1776 2, GetNthClientInitiatedStreamId(0), true, true,
1777 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1778 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1779 1, GetNthClientInitiatedStreamId(0), false,
1780 false, GetResponseHeaders("200 OK")));
1781 mock_quic_data.AddRead(
1782 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1783 false, true, 0, "hello!"));
1784 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391785 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1786 mock_quic_data.AddRead(ASYNC, 0); // EOF
1787
1788 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1789
1790 AddHangingNonAlternateProtocolSocketData();
1791 CreateSession(supported_versions_);
1792
1793 SendRequestAndExpectHttpResponse("hello world");
1794 SendRequestAndExpectQuicResponse("hello!");
1795}
1796
1797TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1798 // Client and server mutually support more than one QUIC_VERSION.
1799 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1800 // which is verified as the PacketMakers are using |version_|.
1801
Ryan Hamilton8d9ee76e2018-05-29 23:52:521802 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1803 for (const quic::QuicTransportVersion& version :
1804 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391805 if (version == version_)
1806 continue;
1807 common_version_2 = version;
1808 break;
1809 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521810 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391811
1812 supported_versions_.push_back(
1813 common_version_2); // Supported but unpreferred.
1814
1815 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1816 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1817
1818 MockRead http_reads[] = {
1819 MockRead("HTTP/1.1 200 OK\r\n"),
1820 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1821 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1822 MockRead(ASYNC, OK)};
1823
Ryan Sleevib8d7ea02018-05-07 20:01:011824 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391825 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081826 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391827 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1828
1829 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521830 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391831 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431832 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1833 mock_quic_data.AddWrite(
1834 SYNCHRONOUS,
1835 ConstructClientRequestHeadersPacket(
1836 2, GetNthClientInitiatedStreamId(0), true, true,
1837 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1838 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1839 1, GetNthClientInitiatedStreamId(0), false,
1840 false, GetResponseHeaders("200 OK")));
1841 mock_quic_data.AddRead(
1842 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1843 false, true, 0, "hello!"));
1844 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391845 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1846 mock_quic_data.AddRead(ASYNC, 0); // EOF
1847
1848 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1849
1850 AddHangingNonAlternateProtocolSocketData();
1851 CreateSession(supported_versions_);
1852
1853 SendRequestAndExpectHttpResponse("hello world");
1854 SendRequestAndExpectQuicResponse("hello!");
1855}
1856
rchf47265dc2016-03-21 21:33:121857TEST_P(QuicNetworkTransactionTest,
1858 UseAlternativeServiceWithProbabilityForQuic) {
1859 MockRead http_reads[] = {
1860 MockRead("HTTP/1.1 200 OK\r\n"),
1861 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1862 MockRead("hello world"),
1863 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1864 MockRead(ASYNC, OK)};
1865
Ryan Sleevib8d7ea02018-05-07 20:01:011866 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121867 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081868 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121869 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1870
1871 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521872 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361873 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431874 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1875 mock_quic_data.AddWrite(
1876 SYNCHRONOUS,
1877 ConstructClientRequestHeadersPacket(
1878 2, GetNthClientInitiatedStreamId(0), true, true,
1879 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1880 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
1881 1, GetNthClientInitiatedStreamId(0), false,
1882 false, GetResponseHeaders("200 OK")));
1883 mock_quic_data.AddRead(
1884 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
1885 false, true, 0, "hello!"));
1886 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121887 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1888 mock_quic_data.AddRead(ASYNC, 0); // EOF
1889
1890 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1891
rtennetib8e80fb2016-05-16 00:12:091892 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121893 CreateSession();
1894
1895 SendRequestAndExpectHttpResponse("hello world");
1896 SendRequestAndExpectQuicResponse("hello!");
1897}
1898
zhongyi3d4a55e72016-04-22 20:36:461899TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1900 MockRead http_reads[] = {
1901 MockRead("HTTP/1.1 200 OK\r\n"),
1902 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1903 MockRead("hello world"),
1904 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1905 MockRead(ASYNC, OK)};
1906
Ryan Sleevib8d7ea02018-05-07 20:01:011907 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461908 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081909 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461910 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1911
1912 CreateSession();
bncb26024382016-06-29 02:39:451913 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461914 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451915 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:461916 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401917 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461918 session_->http_server_properties();
1919 url::SchemeHostPort http_server("http", "mail.example.org", 443);
1920 url::SchemeHostPort https_server("https", "mail.example.org", 443);
1921 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:461922 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:341923 2u,
1924 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:451925 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:341926 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:461927}
1928
1929TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
1930 MockRead http_reads[] = {
1931 MockRead("HTTP/1.1 200 OK\r\n"),
1932 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1933 MockRead("hello world"),
1934 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1935 MockRead(ASYNC, OK)};
1936
Ryan Sleevib8d7ea02018-05-07 20:01:011937 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:081938 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461939
1940 socket_factory_.AddSocketDataProvider(&http_data);
1941 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1942 socket_factory_.AddSocketDataProvider(&http_data);
1943 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1944
1945 CreateSession();
1946
1947 // Send https request and set alternative services if response header
1948 // advertises alternative service for mail.example.org.
1949 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401950 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461951 session_->http_server_properties();
1952
1953 const url::SchemeHostPort https_server(request_.url);
1954 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:341955 EXPECT_EQ(
1956 2u,
1957 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:461958
1959 // Send http request to the same origin but with diffrent scheme, should not
1960 // use QUIC.
1961 request_.url = GURL("http://mail.example.org:443");
1962 SendRequestAndExpectHttpResponse("hello world");
1963}
1964
zhongyie537a002017-06-27 16:48:211965TEST_P(QuicNetworkTransactionTest,
1966 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:441967 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521968 for (const quic::QuicTransportVersion& version :
1969 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:441970 if (version == version_)
1971 continue;
1972 supported_versions_.push_back(version);
1973 break;
1974 }
1975
zhongyie537a002017-06-27 16:48:211976 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521977 GenerateQuicVersionsListForAltSvcHeader(
1978 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:211979 std::string altsvc_header =
1980 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1981 advertised_versions_list_str.c_str());
1982 MockRead http_reads[] = {
1983 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1984 MockRead("hello world"),
1985 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1986 MockRead(ASYNC, OK)};
1987
Ryan Sleevib8d7ea02018-05-07 20:01:011988 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:211989 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081990 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:211991 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1992
1993 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521994 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:211995 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431996 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1997 mock_quic_data.AddWrite(
1998 SYNCHRONOUS,
1999 ConstructClientRequestHeadersPacket(
2000 2, GetNthClientInitiatedStreamId(0), true, true,
2001 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2002 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2003 1, GetNthClientInitiatedStreamId(0), false,
2004 false, GetResponseHeaders("200 OK")));
2005 mock_quic_data.AddRead(
2006 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
2007 false, true, 0, "hello!"));
2008 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212009 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2010 mock_quic_data.AddRead(ASYNC, 0); // EOF
2011
2012 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2013
2014 AddHangingNonAlternateProtocolSocketData();
2015
zhongyi86838d52017-06-30 01:19:442016 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212017
2018 SendRequestAndExpectHttpResponse("hello world");
2019 SendRequestAndExpectQuicResponse("hello!");
2020
2021 // Check alternative service is set with only mutually supported versions.
2022 const url::SchemeHostPort https_server(request_.url);
2023 const AlternativeServiceInfoVector alt_svc_info_vector =
2024 session_->http_server_properties()->GetAlternativeServiceInfos(
2025 https_server);
2026 EXPECT_EQ(1u, alt_svc_info_vector.size());
2027 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2028 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2029 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442030 std::sort(supported_versions_.begin(), supported_versions_.end());
2031 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212032 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442033 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212034 alt_svc_info_vector[0].advertised_versions()[1]);
2035}
2036
danzh3134c2562016-08-12 14:07:522037TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442038 std::string altsvc_header =
2039 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072040 MockRead http_reads[] = {
2041 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2042 MockRead("hello world"),
2043 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2044 MockRead(ASYNC, OK)};
2045
Ryan Sleevib8d7ea02018-05-07 20:01:012046 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072047 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082048 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072049 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2050
2051 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522052 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362053 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432054 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2055 mock_quic_data.AddWrite(
2056 SYNCHRONOUS,
2057 ConstructClientRequestHeadersPacket(
2058 2, GetNthClientInitiatedStreamId(0), true, true,
2059 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2060 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2061 1, GetNthClientInitiatedStreamId(0), false,
2062 false, GetResponseHeaders("200 OK")));
2063 mock_quic_data.AddRead(
2064 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
2065 false, true, 0, "hello!"));
2066 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072067 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592068 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072069
2070 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2071
rtennetib8e80fb2016-05-16 00:12:092072 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322073 CreateSession();
bnc8be55ebb2015-10-30 14:12:072074
2075 SendRequestAndExpectHttpResponse("hello world");
2076 SendRequestAndExpectQuicResponse("hello!");
2077}
2078
zhongyi6b5a3892016-03-12 04:46:202079TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092080 if (version_ == quic::QUIC_VERSION_99) {
2081 // Not available under version 99
2082 return;
2083 }
zhongyi6b5a3892016-03-12 04:46:202084 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522085 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362086 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432087 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2088 mock_quic_data.AddWrite(
2089 SYNCHRONOUS,
2090 ConstructClientRequestHeadersPacket(
2091 2, GetNthClientInitiatedStreamId(0), true, true,
2092 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2093 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2094 1, GetNthClientInitiatedStreamId(0), false,
2095 false, GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202096 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522097 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432098 mock_quic_data.AddRead(SYNCHRONOUS,
2099 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522100 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432101 "connection migration with port change only"));
2102 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
2103 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
2104 3, GetNthClientInitiatedStreamId(0),
2105 false, true, 0, "hello!"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522106 mock_quic_data.AddWrite(
2107 SYNCHRONOUS,
2108 ConstructClientAckAndRstPacket(4, GetNthClientInitiatedStreamId(0),
2109 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202110 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2111 mock_quic_data.AddRead(ASYNC, 0); // EOF
2112
2113 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2114
2115 // The non-alternate protocol job needs to hang in order to guarantee that
2116 // the alternate-protocol job will "win".
2117 AddHangingNonAlternateProtocolSocketData();
2118
2119 // In order for a new QUIC session to be established via alternate-protocol
2120 // without racing an HTTP connection, we need the host resolution to happen
2121 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2122 // connection to the the server, in this test we require confirmation
2123 // before encrypting so the HTTP job will still start.
2124 host_resolver_.set_synchronous_mode(true);
2125 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2126 "");
2127 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2128 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102129 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582130 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2131 CompletionOnceCallback(), &request,
2132 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412133 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202134
2135 CreateSession();
2136 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272137 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202138
bnc691fda62016-08-12 00:43:162139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202140 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412141 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202143
2144 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522145 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012146 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202147
2148 // Check whether this transaction is correctly marked as received a go-away
2149 // because of migrating port.
2150 NetErrorDetails details;
2151 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162152 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202153 EXPECT_TRUE(details.quic_port_migration_detected);
2154}
2155
Zhongyi Shia6b68d112018-09-24 07:49:032156// This test verifies that a new QUIC connection will be attempted on the
2157// alternate network if the original QUIC connection fails with idle timeout
2158// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2159// alternate network as well, QUIC is marked as broken and the brokenness will
2160// not expire when default network changes.
2161TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2162 SetUpTestForRetryConnectionOnAlternateNetwork();
2163
2164 std::string request_data;
2165 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2166 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2167
2168 // The request will initially go out over QUIC.
2169 MockQuicData quic_data;
2170 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2171 int packet_num = 1;
2172 quic_data.AddWrite(SYNCHRONOUS,
2173 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2174 // Retranmit the handshake messages.
2175 quic_data.AddWrite(SYNCHRONOUS,
2176 client_maker_.MakeDummyCHLOPacket(packet_num++));
2177 quic_data.AddWrite(SYNCHRONOUS,
2178 client_maker_.MakeDummyCHLOPacket(packet_num++));
2179 quic_data.AddWrite(SYNCHRONOUS,
2180 client_maker_.MakeDummyCHLOPacket(packet_num++));
2181 quic_data.AddWrite(SYNCHRONOUS,
2182 client_maker_.MakeDummyCHLOPacket(packet_num++));
2183 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2184 if (version_ <= quic::QUIC_VERSION_39) {
2185 quic_data.AddWrite(SYNCHRONOUS,
2186 client_maker_.MakeDummyCHLOPacket(packet_num++));
2187 }
2188 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2189 quic_data.AddWrite(SYNCHRONOUS,
2190 client_maker_.MakeConnectionClosePacket(
2191 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2192 "No recent network activity."));
2193 quic_data.AddSocketDataToFactory(&socket_factory_);
2194
2195 // Add successful TCP data so that TCP job will succeed.
2196 MockWrite http_writes[] = {
2197 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2198 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2199 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2200
2201 MockRead http_reads[] = {
2202 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2203 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2204 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2205 SequencedSocketData http_data(http_reads, http_writes);
2206 socket_factory_.AddSocketDataProvider(&http_data);
2207 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2208
2209 // Add data for the second QUIC connection to fail.
2210 MockQuicData quic_data2;
2211 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2212 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2213 quic_data2.AddSocketDataToFactory(&socket_factory_);
2214
2215 // Resolve the host resolution synchronously.
2216 host_resolver_.set_synchronous_mode(true);
2217 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2218 "");
2219 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2220 AddressList address;
2221 std::unique_ptr<HostResolver::Request> request;
2222 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2223 CompletionOnceCallback(), &request,
2224 net_log_.bound());
2225 EXPECT_THAT(rv, IsOk());
2226
2227 CreateSession();
2228 session_->quic_stream_factory()->set_require_confirmation(true);
2229 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2230 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2231 QuicStreamFactoryPeer::SetAlarmFactory(
2232 session_->quic_stream_factory(),
2233 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2234 &clock_));
2235 // Add alternate protocol mapping to race QUIC and TCP.
2236 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2237 // peer.
2238 AddQuicAlternateProtocolMapping(
2239 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2240
2241 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2242 TestCompletionCallback callback;
2243 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2244 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2245
2246 // Pump the message loop to get the request started.
2247 // Request will be served with TCP job.
2248 base::RunLoop().RunUntilIdle();
2249 EXPECT_THAT(callback.WaitForResult(), IsOk());
2250 CheckResponseData(&trans, "TCP succeeds");
2251
2252 // Fire the retransmission alarm, from this point, connection will idle
2253 // timeout after 4 seconds.
Zhongyi Shia15736c2018-09-25 00:31:182254 if (!quic::GetQuicReloadableFlag(
2255 quic_fix_time_of_first_packet_sent_after_receiving)) {
2256 quic_task_runner_->RunNextTask();
2257 }
Zhongyi Shia6b68d112018-09-24 07:49:032258 // Fast forward to idle timeout the original connection. A new connection will
2259 // be kicked off on the alternate network.
2260 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2261 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2262 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2263
2264 // Run the message loop to execute posted tasks, which will report job status.
2265 base::RunLoop().RunUntilIdle();
2266
2267 // Verify that QUIC is marked as broken.
2268 ExpectBrokenAlternateProtocolMapping();
2269
2270 // Deliver a message to notify the new network becomes default, the brokenness
2271 // will not expire as QUIC is broken on both networks.
2272 scoped_mock_change_notifier_->mock_network_change_notifier()
2273 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2274 ExpectBrokenAlternateProtocolMapping();
2275
2276 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2277 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2278}
2279
2280// This test verifies that a new QUIC connection will be attempted on the
2281// alternate network if the original QUIC connection fails with idle timeout
2282// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2283// alternate network, QUIC is marked as broken. The brokenness will expire when
2284// the default network changes.
2285TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2286 SetUpTestForRetryConnectionOnAlternateNetwork();
2287
2288 std::string request_data;
2289 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2290 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2291
2292 // The request will initially go out over QUIC.
2293 MockQuicData quic_data;
2294 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2295 int packet_num = 1;
2296 quic_data.AddWrite(SYNCHRONOUS,
2297 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2298 // Retranmit the handshake messages.
2299 quic_data.AddWrite(SYNCHRONOUS,
2300 client_maker_.MakeDummyCHLOPacket(packet_num++));
2301 quic_data.AddWrite(SYNCHRONOUS,
2302 client_maker_.MakeDummyCHLOPacket(packet_num++));
2303 quic_data.AddWrite(SYNCHRONOUS,
2304 client_maker_.MakeDummyCHLOPacket(packet_num++));
2305 quic_data.AddWrite(SYNCHRONOUS,
2306 client_maker_.MakeDummyCHLOPacket(packet_num++));
2307 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2308 if (version_ <= quic::QUIC_VERSION_39) {
2309 quic_data.AddWrite(SYNCHRONOUS,
2310 client_maker_.MakeDummyCHLOPacket(packet_num++));
2311 }
2312 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2313 quic_data.AddWrite(SYNCHRONOUS,
2314 client_maker_.MakeConnectionClosePacket(
2315 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2316 "No recent network activity."));
2317 quic_data.AddSocketDataToFactory(&socket_factory_);
2318
2319 // Add successful TCP data so that TCP job will succeed.
2320 MockWrite http_writes[] = {
2321 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2322 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2323 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2324
2325 MockRead http_reads[] = {
2326 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2327 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2328 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2329 SequencedSocketData http_data(http_reads, http_writes);
2330 socket_factory_.AddSocketDataProvider(&http_data);
2331 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2332
2333 // Quic connection will be retried on the alternate network after the initial
2334 // one fails on the default network.
2335 MockQuicData quic_data2;
2336 quic::QuicStreamOffset header_stream_offset = 0;
2337 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2338 quic_data2.AddWrite(SYNCHRONOUS,
2339 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2340
2341 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2342 quic_data2.AddWrite(SYNCHRONOUS,
2343 ConstructInitialSettingsPacket(2, &header_stream_offset));
2344 quic_data2.AddSocketDataToFactory(&socket_factory_);
2345
2346 // Resolve the host resolution synchronously.
2347 host_resolver_.set_synchronous_mode(true);
2348 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2349 "");
2350 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2351 AddressList address;
2352 std::unique_ptr<HostResolver::Request> request;
2353 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2354 CompletionOnceCallback(), &request,
2355 net_log_.bound());
2356 EXPECT_THAT(rv, IsOk());
2357
2358 CreateSession();
2359 session_->quic_stream_factory()->set_require_confirmation(true);
2360 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2361 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2362 QuicStreamFactoryPeer::SetAlarmFactory(
2363 session_->quic_stream_factory(),
2364 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2365 &clock_));
2366 // Add alternate protocol mapping to race QUIC and TCP.
2367 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2368 // peer.
2369 AddQuicAlternateProtocolMapping(
2370 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2371
2372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2373 TestCompletionCallback callback;
2374 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2376
2377 // Pump the message loop to get the request started.
2378 // Request will be served with TCP job.
2379 base::RunLoop().RunUntilIdle();
2380 EXPECT_THAT(callback.WaitForResult(), IsOk());
2381 CheckResponseData(&trans, "TCP succeeds");
2382
2383 // Fire the retransmission alarm, after which connection will idle
2384 // timeout after 4 seconds.
Zhongyi Shia15736c2018-09-25 00:31:182385 if (!quic::GetQuicReloadableFlag(
2386 quic_fix_time_of_first_packet_sent_after_receiving)) {
2387 quic_task_runner_->RunNextTask();
2388 }
Zhongyi Shia6b68d112018-09-24 07:49:032389 // Fast forward to idle timeout the original connection. A new connection will
2390 // be kicked off on the alternate network.
2391 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2392 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2393 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2394
2395 // The second connection hasn't finish handshake, verify that QUIC is not
2396 // marked as broken.
2397 ExpectQuicAlternateProtocolMapping();
2398 // Explicitly confirm the handshake on the second connection.
2399 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2400 quic::QuicSession::HANDSHAKE_CONFIRMED);
2401 // Run message loop to execute posted tasks, which will notify JoController
2402 // about the orphaned job status.
2403 base::RunLoop().RunUntilIdle();
2404
2405 // Verify that QUIC is marked as broken.
2406 ExpectBrokenAlternateProtocolMapping();
2407
2408 // Deliver a message to notify the new network becomes default, the previous
2409 // brokenness will be clear as the brokenness is bond with old default
2410 // network.
2411 scoped_mock_change_notifier_->mock_network_change_notifier()
2412 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2413 ExpectQuicAlternateProtocolMapping();
2414
2415 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2416 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2417}
2418
2419// This test verifies that a new QUIC connection will be attempted on the
2420// alternate network if the original QUIC connection fails with idle timeout
2421// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2422// alternative network succeeds, QUIC is not marked as broken.
2423TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2424 SetUpTestForRetryConnectionOnAlternateNetwork();
2425
2426 std::string request_data;
2427 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2428 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2429
2430 // The request will initially go out over QUIC.
2431 MockQuicData quic_data;
2432 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2433 int packet_num = 1;
2434 quic_data.AddWrite(SYNCHRONOUS,
2435 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2436 // Retranmit the handshake messages.
2437 quic_data.AddWrite(SYNCHRONOUS,
2438 client_maker_.MakeDummyCHLOPacket(packet_num++));
2439 quic_data.AddWrite(SYNCHRONOUS,
2440 client_maker_.MakeDummyCHLOPacket(packet_num++));
2441 quic_data.AddWrite(SYNCHRONOUS,
2442 client_maker_.MakeDummyCHLOPacket(packet_num++));
2443 quic_data.AddWrite(SYNCHRONOUS,
2444 client_maker_.MakeDummyCHLOPacket(packet_num++));
2445 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2446 // quic_fix_has_pending_crypto_data is introduced and enabled.
2447 if (version_ <= quic::QUIC_VERSION_39) {
2448 quic_data.AddWrite(SYNCHRONOUS,
2449 client_maker_.MakeDummyCHLOPacket(packet_num++));
2450 }
2451 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2452 quic_data.AddWrite(SYNCHRONOUS,
2453 client_maker_.MakeConnectionClosePacket(
2454 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2455 "No recent network activity."));
2456 quic_data.AddSocketDataToFactory(&socket_factory_);
2457
2458 // Add hanging TCP data so that TCP job will never succeeded.
2459 AddHangingNonAlternateProtocolSocketData();
2460
2461 // Quic connection will then be retried on the alternate network.
2462 MockQuicData quic_data2;
2463 quic::QuicStreamOffset header_stream_offset = 0;
2464 quic_data2.AddWrite(SYNCHRONOUS,
2465 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2466
2467 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2468 quic_data2.AddWrite(SYNCHRONOUS,
2469 ConstructInitialSettingsPacket(2, &header_stream_offset));
2470 quic_data2.AddWrite(
2471 SYNCHRONOUS,
2472 ConstructClientRequestHeadersPacket(
2473 3, GetNthClientInitiatedStreamId(0), true, true,
2474 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2475 quic_data2.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
2476 1, GetNthClientInitiatedStreamId(0), false,
2477 false, GetResponseHeaders("200 OK")));
2478 quic_data2.AddRead(
2479 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
2480 false, true, 0, "hello!"));
2481 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2482 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2483 quic_data2.AddSocketDataToFactory(&socket_factory_);
2484
2485 // Resolve the host resolution synchronously.
2486 host_resolver_.set_synchronous_mode(true);
2487 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2488 "");
2489 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2490 AddressList address;
2491 std::unique_ptr<HostResolver::Request> request;
2492 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2493 CompletionOnceCallback(), &request,
2494 net_log_.bound());
2495 EXPECT_THAT(rv, IsOk());
2496
2497 CreateSession();
2498 session_->quic_stream_factory()->set_require_confirmation(true);
2499 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2500 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2501 QuicStreamFactoryPeer::SetAlarmFactory(
2502 session_->quic_stream_factory(),
2503 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2504 &clock_));
2505 // Add alternate protocol mapping to race QUIC and TCP.
2506 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2507 // peer.
2508 AddQuicAlternateProtocolMapping(
2509 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2510
2511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2512 TestCompletionCallback callback;
2513 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2514 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2515
2516 // Pump the message loop to get the request started.
2517 base::RunLoop().RunUntilIdle();
Zhongyi Shia15736c2018-09-25 00:31:182518 if (!quic::GetQuicReloadableFlag(
2519 quic_fix_time_of_first_packet_sent_after_receiving)) {
2520 quic_task_runner_->RunNextTask();
2521 }
Zhongyi Shia6b68d112018-09-24 07:49:032522
2523 // Fast forward to idle timeout the original connection. A new connection will
2524 // be kicked off on the alternate network.
2525 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2526 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2527 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2528
2529 // Verify that QUIC is not marked as broken.
2530 ExpectQuicAlternateProtocolMapping();
2531 // Explicitly confirm the handshake on the second connection.
2532 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2533 quic::QuicSession::HANDSHAKE_CONFIRMED);
2534
2535 // Read the response.
2536 EXPECT_THAT(callback.WaitForResult(), IsOk());
2537 CheckResponseData(&trans, "hello!");
2538 // Verify that QUIC is not marked as broken.
2539 ExpectQuicAlternateProtocolMapping();
2540
2541 // Deliver a message to notify the new network becomes default.
2542 scoped_mock_change_notifier_->mock_network_change_notifier()
2543 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2544 ExpectQuicAlternateProtocolMapping();
2545 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2546 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2547}
2548
rch9ecde09b2017-04-08 00:18:232549// Verify that if a QUIC connection times out, the QuicHttpStream will
2550// return QUIC_PROTOCOL_ERROR.
2551TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482552 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412553 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232554
2555 // The request will initially go out over QUIC.
2556 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522557 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132558 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232559 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2560
2561 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522562 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2563 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432564 quic_data.AddWrite(SYNCHRONOUS,
2565 client_maker_.MakeRequestHeadersPacketAndSaveData(
2566 1, GetNthClientInitiatedStreamId(0), true, true,
2567 priority, GetRequestHeaders("GET", "https", "/"), 0,
2568 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232569
2570 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522571 quic::QuicStreamOffset settings_offset = header_stream_offset;
2572 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432573 quic_data.AddWrite(SYNCHRONOUS,
2574 client_maker_.MakeInitialSettingsPacketAndSaveData(
2575 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232576 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092577 quic_data.AddWrite(SYNCHRONOUS,
2578 client_maker_.MakeDataPacket(
2579 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2580 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232581 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092582 quic_data.AddWrite(SYNCHRONOUS,
2583 client_maker_.MakeDataPacket(
2584 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2585 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232586 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092587 quic_data.AddWrite(SYNCHRONOUS,
2588 client_maker_.MakeDataPacket(
2589 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2590 false, 0, request_data));
2591 quic_data.AddWrite(SYNCHRONOUS,
2592 client_maker_.MakeDataPacket(
2593 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2594 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232595 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092596 quic_data.AddWrite(SYNCHRONOUS,
2597 client_maker_.MakeDataPacket(
2598 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2599 false, 0, request_data));
2600 quic_data.AddWrite(SYNCHRONOUS,
2601 client_maker_.MakeDataPacket(
2602 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2603 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232604 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092605 quic_data.AddWrite(SYNCHRONOUS,
2606 client_maker_.MakeDataPacket(
2607 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2608 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522609 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092610 SYNCHRONOUS, client_maker_.MakeDataPacket(
2611 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2612 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232613
Zhongyi Shi32f2fd02018-04-16 18:23:432614 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522615 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432616 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222617
rch9ecde09b2017-04-08 00:18:232618 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2619 quic_data.AddRead(ASYNC, OK);
2620 quic_data.AddSocketDataToFactory(&socket_factory_);
2621
2622 // In order for a new QUIC session to be established via alternate-protocol
2623 // without racing an HTTP connection, we need the host resolution to happen
2624 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2625 // connection to the the server, in this test we require confirmation
2626 // before encrypting so the HTTP job will still start.
2627 host_resolver_.set_synchronous_mode(true);
2628 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2629 "");
2630 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2631 AddressList address;
2632 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582633 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2634 CompletionOnceCallback(), &request,
2635 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412636 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232637
2638 CreateSession();
2639 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552640 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232641 QuicStreamFactoryPeer::SetAlarmFactory(
2642 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192643 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552644 &clock_));
rch9ecde09b2017-04-08 00:18:232645
Ryan Hamilton9835e662018-08-02 05:36:272646 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232647
2648 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2649 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412650 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2652
2653 // Pump the message loop to get the request started.
2654 base::RunLoop().RunUntilIdle();
2655 // Explicitly confirm the handshake.
2656 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522657 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232658
2659 // Run the QUIC session to completion.
2660 quic_task_runner_->RunUntilIdle();
2661
2662 ExpectQuicAlternateProtocolMapping();
2663 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2664 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2665}
2666
2667// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2668// return QUIC_PROTOCOL_ERROR.
2669TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482670 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522671 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232672
2673 // The request will initially go out over QUIC.
2674 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522675 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132676 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232677 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2678
2679 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522680 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2681 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432682 quic_data.AddWrite(SYNCHRONOUS,
2683 client_maker_.MakeRequestHeadersPacketAndSaveData(
2684 1, GetNthClientInitiatedStreamId(0), true, true,
2685 priority, GetRequestHeaders("GET", "https", "/"), 0,
2686 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232687
2688 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522689 quic::QuicStreamOffset settings_offset = header_stream_offset;
2690 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432691 quic_data.AddWrite(SYNCHRONOUS,
2692 client_maker_.MakeInitialSettingsPacketAndSaveData(
2693 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232694 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092695 quic_data.AddWrite(SYNCHRONOUS,
2696 client_maker_.MakeDataPacket(
2697 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2698 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232699 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092700 quic_data.AddWrite(SYNCHRONOUS,
2701 client_maker_.MakeDataPacket(
2702 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2703 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232704 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092705 quic_data.AddWrite(SYNCHRONOUS,
2706 client_maker_.MakeDataPacket(
2707 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2708 false, 0, request_data));
2709 quic_data.AddWrite(SYNCHRONOUS,
2710 client_maker_.MakeDataPacket(
2711 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2712 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232713 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092714 quic_data.AddWrite(SYNCHRONOUS,
2715 client_maker_.MakeDataPacket(
2716 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2717 false, 0, request_data));
2718 quic_data.AddWrite(SYNCHRONOUS,
2719 client_maker_.MakeDataPacket(
2720 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2721 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232722 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092723 quic_data.AddWrite(SYNCHRONOUS,
2724 client_maker_.MakeDataPacket(
2725 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2726 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522727 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092728 SYNCHRONOUS, client_maker_.MakeDataPacket(
2729 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2730 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232731 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522732 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092733 SYNCHRONOUS, client_maker_.MakeDataPacket(
2734 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2735 false, 0, request_data));
2736 quic_data.AddWrite(
2737 SYNCHRONOUS, client_maker_.MakeDataPacket(
2738 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2739 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232740 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432741 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522742 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432743 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232744
2745 quic_data.AddRead(ASYNC, OK);
2746 quic_data.AddSocketDataToFactory(&socket_factory_);
2747
2748 // In order for a new QUIC session to be established via alternate-protocol
2749 // without racing an HTTP connection, we need the host resolution to happen
2750 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2751 // connection to the the server, in this test we require confirmation
2752 // before encrypting so the HTTP job will still start.
2753 host_resolver_.set_synchronous_mode(true);
2754 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2755 "");
2756 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2757 AddressList address;
2758 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582759 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2760 CompletionOnceCallback(), &request,
2761 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412762 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232763
2764 CreateSession();
2765 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552766 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232767 QuicStreamFactoryPeer::SetAlarmFactory(
2768 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192769 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552770 &clock_));
rch9ecde09b2017-04-08 00:18:232771
Ryan Hamilton9835e662018-08-02 05:36:272772 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232773
2774 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2775 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412776 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2778
2779 // Pump the message loop to get the request started.
2780 base::RunLoop().RunUntilIdle();
2781 // Explicitly confirm the handshake.
2782 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522783 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232784
2785 // Run the QUIC session to completion.
2786 quic_task_runner_->RunUntilIdle();
2787
2788 ExpectQuicAlternateProtocolMapping();
2789 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2790 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2791}
2792
2793// Verify that if a QUIC connection RTOs, while there are no active streams
2794// QUIC will not be marked as broken.
2795TEST_P(QuicNetworkTransactionTest,
2796 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522797 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232798
2799 // The request will initially go out over QUIC.
2800 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522801 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132802 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232803 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2804
2805 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522806 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2807 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432808 quic_data.AddWrite(SYNCHRONOUS,
2809 client_maker_.MakeRequestHeadersPacketAndSaveData(
2810 1, GetNthClientInitiatedStreamId(0), true, true,
2811 priority, GetRequestHeaders("GET", "https", "/"), 0,
2812 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232813
2814 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522815 quic::QuicStreamOffset settings_offset = header_stream_offset;
2816 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432817 quic_data.AddWrite(SYNCHRONOUS,
2818 client_maker_.MakeInitialSettingsPacketAndSaveData(
2819 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232820
Zhongyi Shi32f2fd02018-04-16 18:23:432821 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2822 3, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522823 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232824 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092825 quic_data.AddWrite(SYNCHRONOUS,
2826 client_maker_.MakeDataPacket(
2827 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2828 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232829 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092830 quic_data.AddWrite(SYNCHRONOUS,
2831 client_maker_.MakeDataPacket(
2832 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2833 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232834 // RTO 1
Zhongyi Shi32f2fd02018-04-16 18:23:432835 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2836 6, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522837 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092838 quic_data.AddWrite(SYNCHRONOUS,
2839 client_maker_.MakeDataPacket(
2840 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2841 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232842 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092843 quic_data.AddWrite(SYNCHRONOUS,
2844 client_maker_.MakeDataPacket(
2845 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2846 false, settings_offset, settings_data));
Zhongyi Shi32f2fd02018-04-16 18:23:432847 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
2848 9, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522849 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232850 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522851 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092852 SYNCHRONOUS, client_maker_.MakeDataPacket(
2853 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2854 false, 0, request_data));
2855 quic_data.AddWrite(
2856 SYNCHRONOUS, client_maker_.MakeDataPacket(
2857 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2858 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232859 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432860 quic_data.AddWrite(
2861 SYNCHRONOUS,
2862 client_maker_.MakeRstPacket(12, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:522863 quic::QUIC_STREAM_CANCELLED));
2864 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092865 SYNCHRONOUS, client_maker_.MakeDataPacket(
2866 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2867 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232868 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432869 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522870 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432871 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232872
2873 quic_data.AddRead(ASYNC, OK);
2874 quic_data.AddSocketDataToFactory(&socket_factory_);
2875
2876 // In order for a new QUIC session to be established via alternate-protocol
2877 // without racing an HTTP connection, we need the host resolution to happen
2878 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2879 // connection to the the server, in this test we require confirmation
2880 // before encrypting so the HTTP job will still start.
2881 host_resolver_.set_synchronous_mode(true);
2882 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2883 "");
2884 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2885 AddressList address;
2886 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582887 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2888 CompletionOnceCallback(), &request,
2889 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412890 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232891
2892 CreateSession();
2893 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552894 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232895 QuicStreamFactoryPeer::SetAlarmFactory(
2896 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192897 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552898 &clock_));
rch9ecde09b2017-04-08 00:18:232899
Ryan Hamilton9835e662018-08-02 05:36:272900 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232901
Jeremy Roman0579ed62017-08-29 15:56:192902 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232903 session_.get());
2904 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412905 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2907
2908 // Pump the message loop to get the request started.
2909 base::RunLoop().RunUntilIdle();
2910 // Explicitly confirm the handshake.
2911 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522912 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232913
2914 // Now cancel the request.
2915 trans.reset();
2916
2917 // Run the QUIC session to completion.
2918 quic_task_runner_->RunUntilIdle();
2919
2920 ExpectQuicAlternateProtocolMapping();
2921
2922 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2923}
2924
rch2f2991c2017-04-13 19:28:172925// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2926// the request fails with QUIC_PROTOCOL_ERROR.
2927TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482928 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172929 // The request will initially go out over QUIC.
2930 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522931 quic::QuicStreamOffset header_stream_offset = 0;
2932 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2933 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432934 quic_data.AddWrite(
2935 SYNCHRONOUS,
2936 ConstructClientRequestHeadersPacket(
2937 1, GetNthClientInitiatedStreamId(0), true, true,
2938 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522939 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432940 quic_data.AddWrite(SYNCHRONOUS,
2941 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:172942 // Peer sending data from an non-existing stream causes this end to raise
2943 // error and close connection.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522944 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
Fan Yang7c68f632018-11-06 03:05:382945 1, false, GetNthClientInitiatedStreamId(47),
2946 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172947 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:432948 quic_data.AddWrite(SYNCHRONOUS,
2949 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522950 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
2951 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:172952 quic_data.AddSocketDataToFactory(&socket_factory_);
2953
2954 // In order for a new QUIC session to be established via alternate-protocol
2955 // without racing an HTTP connection, we need the host resolution to happen
2956 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2957 // connection to the the server, in this test we require confirmation
2958 // before encrypting so the HTTP job will still start.
2959 host_resolver_.set_synchronous_mode(true);
2960 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2961 "");
2962 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2963 AddressList address;
2964 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582965 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2966 CompletionOnceCallback(), &request,
2967 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412968 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:172969
2970 CreateSession();
2971
Ryan Hamilton9835e662018-08-02 05:36:272972 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:172973
2974 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2975 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412976 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:172977 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2978
2979 // Pump the message loop to get the request started.
2980 base::RunLoop().RunUntilIdle();
2981 // Explicitly confirm the handshake.
2982 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522983 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:172984
2985 ASSERT_FALSE(quic_data.AllReadDataConsumed());
2986
2987 // Run the QUIC session to completion.
2988 base::RunLoop().RunUntilIdle();
2989 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2990 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2991
2992 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2993 ExpectQuicAlternateProtocolMapping();
2994 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2995}
2996
rch9ecde09b2017-04-08 00:18:232997// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
2998// connection times out, then QUIC will be marked as broken and the request
2999// retried over TCP.
3000TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413001 session_params_.mark_quic_broken_when_network_blackholes = true;
3002 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233003
3004 // The request will initially go out over QUIC.
3005 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523006 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133007 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233008 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3009
3010 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523011 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3012 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433013 quic_data.AddWrite(SYNCHRONOUS,
3014 client_maker_.MakeRequestHeadersPacketAndSaveData(
3015 1, GetNthClientInitiatedStreamId(0), true, true,
3016 priority, GetRequestHeaders("GET", "https", "/"), 0,
3017 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233018
3019 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523020 quic::QuicStreamOffset settings_offset = header_stream_offset;
3021 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433022 quic_data.AddWrite(SYNCHRONOUS,
3023 client_maker_.MakeInitialSettingsPacketAndSaveData(
3024 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233025 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093026 quic_data.AddWrite(SYNCHRONOUS,
3027 client_maker_.MakeDataPacket(
3028 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3029 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233030 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093031 quic_data.AddWrite(SYNCHRONOUS,
3032 client_maker_.MakeDataPacket(
3033 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3034 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233035 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093036 quic_data.AddWrite(SYNCHRONOUS,
3037 client_maker_.MakeDataPacket(
3038 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3039 false, 0, request_data));
3040 quic_data.AddWrite(SYNCHRONOUS,
3041 client_maker_.MakeDataPacket(
3042 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3043 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233044 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093045 quic_data.AddWrite(SYNCHRONOUS,
3046 client_maker_.MakeDataPacket(
3047 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3048 false, 0, request_data));
3049 quic_data.AddWrite(SYNCHRONOUS,
3050 client_maker_.MakeDataPacket(
3051 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3052 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233053 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093054 quic_data.AddWrite(SYNCHRONOUS,
3055 client_maker_.MakeDataPacket(
3056 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3057 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523058 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093059 SYNCHRONOUS, client_maker_.MakeDataPacket(
3060 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3061 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233062
Zhongyi Shi32f2fd02018-04-16 18:23:433063 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523064 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433065 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223066
rch9ecde09b2017-04-08 00:18:233067 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3068 quic_data.AddRead(ASYNC, OK);
3069 quic_data.AddSocketDataToFactory(&socket_factory_);
3070
3071 // After that fails, it will be resent via TCP.
3072 MockWrite http_writes[] = {
3073 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3074 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3075 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3076
3077 MockRead http_reads[] = {
3078 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3079 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3080 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013081 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233082 socket_factory_.AddSocketDataProvider(&http_data);
3083 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3084
3085 // In order for a new QUIC session to be established via alternate-protocol
3086 // without racing an HTTP connection, we need the host resolution to happen
3087 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3088 // connection to the the server, in this test we require confirmation
3089 // before encrypting so the HTTP job will still start.
3090 host_resolver_.set_synchronous_mode(true);
3091 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3092 "");
3093 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3094 AddressList address;
3095 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583096 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3097 CompletionOnceCallback(), &request,
3098 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413099 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233100
3101 CreateSession();
3102 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553103 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233104 QuicStreamFactoryPeer::SetAlarmFactory(
3105 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193106 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553107 &clock_));
rch9ecde09b2017-04-08 00:18:233108
Ryan Hamilton9835e662018-08-02 05:36:273109 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233110
3111 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3112 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413113 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3115
3116 // Pump the message loop to get the request started.
3117 base::RunLoop().RunUntilIdle();
3118 // Explicitly confirm the handshake.
3119 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523120 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233121
3122 // Run the QUIC session to completion.
3123 quic_task_runner_->RunUntilIdle();
3124 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3125
3126 // Let the transaction proceed which will result in QUIC being marked
3127 // as broken and the request falling back to TCP.
3128 EXPECT_THAT(callback.WaitForResult(), IsOk());
3129
3130 ExpectBrokenAlternateProtocolMapping();
3131 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3132 ASSERT_FALSE(http_data.AllReadDataConsumed());
3133
3134 // Read the response body over TCP.
3135 CheckResponseData(&trans, "hello world");
3136 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3137 ASSERT_TRUE(http_data.AllReadDataConsumed());
3138}
3139
rch2f2991c2017-04-13 19:28:173140// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3141// connection times out, then QUIC will be marked as broken and the request
3142// retried over TCP.
3143TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413144 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173145
3146 // The request will initially go out over QUIC.
3147 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523148 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133149 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173150 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3151
3152 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523153 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3154 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433155 quic_data.AddWrite(SYNCHRONOUS,
3156 client_maker_.MakeRequestHeadersPacketAndSaveData(
3157 1, GetNthClientInitiatedStreamId(0), true, true,
3158 priority, GetRequestHeaders("GET", "https", "/"), 0,
3159 nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173160
3161 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523162 quic::QuicStreamOffset settings_offset = header_stream_offset;
3163 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433164 quic_data.AddWrite(SYNCHRONOUS,
3165 client_maker_.MakeInitialSettingsPacketAndSaveData(
3166 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173167 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093168 quic_data.AddWrite(SYNCHRONOUS,
3169 client_maker_.MakeDataPacket(
3170 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3171 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173172 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093173 quic_data.AddWrite(SYNCHRONOUS,
3174 client_maker_.MakeDataPacket(
3175 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3176 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173177 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093178 quic_data.AddWrite(SYNCHRONOUS,
3179 client_maker_.MakeDataPacket(
3180 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3181 false, 0, request_data));
3182 quic_data.AddWrite(SYNCHRONOUS,
3183 client_maker_.MakeDataPacket(
3184 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3185 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173186 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093187 quic_data.AddWrite(SYNCHRONOUS,
3188 client_maker_.MakeDataPacket(
3189 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3190 false, 0, request_data));
3191 quic_data.AddWrite(SYNCHRONOUS,
3192 client_maker_.MakeDataPacket(
3193 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3194 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173195 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093196 quic_data.AddWrite(SYNCHRONOUS,
3197 client_maker_.MakeDataPacket(
3198 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3199 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523200 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093201 SYNCHRONOUS, client_maker_.MakeDataPacket(
3202 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3203 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173204
Zhongyi Shi32f2fd02018-04-16 18:23:433205 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523206 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433207 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223208
rch2f2991c2017-04-13 19:28:173209 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3210 quic_data.AddRead(ASYNC, OK);
3211 quic_data.AddSocketDataToFactory(&socket_factory_);
3212
3213 // After that fails, it will be resent via TCP.
3214 MockWrite http_writes[] = {
3215 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3216 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3217 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3218
3219 MockRead http_reads[] = {
3220 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3221 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3222 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013223 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173224 socket_factory_.AddSocketDataProvider(&http_data);
3225 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3226
3227 // In order for a new QUIC session to be established via alternate-protocol
3228 // without racing an HTTP connection, we need the host resolution to happen
3229 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3230 // connection to the the server, in this test we require confirmation
3231 // before encrypting so the HTTP job will still start.
3232 host_resolver_.set_synchronous_mode(true);
3233 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3234 "");
3235 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3236 AddressList address;
3237 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583238 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3239 CompletionOnceCallback(), &request,
3240 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413241 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173242
3243 CreateSession();
3244 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553245 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173246 QuicStreamFactoryPeer::SetAlarmFactory(
3247 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193248 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553249 &clock_));
rch2f2991c2017-04-13 19:28:173250
Ryan Hamilton9835e662018-08-02 05:36:273251 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173252
3253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3254 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413255 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173256 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3257
3258 // Pump the message loop to get the request started.
3259 base::RunLoop().RunUntilIdle();
3260 // Explicitly confirm the handshake.
3261 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523262 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173263
3264 // Run the QUIC session to completion.
3265 quic_task_runner_->RunUntilIdle();
3266 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3267
3268 ExpectQuicAlternateProtocolMapping();
3269
3270 // Let the transaction proceed which will result in QUIC being marked
3271 // as broken and the request falling back to TCP.
3272 EXPECT_THAT(callback.WaitForResult(), IsOk());
3273
3274 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3275 ASSERT_FALSE(http_data.AllReadDataConsumed());
3276
3277 // Read the response body over TCP.
3278 CheckResponseData(&trans, "hello world");
3279 ExpectBrokenAlternateProtocolMapping();
3280 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3281 ASSERT_TRUE(http_data.AllReadDataConsumed());
3282}
3283
rch9ecde09b2017-04-08 00:18:233284// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3285// connection times out, then QUIC will be marked as broken but the request
3286// will not be retried over TCP.
3287TEST_P(QuicNetworkTransactionTest,
3288 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413289 session_params_.mark_quic_broken_when_network_blackholes = true;
3290 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233291
3292 // The request will initially go out over QUIC.
3293 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523294 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133295 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233296 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3297
3298 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523299 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3300 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433301 quic_data.AddWrite(SYNCHRONOUS,
3302 client_maker_.MakeRequestHeadersPacketAndSaveData(
3303 1, GetNthClientInitiatedStreamId(0), true, true,
3304 priority, GetRequestHeaders("GET", "https", "/"), 0,
3305 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233306
3307 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523308 quic::QuicStreamOffset settings_offset = header_stream_offset;
3309 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433310 quic_data.AddWrite(SYNCHRONOUS,
3311 client_maker_.MakeInitialSettingsPacketAndSaveData(
3312 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233313
Zhongyi Shi32f2fd02018-04-16 18:23:433314 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
3315 1, GetNthClientInitiatedStreamId(0), false,
3316 false, GetResponseHeaders("200 OK")));
3317 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523318 quic_data.AddWrite(
3319 SYNCHRONOUS,
3320 ConstructClientAckPacket(3, 1, 1, 1,
3321 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233322
3323 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523324 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093325 SYNCHRONOUS, client_maker_.MakeDataPacket(
3326 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3327 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233328 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093329 quic_data.AddWrite(
3330 SYNCHRONOUS, client_maker_.MakeDataPacket(
3331 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3332 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233333 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523334 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093335 SYNCHRONOUS, client_maker_.MakeDataPacket(
3336 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3337 false, 0, request_data));
3338 quic_data.AddWrite(
3339 SYNCHRONOUS, client_maker_.MakeDataPacket(
3340 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3341 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233342 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523343 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093344 SYNCHRONOUS, client_maker_.MakeDataPacket(
3345 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3346 false, 0, request_data));
3347 quic_data.AddWrite(
3348 SYNCHRONOUS, client_maker_.MakeDataPacket(
3349 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3350 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233351 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523352 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093353 SYNCHRONOUS, client_maker_.MakeDataPacket(
3354 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3355 false, 0, request_data));
3356 quic_data.AddWrite(
3357 SYNCHRONOUS, client_maker_.MakeDataPacket(
3358 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3359 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233360
Zhongyi Shia15736c2018-09-25 00:31:183361 if (quic::GetQuicReloadableFlag(
3362 quic_fix_time_of_first_packet_sent_after_receiving)) {
3363 quic_data.AddWrite(
3364 SYNCHRONOUS,
3365 client_maker_.MakeAckAndConnectionClosePacket(
3366 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3367 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3368
3369 } else {
3370 quic_data.AddWrite(
3371 SYNCHRONOUS,
3372 client_maker_.MakeAckAndConnectionClosePacket(
3373 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3374 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3375 }
Fan Yang928f1632017-12-14 18:55:223376
rch9ecde09b2017-04-08 00:18:233377 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3378 quic_data.AddRead(ASYNC, OK);
3379 quic_data.AddSocketDataToFactory(&socket_factory_);
3380
3381 // In order for a new QUIC session to be established via alternate-protocol
3382 // without racing an HTTP connection, we need the host resolution to happen
3383 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3384 // connection to the the server, in this test we require confirmation
3385 // before encrypting so the HTTP job will still start.
3386 host_resolver_.set_synchronous_mode(true);
3387 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3388 "");
3389 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3390 AddressList address;
3391 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583392 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3393 CompletionOnceCallback(), &request,
3394 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413395 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233396
3397 CreateSession();
3398 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553399 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233400 QuicStreamFactoryPeer::SetAlarmFactory(
3401 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193402 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553403 &clock_));
rch9ecde09b2017-04-08 00:18:233404
Ryan Hamilton9835e662018-08-02 05:36:273405 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233406
3407 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3408 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413409 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233410 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3411
3412 // Pump the message loop to get the request started.
3413 base::RunLoop().RunUntilIdle();
3414 // Explicitly confirm the handshake.
3415 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523416 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233417
3418 // Pump the message loop to get the request started.
3419 base::RunLoop().RunUntilIdle();
3420
3421 // Run the QUIC session to completion.
3422 quic_task_runner_->RunUntilIdle();
3423 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3424
3425 // Let the transaction proceed which will result in QUIC being marked
3426 // as broken and the request falling back to TCP.
3427 EXPECT_THAT(callback.WaitForResult(), IsOk());
3428
3429 ExpectBrokenAlternateProtocolMapping();
3430 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3431
3432 std::string response_data;
3433 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3434 IsError(ERR_QUIC_PROTOCOL_ERROR));
3435}
3436
3437// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3438// connection RTOs, then QUIC will be marked as broken and the request retried
3439// over TCP.
3440TEST_P(QuicNetworkTransactionTest,
3441 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413442 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523443 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233444
3445 // The request will initially go out over QUIC.
3446 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523447 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133448 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233449 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3450
3451 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523452 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3453 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433454 quic_data.AddWrite(SYNCHRONOUS,
3455 client_maker_.MakeRequestHeadersPacketAndSaveData(
3456 1, GetNthClientInitiatedStreamId(0), true, true,
3457 priority, GetRequestHeaders("GET", "https", "/"), 0,
3458 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233459
3460 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523461 quic::QuicStreamOffset settings_offset = header_stream_offset;
3462 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433463 quic_data.AddWrite(SYNCHRONOUS,
3464 client_maker_.MakeInitialSettingsPacketAndSaveData(
3465 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233466 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093467 quic_data.AddWrite(SYNCHRONOUS,
3468 client_maker_.MakeDataPacket(
3469 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3470 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233471 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093472 quic_data.AddWrite(SYNCHRONOUS,
3473 client_maker_.MakeDataPacket(
3474 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3475 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233476 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093477 quic_data.AddWrite(SYNCHRONOUS,
3478 client_maker_.MakeDataPacket(
3479 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3480 false, 0, request_data));
3481 quic_data.AddWrite(SYNCHRONOUS,
3482 client_maker_.MakeDataPacket(
3483 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3484 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233485 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093486 quic_data.AddWrite(SYNCHRONOUS,
3487 client_maker_.MakeDataPacket(
3488 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3489 false, 0, request_data));
3490 quic_data.AddWrite(SYNCHRONOUS,
3491 client_maker_.MakeDataPacket(
3492 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3493 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233494 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093495 quic_data.AddWrite(SYNCHRONOUS,
3496 client_maker_.MakeDataPacket(
3497 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3498 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523499 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093500 SYNCHRONOUS, client_maker_.MakeDataPacket(
3501 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3502 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233503 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523504 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093505 SYNCHRONOUS, client_maker_.MakeDataPacket(
3506 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3507 false, 0, request_data));
3508 quic_data.AddWrite(
3509 SYNCHRONOUS, client_maker_.MakeDataPacket(
3510 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3511 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233512
Zhongyi Shi32f2fd02018-04-16 18:23:433513 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523514 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433515 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233516
3517 quic_data.AddRead(ASYNC, OK);
3518 quic_data.AddSocketDataToFactory(&socket_factory_);
3519
3520 // After that fails, it will be resent via TCP.
3521 MockWrite http_writes[] = {
3522 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3523 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3524 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3525
3526 MockRead http_reads[] = {
3527 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3528 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3529 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013530 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233531 socket_factory_.AddSocketDataProvider(&http_data);
3532 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3533
3534 // In order for a new QUIC session to be established via alternate-protocol
3535 // without racing an HTTP connection, we need the host resolution to happen
3536 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3537 // connection to the the server, in this test we require confirmation
3538 // before encrypting so the HTTP job will still start.
3539 host_resolver_.set_synchronous_mode(true);
3540 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3541 "");
3542 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3543 AddressList address;
3544 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583545 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3546 CompletionOnceCallback(), &request,
3547 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413548 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233549
3550 CreateSession();
3551 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553552 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233553 QuicStreamFactoryPeer::SetAlarmFactory(
3554 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193555 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553556 &clock_));
rch9ecde09b2017-04-08 00:18:233557
Ryan Hamilton9835e662018-08-02 05:36:273558 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233559
3560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3561 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413562 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3564
3565 // Pump the message loop to get the request started.
3566 base::RunLoop().RunUntilIdle();
3567 // Explicitly confirm the handshake.
3568 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523569 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233570
3571 // Run the QUIC session to completion.
3572 quic_task_runner_->RunUntilIdle();
3573 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3574
3575 // Let the transaction proceed which will result in QUIC being marked
3576 // as broken and the request falling back to TCP.
3577 EXPECT_THAT(callback.WaitForResult(), IsOk());
3578
3579 ExpectBrokenAlternateProtocolMapping();
3580 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3581 ASSERT_FALSE(http_data.AllReadDataConsumed());
3582
3583 // Read the response body over TCP.
3584 CheckResponseData(&trans, "hello world");
3585 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3586 ASSERT_TRUE(http_data.AllReadDataConsumed());
3587}
3588
3589// Verify that if a QUIC connection RTOs, while there are no active streams
3590// QUIC will be marked as broken.
3591TEST_P(QuicNetworkTransactionTest,
3592 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413593 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523594 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233595
3596 // The request will initially go out over QUIC.
3597 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523598 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133599 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233600 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3601
3602 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523603 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3604 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433605 quic_data.AddWrite(SYNCHRONOUS,
3606 client_maker_.MakeRequestHeadersPacketAndSaveData(
3607 1, GetNthClientInitiatedStreamId(0), true, true,
3608 priority, GetRequestHeaders("GET", "https", "/"), 0,
3609 nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233610
3611 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523612 quic::QuicStreamOffset settings_offset = header_stream_offset;
3613 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433614 quic_data.AddWrite(SYNCHRONOUS,
3615 client_maker_.MakeInitialSettingsPacketAndSaveData(
3616 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233617
Zhongyi Shi32f2fd02018-04-16 18:23:433618 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3619 3, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523620 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233621 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093622 quic_data.AddWrite(SYNCHRONOUS,
3623 client_maker_.MakeDataPacket(
3624 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3625 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233626 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093627 quic_data.AddWrite(SYNCHRONOUS,
3628 client_maker_.MakeDataPacket(
3629 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3630 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233631 // RTO 1
Zhongyi Shi32f2fd02018-04-16 18:23:433632 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3633 6, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523634 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093635 quic_data.AddWrite(SYNCHRONOUS,
3636 client_maker_.MakeDataPacket(
3637 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3638 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233639 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093640 quic_data.AddWrite(SYNCHRONOUS,
3641 client_maker_.MakeDataPacket(
3642 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3643 false, settings_offset, settings_data));
Zhongyi Shi32f2fd02018-04-16 18:23:433644 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeRstPacket(
3645 9, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523646 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233647 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523648 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093649 SYNCHRONOUS, client_maker_.MakeDataPacket(
3650 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3651 false, 0, request_data));
3652 quic_data.AddWrite(
3653 SYNCHRONOUS, client_maker_.MakeDataPacket(
3654 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3655 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233656 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433657 quic_data.AddWrite(
3658 SYNCHRONOUS,
3659 client_maker_.MakeRstPacket(12, true, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523660 quic::QUIC_STREAM_CANCELLED));
3661 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093662 SYNCHRONOUS, client_maker_.MakeDataPacket(
3663 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3664 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233665 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433666 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523667 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433668 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233669
3670 quic_data.AddRead(ASYNC, OK);
3671 quic_data.AddSocketDataToFactory(&socket_factory_);
3672
3673 // In order for a new QUIC session to be established via alternate-protocol
3674 // without racing an HTTP connection, we need the host resolution to happen
3675 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3676 // connection to the the server, in this test we require confirmation
3677 // before encrypting so the HTTP job will still start.
3678 host_resolver_.set_synchronous_mode(true);
3679 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3680 "");
3681 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3682 AddressList address;
3683 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583684 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3685 CompletionOnceCallback(), &request,
3686 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413687 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233688
3689 CreateSession();
3690 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553691 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233692 QuicStreamFactoryPeer::SetAlarmFactory(
3693 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193694 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553695 &clock_));
rch9ecde09b2017-04-08 00:18:233696
Ryan Hamilton9835e662018-08-02 05:36:273697 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233698
Jeremy Roman0579ed62017-08-29 15:56:193699 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233700 session_.get());
3701 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413702 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3704
3705 // Pump the message loop to get the request started.
3706 base::RunLoop().RunUntilIdle();
3707 // Explicitly confirm the handshake.
3708 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523709 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233710
3711 // Now cancel the request.
3712 trans.reset();
3713
3714 // Run the QUIC session to completion.
3715 quic_task_runner_->RunUntilIdle();
3716
3717 ExpectBrokenAlternateProtocolMapping();
3718
3719 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3720}
3721
rch2f2991c2017-04-13 19:28:173722// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3723// protocol error occurs after the handshake is confirmed, the request
3724// retried over TCP and the QUIC will be marked as broken.
3725TEST_P(QuicNetworkTransactionTest,
3726 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413727 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173728
3729 // The request will initially go out over QUIC.
3730 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523731 quic::QuicStreamOffset header_stream_offset = 0;
3732 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3733 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433734 quic_data.AddWrite(
3735 SYNCHRONOUS,
3736 ConstructClientRequestHeadersPacket(
3737 1, GetNthClientInitiatedStreamId(0), true, true,
3738 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523739 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433740 quic_data.AddWrite(SYNCHRONOUS,
3741 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173742 // Peer sending data from an non-existing stream causes this end to raise
3743 // error and close connection.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523744 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
Fan Yang7c68f632018-11-06 03:05:383745 1, false, GetNthClientInitiatedStreamId(47),
3746 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173747 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433748 quic_data.AddWrite(SYNCHRONOUS,
3749 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523750 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3751 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173752 quic_data.AddSocketDataToFactory(&socket_factory_);
3753
3754 // After that fails, it will be resent via TCP.
3755 MockWrite http_writes[] = {
3756 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3757 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3758 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3759
3760 MockRead http_reads[] = {
3761 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3762 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3763 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013764 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173765 socket_factory_.AddSocketDataProvider(&http_data);
3766 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3767
3768 // In order for a new QUIC session to be established via alternate-protocol
3769 // without racing an HTTP connection, we need the host resolution to happen
3770 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3771 // connection to the the server, in this test we require confirmation
3772 // before encrypting so the HTTP job will still start.
3773 host_resolver_.set_synchronous_mode(true);
3774 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3775 "");
3776 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3777 AddressList address;
3778 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583779 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3780 CompletionOnceCallback(), &request,
3781 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413782 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173783
3784 CreateSession();
3785
Ryan Hamilton9835e662018-08-02 05:36:273786 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173787
3788 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3789 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413790 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173791 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3792
3793 // Pump the message loop to get the request started.
3794 base::RunLoop().RunUntilIdle();
3795 // Explicitly confirm the handshake.
3796 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523797 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173798
3799 // Run the QUIC session to completion.
3800 base::RunLoop().RunUntilIdle();
3801 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3802
3803 ExpectQuicAlternateProtocolMapping();
3804
3805 // Let the transaction proceed which will result in QUIC being marked
3806 // as broken and the request falling back to TCP.
3807 EXPECT_THAT(callback.WaitForResult(), IsOk());
3808
3809 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3810 ASSERT_FALSE(http_data.AllReadDataConsumed());
3811
3812 // Read the response body over TCP.
3813 CheckResponseData(&trans, "hello world");
3814 ExpectBrokenAlternateProtocolMapping();
3815 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3816 ASSERT_TRUE(http_data.AllReadDataConsumed());
3817}
3818
rch30943ee2017-06-12 21:28:443819// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3820// request is reset from, then QUIC will be marked as broken and the request
3821// retried over TCP.
3822TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443823 // The request will initially go out over QUIC.
3824 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523825 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133826 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443827 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3828
3829 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523830 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3831 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433832 quic_data.AddWrite(SYNCHRONOUS,
3833 client_maker_.MakeRequestHeadersPacketAndSaveData(
3834 1, GetNthClientInitiatedStreamId(0), true, true,
3835 priority, GetRequestHeaders("GET", "https", "/"), 0,
3836 nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443837
3838 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523839 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3840 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433841 quic_data.AddWrite(SYNCHRONOUS,
3842 client_maker_.MakeInitialSettingsPacketAndSaveData(
3843 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443844
Zhongyi Shi32f2fd02018-04-16 18:23:433845 quic_data.AddRead(ASYNC, ConstructServerRstPacket(
3846 1, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:523847 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443848
3849 quic_data.AddRead(ASYNC, OK);
3850 quic_data.AddSocketDataToFactory(&socket_factory_);
3851
3852 // After that fails, it will be resent via TCP.
3853 MockWrite http_writes[] = {
3854 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3855 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3856 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3857
3858 MockRead http_reads[] = {
3859 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3860 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3861 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013862 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443863 socket_factory_.AddSocketDataProvider(&http_data);
3864 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3865
3866 // In order for a new QUIC session to be established via alternate-protocol
3867 // without racing an HTTP connection, we need the host resolution to happen
3868 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3869 // connection to the the server, in this test we require confirmation
3870 // before encrypting so the HTTP job will still start.
3871 host_resolver_.set_synchronous_mode(true);
3872 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3873 "");
3874 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3875 AddressList address;
3876 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583877 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3878 CompletionOnceCallback(), &request,
3879 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413880 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443881
3882 CreateSession();
3883
Ryan Hamilton9835e662018-08-02 05:36:273884 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443885
3886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3887 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413888 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3890
3891 // Pump the message loop to get the request started.
3892 base::RunLoop().RunUntilIdle();
3893 // Explicitly confirm the handshake.
3894 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523895 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443896
3897 // Run the QUIC session to completion.
3898 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3899
3900 ExpectQuicAlternateProtocolMapping();
3901
3902 // Let the transaction proceed which will result in QUIC being marked
3903 // as broken and the request falling back to TCP.
3904 EXPECT_THAT(callback.WaitForResult(), IsOk());
3905
3906 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3907 ASSERT_FALSE(http_data.AllReadDataConsumed());
3908
3909 // Read the response body over TCP.
3910 CheckResponseData(&trans, "hello world");
3911 ExpectBrokenAlternateProtocolMapping();
3912 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3913 ASSERT_TRUE(http_data.AllReadDataConsumed());
3914}
3915
Ryan Hamilton6c2a2a82017-12-15 02:06:283916// Verify that when an origin has two alt-svc advertisements, one local and one
3917// remote, that when the local is broken the request will go over QUIC via
3918// the remote Alt-Svc.
3919// This is a regression test for crbug/825646.
3920TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3921 session_params_.quic_allow_remote_alt_svc = true;
3922
3923 GURL origin1 = request_.url; // mail.example.org
3924 GURL origin2("https://www.example.org/");
3925 ASSERT_NE(origin1.host(), origin2.host());
3926
3927 scoped_refptr<X509Certificate> cert(
3928 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243929 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3930 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283931
3932 ProofVerifyDetailsChromium verify_details;
3933 verify_details.cert_verify_result.verified_cert = cert;
3934 verify_details.cert_verify_result.is_issued_by_known_root = true;
3935 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3936
3937 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523938 quic::QuicStreamOffset request_header_offset(0);
3939 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283940 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433941 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3942 mock_quic_data.AddWrite(
3943 SYNCHRONOUS,
3944 ConstructClientRequestHeadersPacket(
3945 2, GetNthClientInitiatedStreamId(0), true, true,
3946 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3947 mock_quic_data.AddRead(
3948 ASYNC, ConstructServerResponseHeadersPacket(
3949 1, GetNthClientInitiatedStreamId(0), false, false,
3950 GetResponseHeaders("200 OK"), &response_header_offset));
3951 mock_quic_data.AddRead(
3952 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
3953 false, true, 0, "hello!"));
3954 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:283955 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
3956 mock_quic_data.AddRead(ASYNC, 0); // EOF
3957
3958 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
3959 MockQuicData mock_quic_data2;
3960 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
3961 AddHangingNonAlternateProtocolSocketData();
3962
3963 CreateSession();
3964
3965 // Set up alternative service for |origin1|.
3966 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
3967 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
3968 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
3969 AlternativeServiceInfoVector alternative_services;
3970 alternative_services.push_back(
3971 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3972 local_alternative, expiration,
3973 session_->params().quic_supported_versions));
3974 alternative_services.push_back(
3975 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
3976 remote_alternative, expiration,
3977 session_->params().quic_supported_versions));
3978 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
3979 alternative_services);
3980
3981 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
3982
3983 SendRequestAndExpectQuicResponse("hello!");
3984}
3985
rch30943ee2017-06-12 21:28:443986// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3987// request is reset from, then QUIC will be marked as broken and the request
3988// retried over TCP. Then, subsequent requests will go over a new QUIC
3989// connection instead of going back to the broken QUIC connection.
3990// This is a regression tests for crbug/731303.
3991TEST_P(QuicNetworkTransactionTest,
3992 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:343993 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:443994
3995 GURL origin1 = request_.url;
3996 GURL origin2("https://www.example.org/");
3997 ASSERT_NE(origin1.host(), origin2.host());
3998
3999 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524000 quic::QuicStreamOffset request_header_offset(0);
4001 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444002
4003 scoped_refptr<X509Certificate> cert(
4004 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244005 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4006 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444007
4008 ProofVerifyDetailsChromium verify_details;
4009 verify_details.cert_verify_result.verified_cert = cert;
4010 verify_details.cert_verify_result.is_issued_by_known_root = true;
4011 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4012
4013 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434014 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444015 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434016 mock_quic_data.AddWrite(
4017 SYNCHRONOUS,
4018 ConstructClientRequestHeadersPacket(
4019 2, GetNthClientInitiatedStreamId(0), true, true,
4020 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4021 mock_quic_data.AddRead(
4022 ASYNC, ConstructServerResponseHeadersPacket(
4023 1, GetNthClientInitiatedStreamId(0), false, false,
4024 GetResponseHeaders("200 OK"), &response_header_offset));
4025 mock_quic_data.AddRead(
4026 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4027 false, true, 0, "hello!"));
4028 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444029
4030 // Second request will go over the pooled QUIC connection, but will be
4031 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054032 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524033 version_, 0, &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054034 client_headers_include_h2_stream_dependency_);
rch30943ee2017-06-12 21:28:444035 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524036 quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434037 mock_quic_data.AddWrite(
4038 SYNCHRONOUS,
4039 ConstructClientRequestHeadersPacket(
4040 4, GetNthClientInitiatedStreamId(1), false, true,
4041 GetRequestHeaders("GET", "https", "/", &client_maker2),
4042 GetNthClientInitiatedStreamId(0), &request_header_offset));
4043 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
4044 3, false, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524045 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444046 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4047 mock_quic_data.AddRead(ASYNC, 0); // EOF
4048
4049 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4050
4051 // After that fails, it will be resent via TCP.
4052 MockWrite http_writes[] = {
4053 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4054 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4055 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4056
4057 MockRead http_reads[] = {
4058 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4059 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4060 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014061 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444062 socket_factory_.AddSocketDataProvider(&http_data);
4063 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4064
Ryan Hamilton6c2a2a82017-12-15 02:06:284065 // Then the next request to the second origin will be sent over TCP.
4066 socket_factory_.AddSocketDataProvider(&http_data);
4067 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444068
4069 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564070 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4071 QuicStreamFactoryPeer::SetAlarmFactory(
4072 session_->quic_stream_factory(),
4073 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4074 &clock_));
rch30943ee2017-06-12 21:28:444075
4076 // Set up alternative service for |origin1|.
4077 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244078 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214079 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244080 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444081 supported_versions_);
rch30943ee2017-06-12 21:28:444082
4083 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244084 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214085 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244086 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444087 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344088
rch30943ee2017-06-12 21:28:444089 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524090 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444091 SendRequestAndExpectQuicResponse("hello!");
4092
4093 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524094 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444095 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4096 request_.url = origin2;
4097 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284098 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244099 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284100 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244101 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444102
4103 // The third request should use a new QUIC connection, not the broken
4104 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284105 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444106}
4107
bnc8be55ebb2015-10-30 14:12:074108TEST_P(QuicNetworkTransactionTest,
4109 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4110 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444111 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074112 MockRead http_reads[] = {
4113 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4114 MockRead("hello world"),
4115 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4116 MockRead(ASYNC, OK)};
4117
Ryan Sleevib8d7ea02018-05-07 20:01:014118 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074119 socket_factory_.AddSocketDataProvider(&http_data);
4120 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4121 socket_factory_.AddSocketDataProvider(&http_data);
4122 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4123
rch3f4b8452016-02-23 16:59:324124 CreateSession();
bnc8be55ebb2015-10-30 14:12:074125
4126 SendRequestAndExpectHttpResponse("hello world");
4127 SendRequestAndExpectHttpResponse("hello world");
4128}
4129
Xida Chen9bfe0b62018-04-24 19:52:214130// When multiple alternative services are advertised, HttpStreamFactory should
4131// select the alternative service which uses existing QUIC session if available.
4132// If no existing QUIC session can be used, use the first alternative service
4133// from the list.
zhongyi32569c62016-01-08 02:54:304134TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344135 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524136 MockRead http_reads[] = {
4137 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294138 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524139 MockRead("hello world"),
4140 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4141 MockRead(ASYNC, OK)};
4142
Ryan Sleevib8d7ea02018-05-07 20:01:014143 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524144 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084145 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564146 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524147
Ryan Hamilton8d9ee76e2018-05-29 23:52:524148 quic::QuicStreamOffset request_header_offset = 0;
4149 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304150 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294151 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304152 // alternative service list.
bncc958faa2015-07-31 18:14:524153 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364154 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434155 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4156 mock_quic_data.AddWrite(
4157 SYNCHRONOUS,
4158 ConstructClientRequestHeadersPacket(
4159 2, GetNthClientInitiatedStreamId(0), true, true,
4160 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304161
4162 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294163 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4164 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434165 mock_quic_data.AddRead(
4166 ASYNC,
4167 ConstructServerResponseHeadersPacket(
4168 1, GetNthClientInitiatedStreamId(0), false, false,
4169 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
4170 mock_quic_data.AddRead(
4171 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4172 false, true, 0, "hello!"));
4173 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304174
4175 // Second QUIC request data.
4176 // Connection pooling, using existing session, no need to include version
4177 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584178 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434179 SYNCHRONOUS,
4180 ConstructClientRequestHeadersPacket(
4181 4, GetNthClientInitiatedStreamId(1), false, true,
4182 GetRequestHeaders("GET", "https", "/"),
4183 GetNthClientInitiatedStreamId(0), &request_header_offset));
4184 mock_quic_data.AddRead(
4185 ASYNC, ConstructServerResponseHeadersPacket(
4186 3, GetNthClientInitiatedStreamId(1), false, false,
4187 GetResponseHeaders("200 OK"), &response_header_offset));
4188 mock_quic_data.AddRead(
4189 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4190 false, true, 0, "hello!"));
4191 mock_quic_data.AddWrite(
4192 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524193 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594194 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524195
4196 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4197
rtennetib8e80fb2016-05-16 00:12:094198 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324199 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564200 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4201 QuicStreamFactoryPeer::SetAlarmFactory(
4202 session_->quic_stream_factory(),
4203 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4204 &clock_));
bncc958faa2015-07-31 18:14:524205
4206 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304207
bnc359ed2a2016-04-29 20:43:454208 SendRequestAndExpectQuicResponse("hello!");
4209 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304210}
4211
tbansal6490783c2016-09-20 17:55:274212// Check that an existing QUIC connection to an alternative proxy server is
4213// used.
4214TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4215 base::HistogramTester histogram_tester;
4216
Ryan Hamilton8d9ee76e2018-05-29 23:52:524217 quic::QuicStreamOffset request_header_offset = 0;
4218 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274219 // First QUIC request data.
4220 // Open a session to foo.example.org:443 using the first entry of the
4221 // alternative service list.
4222 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364223 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434224 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4225 mock_quic_data.AddWrite(
4226 SYNCHRONOUS,
4227 ConstructClientRequestHeadersPacket(
4228 2, GetNthClientInitiatedStreamId(0), true, true,
4229 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274230
4231 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434232 mock_quic_data.AddRead(
4233 ASYNC,
4234 ConstructServerResponseHeadersPacket(
4235 1, GetNthClientInitiatedStreamId(0), false, false,
4236 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
4237 mock_quic_data.AddRead(
4238 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4239 false, true, 0, "hello!"));
4240 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274241
4242 // Second QUIC request data.
4243 // Connection pooling, using existing session, no need to include version
4244 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274245 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434246 SYNCHRONOUS,
4247 ConstructClientRequestHeadersPacket(
4248 4, GetNthClientInitiatedStreamId(1), false, true,
4249 GetRequestHeaders("GET", "http", "/"),
4250 GetNthClientInitiatedStreamId(0), &request_header_offset));
4251 mock_quic_data.AddRead(
4252 ASYNC, ConstructServerResponseHeadersPacket(
4253 3, GetNthClientInitiatedStreamId(1), false, false,
4254 GetResponseHeaders("200 OK"), &response_header_offset));
4255 mock_quic_data.AddRead(
4256 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4257 false, true, 0, "hello!"));
4258 mock_quic_data.AddWrite(
4259 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274260 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4261 mock_quic_data.AddRead(ASYNC, 0); // EOF
4262
4263 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4264
4265 AddHangingNonAlternateProtocolSocketData();
4266
4267 TestProxyDelegate test_proxy_delegate;
4268
Lily Houghton8c2f97d2018-01-22 05:06:594269 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494270 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274271
4272 test_proxy_delegate.set_alternative_proxy_server(
4273 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524274 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274275
4276 request_.url = GURL("http://mail.example.org/");
4277
4278 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564279 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4280 QuicStreamFactoryPeer::SetAlarmFactory(
4281 session_->quic_stream_factory(),
4282 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4283 &clock_));
tbansal6490783c2016-09-20 17:55:274284
4285 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4286 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4287 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4288 1);
4289
4290 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4291 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4292 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4293 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4294 1);
4295}
4296
Ryan Hamilton8d9ee76e2018-05-29 23:52:524297// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454298// even if alternative service destination is different.
4299TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344300 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304301 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524302 quic::QuicStreamOffset request_header_offset(0);
4303 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454304
rch5cb522462017-04-25 20:18:364305 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434306 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454307 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434308 mock_quic_data.AddWrite(
4309 SYNCHRONOUS,
4310 ConstructClientRequestHeadersPacket(
4311 2, GetNthClientInitiatedStreamId(0), true, true,
4312 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4313 mock_quic_data.AddRead(
4314 ASYNC, ConstructServerResponseHeadersPacket(
4315 1, GetNthClientInitiatedStreamId(0), false, false,
4316 GetResponseHeaders("200 OK"), &response_header_offset));
4317 mock_quic_data.AddRead(
4318 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4319 false, true, 0, "hello!"));
4320 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304321
bnc359ed2a2016-04-29 20:43:454322 // Second request.
alyssar2adf3ac2016-05-03 17:12:584323 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434324 SYNCHRONOUS,
4325 ConstructClientRequestHeadersPacket(
4326 4, GetNthClientInitiatedStreamId(1), false, true,
4327 GetRequestHeaders("GET", "https", "/"),
4328 GetNthClientInitiatedStreamId(0), &request_header_offset));
4329 mock_quic_data.AddRead(
4330 ASYNC, ConstructServerResponseHeadersPacket(
4331 3, GetNthClientInitiatedStreamId(1), false, false,
4332 GetResponseHeaders("200 OK"), &response_header_offset));
4333 mock_quic_data.AddRead(
4334 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4335 false, true, 0, "hello!"));
4336 mock_quic_data.AddWrite(
4337 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304338 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4339 mock_quic_data.AddRead(ASYNC, 0); // EOF
4340
4341 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454342
4343 AddHangingNonAlternateProtocolSocketData();
4344 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304345
rch3f4b8452016-02-23 16:59:324346 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564347 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4348 QuicStreamFactoryPeer::SetAlarmFactory(
4349 session_->quic_stream_factory(),
4350 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4351 &clock_));
zhongyi32569c62016-01-08 02:54:304352
bnc359ed2a2016-04-29 20:43:454353 const char destination1[] = "first.example.com";
4354 const char destination2[] = "second.example.com";
4355
4356 // Set up alternative service entry to destination1.
4357 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214358 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454359 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214360 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444361 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454362 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524363 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454364 SendRequestAndExpectQuicResponse("hello!");
4365
4366 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214367 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214368 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444369 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524370 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454371 // even though alternative service destination is different.
4372 SendRequestAndExpectQuicResponse("hello!");
4373}
4374
4375// Pool to existing session with matching destination and matching certificate
4376// even if origin is different, and even if the alternative service with
4377// matching destination is not the first one on the list.
4378TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344379 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454380 GURL origin1 = request_.url;
4381 GURL origin2("https://www.example.org/");
4382 ASSERT_NE(origin1.host(), origin2.host());
4383
4384 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524385 quic::QuicStreamOffset request_header_offset(0);
4386 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454387
rch5cb522462017-04-25 20:18:364388 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434389 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454390 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434391 mock_quic_data.AddWrite(
4392 SYNCHRONOUS,
4393 ConstructClientRequestHeadersPacket(
4394 2, GetNthClientInitiatedStreamId(0), true, true,
4395 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4396 mock_quic_data.AddRead(
4397 ASYNC, ConstructServerResponseHeadersPacket(
4398 1, GetNthClientInitiatedStreamId(0), false, false,
4399 GetResponseHeaders("200 OK"), &response_header_offset));
4400 mock_quic_data.AddRead(
4401 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4402 false, true, 0, "hello!"));
4403 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454404
4405 // Second request.
Yixin Wang079ad542018-01-11 04:06:054406 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524407 version_, 0, &clock_, origin2.host(), quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054408 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:554409 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524410 quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584411 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434412 SYNCHRONOUS,
4413 ConstructClientRequestHeadersPacket(
4414 4, GetNthClientInitiatedStreamId(1), false, true,
4415 GetRequestHeaders("GET", "https", "/", &client_maker2),
4416 GetNthClientInitiatedStreamId(0), &request_header_offset));
4417 mock_quic_data.AddRead(
4418 ASYNC, ConstructServerResponseHeadersPacket(
4419 3, GetNthClientInitiatedStreamId(1), false, false,
4420 GetResponseHeaders("200 OK"), &response_header_offset));
4421 mock_quic_data.AddRead(
4422 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
4423 false, true, 0, "hello!"));
4424 mock_quic_data.AddWrite(
4425 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454426 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4427 mock_quic_data.AddRead(ASYNC, 0); // EOF
4428
4429 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4430
4431 AddHangingNonAlternateProtocolSocketData();
4432 AddHangingNonAlternateProtocolSocketData();
4433
4434 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564435 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4436 QuicStreamFactoryPeer::SetAlarmFactory(
4437 session_->quic_stream_factory(),
4438 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4439 &clock_));
bnc359ed2a2016-04-29 20:43:454440
4441 const char destination1[] = "first.example.com";
4442 const char destination2[] = "second.example.com";
4443
4444 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214445 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454446 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214447 http_server_properties_.SetQuicAlternativeService(
4448 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444449 supported_versions_);
bnc359ed2a2016-04-29 20:43:454450
4451 // Set up multiple alternative service entries for |origin2|,
4452 // the first one with a different destination as for |origin1|,
4453 // the second one with the same. The second one should be used,
4454 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214455 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454456 AlternativeServiceInfoVector alternative_services;
4457 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214458 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4459 alternative_service2, expiration,
4460 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454461 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214462 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4463 alternative_service1, expiration,
4464 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454465 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4466 alternative_services);
bnc359ed2a2016-04-29 20:43:454467 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524468 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454469 SendRequestAndExpectQuicResponse("hello!");
4470
4471 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524472 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454473 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584474
bnc359ed2a2016-04-29 20:43:454475 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304476}
4477
4478// Multiple origins have listed the same alternative services. When there's a
4479// existing QUIC session opened by a request to other origin,
4480// if the cert is valid, should select this QUIC session to make the request
4481// if this is also the first existing QUIC session.
4482TEST_P(QuicNetworkTransactionTest,
4483 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344484 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294485 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304486
rch9ae5b3b2016-02-11 00:36:294487 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304488 MockRead http_reads[] = {
4489 MockRead("HTTP/1.1 200 OK\r\n"),
4490 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294491 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304492 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4493 MockRead(ASYNC, OK)};
4494
Ryan Sleevib8d7ea02018-05-07 20:01:014495 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304496 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084497 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304498 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4499
4500 // HTTP data for request to mail.example.org.
4501 MockRead http_reads2[] = {
4502 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294503 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304504 MockRead("hello world from mail.example.org"),
4505 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4506 MockRead(ASYNC, OK)};
4507
Ryan Sleevib8d7ea02018-05-07 20:01:014508 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304509 socket_factory_.AddSocketDataProvider(&http_data2);
4510 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4511
Ryan Hamilton8d9ee76e2018-05-29 23:52:524512 quic::QuicStreamOffset request_header_offset = 0;
4513 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304514
Yixin Wang079ad542018-01-11 04:06:054515 QuicTestPacketMaker client_maker(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524516 version_, 0, &clock_, "mail.example.org", quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054517 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584518 server_maker_.set_hostname("www.example.org");
4519 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304520 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364521 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434522 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304523 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584524 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434525 SYNCHRONOUS,
4526 ConstructClientRequestHeadersPacket(
4527 2, GetNthClientInitiatedStreamId(0), true, true,
4528 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4529
4530 mock_quic_data.AddRead(
4531 ASYNC, ConstructServerResponseHeadersPacket(
4532 1, GetNthClientInitiatedStreamId(0), false, false,
4533 GetResponseHeaders("200 OK"), &response_header_offset));
4534 mock_quic_data.AddRead(ASYNC, ConstructServerDataPacket(
4535 2, GetNthClientInitiatedStreamId(0), false,
4536 true, 0, "hello from mail QUIC!"));
4537 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4538 // Second QUIC request data.
4539 mock_quic_data.AddWrite(
4540 SYNCHRONOUS,
4541 ConstructClientRequestHeadersPacket(
4542 4, GetNthClientInitiatedStreamId(1), false, true,
4543 GetRequestHeaders("GET", "https", "/", &client_maker),
4544 GetNthClientInitiatedStreamId(0), &request_header_offset));
4545 mock_quic_data.AddRead(
4546 ASYNC, ConstructServerResponseHeadersPacket(
4547 3, GetNthClientInitiatedStreamId(1), false, false,
4548 GetResponseHeaders("200 OK"), &response_header_offset));
4549 mock_quic_data.AddRead(ASYNC, ConstructServerDataPacket(
4550 4, GetNthClientInitiatedStreamId(1), false,
4551 true, 0, "hello from mail QUIC!"));
4552 mock_quic_data.AddWrite(
4553 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304554 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4555 mock_quic_data.AddRead(ASYNC, 0); // EOF
4556
4557 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304558
rtennetib8e80fb2016-05-16 00:12:094559 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324560 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564561 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4562 QuicStreamFactoryPeer::SetAlarmFactory(
4563 session_->quic_stream_factory(),
4564 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4565 &clock_));
zhongyi32569c62016-01-08 02:54:304566
4567 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294568 request_.url = GURL("https://www.example.org/");
4569 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304570 request_.url = GURL("https://mail.example.org/");
4571 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4572
rch9ae5b3b2016-02-11 00:36:294573 // Open a QUIC session to mail.example.org:443 when making request
4574 // to mail.example.org.
4575 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454576 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304577
rch9ae5b3b2016-02-11 00:36:294578 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304579 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454580 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524581}
4582
4583TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524584 MockRead http_reads[] = {
4585 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564586 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524587 MockRead("hello world"),
4588 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4589 MockRead(ASYNC, OK)};
4590
Ryan Sleevib8d7ea02018-05-07 20:01:014591 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524592 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084593 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564594 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524595
rtennetib8e80fb2016-05-16 00:12:094596 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324597 CreateSession();
bncc958faa2015-07-31 18:14:524598
4599 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454600
4601 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344602 AlternativeServiceInfoVector alternative_service_info_vector =
4603 http_server_properties_.GetAlternativeServiceInfos(http_server);
4604 ASSERT_EQ(1u, alternative_service_info_vector.size());
4605 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544606 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344607 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4608 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4609 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524610}
4611
4612TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524613 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564614 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4615 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524616 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4617 MockRead(ASYNC, OK)};
4618
Ryan Sleevib8d7ea02018-05-07 20:01:014619 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524620 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084621 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564622 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524623
4624 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524625 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364626 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434627 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4628 mock_quic_data.AddWrite(
4629 SYNCHRONOUS,
4630 ConstructClientRequestHeadersPacket(
4631 2, GetNthClientInitiatedStreamId(0), true, true,
4632 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4633 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4634 1, GetNthClientInitiatedStreamId(0), false,
4635 false, GetResponseHeaders("200 OK")));
4636 mock_quic_data.AddRead(
4637 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4638 false, true, 0, "hello!"));
4639 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524640 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4641 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524642
4643 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4644
rtennetib8e80fb2016-05-16 00:12:094645 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324646 CreateSession();
bncc958faa2015-07-31 18:14:524647
bnc3472afd2016-11-17 15:27:214648 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524649 HostPortPair::FromURL(request_.url));
4650 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4651 alternative_service);
4652 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4653 alternative_service));
4654
4655 SendRequestAndExpectHttpResponse("hello world");
4656 SendRequestAndExpectQuicResponse("hello!");
4657
mmenkee24011922015-12-17 22:12:594658 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524659
4660 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4661 alternative_service));
rchac7f35e2017-03-15 20:42:304662 EXPECT_NE(nullptr,
4663 http_server_properties_.GetServerNetworkStats(
4664 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524665}
4666
bncc958faa2015-07-31 18:14:524667TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524668 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564669 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4670 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524671 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4672 MockRead(ASYNC, OK)};
4673
Ryan Sleevib8d7ea02018-05-07 20:01:014674 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524675 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564676 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524677
4678 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524679 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364680 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434681 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4682 mock_quic_data.AddWrite(
4683 SYNCHRONOUS,
4684 ConstructClientRequestHeadersPacket(
4685 2, GetNthClientInitiatedStreamId(0), true, true,
4686 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4687 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4688 1, GetNthClientInitiatedStreamId(0), false,
4689 false, GetResponseHeaders("200 OK")));
4690 mock_quic_data.AddRead(
4691 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4692 false, true, 0, "hello!"));
4693 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524694 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4695
4696 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4697
4698 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324699 CreateSession();
bncc958faa2015-07-31 18:14:524700
4701 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4702 SendRequestAndExpectHttpResponse("hello world");
4703}
4704
tbansalc3308d72016-08-27 10:25:044705// Tests that the connection to an HTTPS proxy is raced with an available
4706// alternative proxy server.
4707TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274708 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594709 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494710 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044711
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(
4719 2, GetNthClientInitiatedStreamId(0), true, true,
4720 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
4721 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4722 1, GetNthClientInitiatedStreamId(0), false,
4723 false, GetResponseHeaders("200 OK")));
4724 mock_quic_data.AddRead(
4725 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4726 false, true, 0, "hello!"));
4727 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044728 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4729 mock_quic_data.AddRead(ASYNC, 0); // EOF
4730
4731 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4732
4733 // There is no need to set up main job, because no attempt will be made to
4734 // speak to the proxy over TCP.
4735 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044736 TestProxyDelegate test_proxy_delegate;
4737 const HostPortPair host_port_pair("mail.example.org", 443);
4738
4739 test_proxy_delegate.set_alternative_proxy_server(
4740 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524741 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044742 CreateSession();
4743 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4744
4745 // The main job needs to hang in order to guarantee that the alternative
4746 // proxy server job will "win".
4747 AddHangingNonAlternateProtocolSocketData();
4748
4749 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4750
4751 // Verify that the alternative proxy server is not marked as broken.
4752 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4753
4754 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594755 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274756
4757 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4758 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4759 1);
tbansalc3308d72016-08-27 10:25:044760}
4761
bnc1c196c6e2016-05-28 13:51:484762TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304763 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274764 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304765
4766 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564767 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294768 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564769 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304770
4771 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564772 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484773 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564774 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304775
Ryan Sleevib8d7ea02018-05-07 20:01:014776 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504777 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084778 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504779 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304780
4781 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454782 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304783 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454784 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304785 };
Ryan Sleevib8d7ea02018-05-07 20:01:014786 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504787 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304788
4789 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014790 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504791 socket_factory_.AddSocketDataProvider(&http_data2);
4792 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304793
bnc912a04b2016-04-20 14:19:504794 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304795
4796 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304797 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174798 ASSERT_TRUE(http_data.AllReadDataConsumed());
4799 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304800
4801 // Now run the second request in which the QUIC socket hangs,
4802 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304803 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454804 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304805
rch37de576c2015-05-17 20:28:174806 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4807 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454808 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304809}
4810
[email protected]1e960032013-12-20 19:00:204811TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204812 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524813 quic::QuicStreamOffset header_stream_offset = 0;
4814 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4815 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434816 mock_quic_data.AddWrite(
4817 SYNCHRONOUS,
4818 ConstructClientRequestHeadersPacket(
4819 1, GetNthClientInitiatedStreamId(0), true, true,
4820 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4821 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4822 1, GetNthClientInitiatedStreamId(0), false,
4823 false, GetResponseHeaders("200 OK")));
4824 mock_quic_data.AddRead(
4825 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4826 false, true, 0, "hello!"));
4827 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504828 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594829 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484830
rcha5399e02015-04-21 19:32:044831 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484832
rtennetib8e80fb2016-05-16 00:12:094833 // The non-alternate protocol job needs to hang in order to guarantee that
4834 // the alternate-protocol job will "win".
4835 AddHangingNonAlternateProtocolSocketData();
4836
rch3f4b8452016-02-23 16:59:324837 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274838 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194839 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304840
4841 EXPECT_EQ(nullptr,
4842 http_server_properties_.GetServerNetworkStats(
4843 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484844}
4845
[email protected]1e960032013-12-20 19:00:204846TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204847 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524848 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4849 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434850 mock_quic_data.AddWrite(SYNCHRONOUS,
4851 ConstructClientRequestHeadersPacket(
4852 1, GetNthClientInitiatedStreamId(0), true, true,
4853 GetRequestHeaders("GET", "https", "/")));
4854 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4855 1, GetNthClientInitiatedStreamId(0), false,
4856 false, GetResponseHeaders("200 OK")));
4857 mock_quic_data.AddRead(
4858 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4859 false, true, 0, "hello!"));
4860 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504861 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594862 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044863 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274864
4865 // In order for a new QUIC session to be established via alternate-protocol
4866 // without racing an HTTP connection, we need the host resolution to happen
4867 // synchronously.
4868 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294869 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564870 "");
rch9ae5b3b2016-02-11 00:36:294871 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:274872 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104873 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584874 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4875 CompletionOnceCallback(), &request,
4876 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414877 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:274878
rtennetib8e80fb2016-05-16 00:12:094879 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324880 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274881 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274882 SendRequestAndExpectQuicResponse("hello!");
4883}
4884
[email protected]0fc924b2014-03-31 04:34:154885TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494886 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4887 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154888
4889 // Since we are using a proxy, the QUIC job will not succeed.
4890 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294891 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4892 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564893 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154894
4895 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564896 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484897 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564898 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154899
Ryan Sleevib8d7ea02018-05-07 20:01:014900 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154901 socket_factory_.AddSocketDataProvider(&http_data);
4902
4903 // In order for a new QUIC session to be established via alternate-protocol
4904 // without racing an HTTP connection, we need the host resolution to happen
4905 // synchronously.
4906 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294907 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564908 "");
rch9ae5b3b2016-02-11 00:36:294909 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:154910 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104911 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584912 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4913 CompletionOnceCallback(), &request,
4914 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414915 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:154916
rch9ae5b3b2016-02-11 00:36:294917 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324918 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274919 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154920 SendRequestAndExpectHttpResponse("hello world");
4921}
4922
[email protected]1e960032013-12-20 19:00:204923TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204924 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524925 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364926 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434927 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4928 mock_quic_data.AddWrite(
4929 SYNCHRONOUS,
4930 ConstructClientRequestHeadersPacket(
4931 2, GetNthClientInitiatedStreamId(0), true, true,
4932 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
4933 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4934 1, GetNthClientInitiatedStreamId(0), false,
4935 false, GetResponseHeaders("200 OK")));
4936 mock_quic_data.AddRead(
4937 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
4938 false, true, 0, "hello!"));
4939 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:594940 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:044941 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:124942
rtennetib8e80fb2016-05-16 00:12:094943 // The non-alternate protocol job needs to hang in order to guarantee that
4944 // the alternate-protocol job will "win".
4945 AddHangingNonAlternateProtocolSocketData();
4946
[email protected]11c05872013-08-20 02:04:124947 // In order for a new QUIC session to be established via alternate-protocol
4948 // without racing an HTTP connection, we need the host resolution to happen
4949 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
4950 // connection to the the server, in this test we require confirmation
4951 // before encrypting so the HTTP job will still start.
4952 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294953 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564954 "");
rch9ae5b3b2016-02-11 00:36:294955 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:124956 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104957 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584958 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4959 CompletionOnceCallback(), &request,
4960 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414961 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:124962
rch3f4b8452016-02-23 16:59:324963 CreateSession();
[email protected]11c05872013-08-20 02:04:124964 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:274965 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:124966
bnc691fda62016-08-12 00:43:164967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:124968 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:414969 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:014970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:124971
4972 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:524973 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:014974 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:504975
bnc691fda62016-08-12 00:43:164976 CheckWasQuicResponse(&trans);
4977 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:124978}
4979
Steven Valdez58097ec32018-07-16 18:29:044980TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
4981 MockQuicData mock_quic_data;
4982 quic::QuicStreamOffset client_header_stream_offset = 0;
4983 quic::QuicStreamOffset server_header_stream_offset = 0;
4984 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4985 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
4986 mock_quic_data.AddWrite(SYNCHRONOUS,
4987 ConstructClientRequestHeadersPacket(
4988 1, GetNthClientInitiatedStreamId(0), true, true,
4989 GetRequestHeaders("GET", "https", "/"),
4990 &client_header_stream_offset));
4991 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
4992 1, GetNthClientInitiatedStreamId(0), false,
4993 false, GetResponseHeaders("425 TOO_EARLY"),
4994 &server_header_stream_offset));
4995 mock_quic_data.AddWrite(
4996 SYNCHRONOUS,
4997 ConstructClientAckAndRstPacket(2, GetNthClientInitiatedStreamId(0),
4998 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
4999
5000 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5001
5002 spdy::SpdySettingsIR settings_frame;
5003 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5004 quic::kDefaultMaxUncompressedHeaderSize);
5005 spdy::SpdySerializedFrame spdy_frame(
5006 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5007 mock_quic_data.AddWrite(
5008 SYNCHRONOUS,
5009 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385010 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5011 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045012 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5013 client_header_stream_offset += spdy_frame.size();
5014
5015 mock_quic_data.AddWrite(
5016 SYNCHRONOUS,
5017 ConstructClientRequestHeadersPacket(
5018 4, GetNthClientInitiatedStreamId(1), false, true,
5019 GetRequestHeaders("GET", "https", "/"),
5020 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
5021 mock_quic_data.AddRead(
5022 ASYNC, ConstructServerResponseHeadersPacket(
5023 2, GetNthClientInitiatedStreamId(1), false, false,
5024 GetResponseHeaders("200 OK"), &server_header_stream_offset));
5025 mock_quic_data.AddRead(
5026 ASYNC, ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(1),
5027 false, true, 0, "hello!"));
5028 mock_quic_data.AddWrite(
5029 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5030 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5031 mock_quic_data.AddRead(ASYNC, 0); // EOF
5032
5033 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5034
5035 // In order for a new QUIC session to be established via alternate-protocol
5036 // without racing an HTTP connection, we need the host resolution to happen
5037 // synchronously.
5038 host_resolver_.set_synchronous_mode(true);
5039 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5040 "");
5041 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5042 AddressList address;
5043 std::unique_ptr<HostResolver::Request> request;
5044 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5045 CompletionOnceCallback(), &request, net_log_.bound());
5046
5047 AddHangingNonAlternateProtocolSocketData();
5048 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275049 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565050 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5051 QuicStreamFactoryPeer::SetAlarmFactory(
5052 session_->quic_stream_factory(),
5053 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5054 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045055
5056 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5057 TestCompletionCallback callback;
5058 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5060
5061 // Confirm the handshake after the 425 Too Early.
5062 base::RunLoop().RunUntilIdle();
5063
5064 // The handshake hasn't been confirmed yet, so the retry should not have
5065 // succeeded.
5066 EXPECT_FALSE(callback.have_result());
5067
5068 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5069 quic::QuicSession::HANDSHAKE_CONFIRMED);
5070
5071 EXPECT_THAT(callback.WaitForResult(), IsOk());
5072 CheckWasQuicResponse(&trans);
5073 CheckResponseData(&trans, "hello!");
5074}
5075
5076TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5077 MockQuicData mock_quic_data;
5078 quic::QuicStreamOffset client_header_stream_offset = 0;
5079 quic::QuicStreamOffset server_header_stream_offset = 0;
5080 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5081 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
5082 mock_quic_data.AddWrite(SYNCHRONOUS,
5083 ConstructClientRequestHeadersPacket(
5084 1, GetNthClientInitiatedStreamId(0), true, true,
5085 GetRequestHeaders("GET", "https", "/"),
5086 &client_header_stream_offset));
5087 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5088 1, GetNthClientInitiatedStreamId(0), false,
5089 false, GetResponseHeaders("425 TOO_EARLY"),
5090 &server_header_stream_offset));
5091 mock_quic_data.AddWrite(
5092 SYNCHRONOUS,
5093 ConstructClientAckAndRstPacket(2, GetNthClientInitiatedStreamId(0),
5094 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
5095
5096 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5097
5098 spdy::SpdySettingsIR settings_frame;
5099 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5100 quic::kDefaultMaxUncompressedHeaderSize);
5101 spdy::SpdySerializedFrame spdy_frame(
5102 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5103 mock_quic_data.AddWrite(
5104 SYNCHRONOUS,
5105 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385106 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5107 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045108 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5109 client_header_stream_offset += spdy_frame.size();
5110
5111 mock_quic_data.AddWrite(
5112 SYNCHRONOUS,
5113 ConstructClientRequestHeadersPacket(
5114 4, GetNthClientInitiatedStreamId(1), false, true,
5115 GetRequestHeaders("GET", "https", "/"),
5116 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
5117 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5118 2, GetNthClientInitiatedStreamId(1), false,
5119 false, GetResponseHeaders("425 TOO_EARLY"),
5120 &server_header_stream_offset));
5121 mock_quic_data.AddWrite(
5122 SYNCHRONOUS,
5123 ConstructClientAckAndRstPacket(5, GetNthClientInitiatedStreamId(1),
5124 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
5125 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5126 mock_quic_data.AddRead(ASYNC, 0); // EOF
5127
5128 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5129
5130 // In order for a new QUIC session to be established via alternate-protocol
5131 // without racing an HTTP connection, we need the host resolution to happen
5132 // synchronously.
5133 host_resolver_.set_synchronous_mode(true);
5134 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5135 "");
5136 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5137 AddressList address;
5138 std::unique_ptr<HostResolver::Request> request;
5139 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5140 CompletionOnceCallback(), &request, net_log_.bound());
5141
5142 AddHangingNonAlternateProtocolSocketData();
5143 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275144 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565145 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5146 QuicStreamFactoryPeer::SetAlarmFactory(
5147 session_->quic_stream_factory(),
5148 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5149 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045150
5151 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5152 TestCompletionCallback callback;
5153 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5155
5156 // Confirm the handshake after the 425 Too Early.
5157 base::RunLoop().RunUntilIdle();
5158
5159 // The handshake hasn't been confirmed yet, so the retry should not have
5160 // succeeded.
5161 EXPECT_FALSE(callback.have_result());
5162
5163 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5164 quic::QuicSession::HANDSHAKE_CONFIRMED);
5165
5166 EXPECT_THAT(callback.WaitForResult(), IsOk());
5167 const HttpResponseInfo* response = trans.GetResponseInfo();
5168 ASSERT_TRUE(response != nullptr);
5169 ASSERT_TRUE(response->headers.get() != nullptr);
5170 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5171 EXPECT_TRUE(response->was_fetched_via_spdy);
5172 EXPECT_TRUE(response->was_alpn_negotiated);
5173 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5174 response->connection_info);
5175}
5176
zhongyica364fbb2015-12-12 03:39:125177TEST_P(QuicNetworkTransactionTest,
5178 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485179 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125180 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525181 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365182 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435183 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5184 mock_quic_data.AddWrite(
5185 SYNCHRONOUS,
5186 ConstructClientRequestHeadersPacket(
5187 2, GetNthClientInitiatedStreamId(0), true, true,
5188 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125189 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525190 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435191 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125192 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5193
5194 // The non-alternate protocol job needs to hang in order to guarantee that
5195 // the alternate-protocol job will "win".
5196 AddHangingNonAlternateProtocolSocketData();
5197
5198 // In order for a new QUIC session to be established via alternate-protocol
5199 // without racing an HTTP connection, we need the host resolution to happen
5200 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5201 // connection to the the server, in this test we require confirmation
5202 // before encrypting so the HTTP job will still start.
5203 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295204 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125205 "");
rch9ae5b3b2016-02-11 00:36:295206 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125207 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105208 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585209 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5210 CompletionOnceCallback(), &request,
5211 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415212 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125213
rch3f4b8452016-02-23 16:59:325214 CreateSession();
zhongyica364fbb2015-12-12 03:39:125215 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275216 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125217
bnc691fda62016-08-12 00:43:165218 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125219 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415220 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125222
5223 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525224 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015225 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125226
5227 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525228 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125229
bnc691fda62016-08-12 00:43:165230 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125231 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525232 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5233 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125234}
5235
5236TEST_P(QuicNetworkTransactionTest,
5237 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485238 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125239 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525240 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365241 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435242 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5243 mock_quic_data.AddWrite(
5244 SYNCHRONOUS,
5245 ConstructClientRequestHeadersPacket(
5246 2, GetNthClientInitiatedStreamId(0), true, true,
5247 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215248 // Peer sending data from an non-existing stream causes this end to raise
5249 // error and close connection.
Fan Yang7c68f632018-11-06 03:05:385250 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
5251 1, false, GetNthClientInitiatedStreamId(47),
5252 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215253 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525254 mock_quic_data.AddWrite(
5255 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5256 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5257 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125258 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5259
5260 // The non-alternate protocol job needs to hang in order to guarantee that
5261 // the alternate-protocol job will "win".
5262 AddHangingNonAlternateProtocolSocketData();
5263
5264 // In order for a new QUIC session to be established via alternate-protocol
5265 // without racing an HTTP connection, we need the host resolution to happen
5266 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5267 // connection to the the server, in this test we require confirmation
5268 // before encrypting so the HTTP job will still start.
5269 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295270 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125271 "");
rch9ae5b3b2016-02-11 00:36:295272 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125273 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105274 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585275 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5276 CompletionOnceCallback(), &request,
5277 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415278 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125279
rch3f4b8452016-02-23 16:59:325280 CreateSession();
zhongyica364fbb2015-12-12 03:39:125281 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275282 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125283
bnc691fda62016-08-12 00:43:165284 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125285 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415286 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015287 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125288
5289 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525290 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015291 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125292 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525293 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125294
bnc691fda62016-08-12 00:43:165295 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525296 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125297}
5298
rchcd5f1c62016-06-23 02:43:485299TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5300 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525301 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365302 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435303 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5304 mock_quic_data.AddWrite(
5305 SYNCHRONOUS,
5306 ConstructClientRequestHeadersPacket(
5307 2, GetNthClientInitiatedStreamId(0), true, true,
5308 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485309 // Read the response headers, then a RST_STREAM frame.
Zhongyi Shi32f2fd02018-04-16 18:23:435310 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5311 1, GetNthClientInitiatedStreamId(0), false,
5312 false, GetResponseHeaders("200 OK")));
5313 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
5314 2, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525315 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435316 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485317 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5318 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5319
5320 // The non-alternate protocol job needs to hang in order to guarantee that
5321 // the alternate-protocol job will "win".
5322 AddHangingNonAlternateProtocolSocketData();
5323
5324 // In order for a new QUIC session to be established via alternate-protocol
5325 // without racing an HTTP connection, we need the host resolution to happen
5326 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5327 // connection to the the server, in this test we require confirmation
5328 // before encrypting so the HTTP job will still start.
5329 host_resolver_.set_synchronous_mode(true);
5330 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5331 "");
5332 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5333 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105334 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585335 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5336 CompletionOnceCallback(), &request,
5337 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415338 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485339
5340 CreateSession();
5341 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275342 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485343
bnc691fda62016-08-12 00:43:165344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485345 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415346 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015347 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485348
5349 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525350 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485351 // Read the headers.
robpercival214763f2016-07-01 23:27:015352 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485353
bnc691fda62016-08-12 00:43:165354 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485355 ASSERT_TRUE(response != nullptr);
5356 ASSERT_TRUE(response->headers.get() != nullptr);
5357 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5358 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525359 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445360 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5361 response->connection_info);
rchcd5f1c62016-06-23 02:43:485362
5363 std::string response_data;
bnc691fda62016-08-12 00:43:165364 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485365}
5366
5367TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485368 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485369 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525370 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365371 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435372 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5373 mock_quic_data.AddWrite(
5374 SYNCHRONOUS,
5375 ConstructClientRequestHeadersPacket(
5376 2, GetNthClientInitiatedStreamId(0), true, true,
5377 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5378 mock_quic_data.AddRead(ASYNC, ConstructServerRstPacket(
5379 1, false, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:525380 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485381 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5382 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5383
5384 // The non-alternate protocol job needs to hang in order to guarantee that
5385 // the alternate-protocol job will "win".
5386 AddHangingNonAlternateProtocolSocketData();
5387
5388 // In order for a new QUIC session to be established via alternate-protocol
5389 // without racing an HTTP connection, we need the host resolution to happen
5390 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5391 // connection to the the server, in this test we require confirmation
5392 // before encrypting so the HTTP job will still start.
5393 host_resolver_.set_synchronous_mode(true);
5394 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5395 "");
5396 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5397 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105398 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585399 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5400 CompletionOnceCallback(), &request,
5401 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415402 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485403
5404 CreateSession();
5405 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275406 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485407
bnc691fda62016-08-12 00:43:165408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485409 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415410 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485412
5413 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525414 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485415 // Read the headers.
robpercival214763f2016-07-01 23:27:015416 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485417}
5418
[email protected]1e960032013-12-20 19:00:205419TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305420 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525421 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585422 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305423 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505424 MockRead(ASYNC, close->data(), close->length()),
5425 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5426 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305427 };
Ryan Sleevib8d7ea02018-05-07 20:01:015428 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305429 socket_factory_.AddSocketDataProvider(&quic_data);
5430
5431 // Main job which will succeed even though the alternate job fails.
5432 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025433 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5434 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5435 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305436
Ryan Sleevib8d7ea02018-05-07 20:01:015437 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305438 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565439 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305440
rch3f4b8452016-02-23 16:59:325441 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275442 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[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(
5518 1, GetNthClientInitiatedStreamId(0), true, true,
5519 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5520 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5521 1, GetNthClientInitiatedStreamId(0), false,
5522 false, GetResponseHeaders("200 OK")));
5523 mock_quic_data.AddRead(
5524 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5525 false, true, 0, "hello!"));
5526 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505527 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5528 mock_quic_data.AddRead(ASYNC, 0); // EOF
5529
5530 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5531 // No HTTP data is mocked as TCP job never starts in this case.
5532
5533 CreateSession();
5534 // QuicStreamFactory by default requires confirmation on construction.
5535 session_->quic_stream_factory()->set_require_confirmation(true);
5536
Ryan Hamilton9835e662018-08-02 05:36:275537 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505538
5539 // Stall host resolution so that QUIC job will not succeed synchronously.
5540 // Socket will not be configured immediately and QUIC support is not sorted
5541 // out, TCP job will still be delayed as server properties indicates QUIC
5542 // support on last IP address.
5543 host_resolver_.set_synchronous_mode(false);
5544
5545 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5546 TestCompletionCallback callback;
5547 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5548 IsError(ERR_IO_PENDING));
5549 // Complete host resolution in next message loop so that QUIC job could
5550 // proceed.
5551 base::RunLoop().RunUntilIdle();
5552 EXPECT_THAT(callback.WaitForResult(), IsOk());
5553
5554 CheckWasQuicResponse(&trans);
5555 CheckResponseData(&trans, "hello!");
5556}
5557
5558TEST_P(QuicNetworkTransactionTest,
5559 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5560 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5561 // was recently supported on a different IP address on start.
5562
5563 // Set QUIC support on the last IP address, which is different with the local
5564 // IP address. Require confirmation mode will remain when local IP address is
5565 // sorted out after we configure the UDP socket.
5566 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5567
5568 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525569 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505570 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435571 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5572 mock_quic_data.AddWrite(
5573 SYNCHRONOUS,
5574 ConstructClientRequestHeadersPacket(
5575 2, GetNthClientInitiatedStreamId(0), true, true,
5576 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5577 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5578 1, GetNthClientInitiatedStreamId(0), false,
5579 false, GetResponseHeaders("200 OK")));
5580 mock_quic_data.AddRead(
5581 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5582 false, true, 0, "hello!"));
5583 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505584 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5585 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5586 // No HTTP data is mocked as TCP job will be delayed and never starts.
5587
5588 CreateSession();
5589 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275590 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505591
5592 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5593 // Socket will not be configured immediately and QUIC support is not sorted
5594 // out, TCP job will still be delayed as server properties indicates QUIC
5595 // support on last IP address.
5596 host_resolver_.set_synchronous_mode(false);
5597
5598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5599 TestCompletionCallback callback;
5600 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5601 IsError(ERR_IO_PENDING));
5602
5603 // Complete host resolution in next message loop so that QUIC job could
5604 // proceed.
5605 base::RunLoop().RunUntilIdle();
5606 // Explicitly confirm the handshake so that QUIC job could succeed.
5607 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525608 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505609 EXPECT_THAT(callback.WaitForResult(), IsOk());
5610
5611 CheckWasQuicResponse(&trans);
5612 CheckResponseData(&trans, "hello!");
5613}
5614
Ryan Hamilton75f197262017-08-17 14:00:075615TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5616 // Test that NetErrorDetails is correctly populated, even if the
5617 // handshake has not yet been confirmed and no stream has been created.
5618
5619 // QUIC job will pause. When resumed, it will fail.
5620 MockQuicData mock_quic_data;
5621 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5622 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5623 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5624
5625 // Main job will also fail.
5626 MockRead http_reads[] = {
5627 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5628 };
5629
Ryan Sleevib8d7ea02018-05-07 20:01:015630 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075631 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5632 socket_factory_.AddSocketDataProvider(&http_data);
5633 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5634
5635 AddHangingNonAlternateProtocolSocketData();
5636 CreateSession();
5637 // Require handshake confirmation to ensure that no QUIC streams are
5638 // created, and to ensure that the TCP job does not wait for the QUIC
5639 // job to fail before it starts.
5640 session_->quic_stream_factory()->set_require_confirmation(true);
5641
Ryan Hamilton9835e662018-08-02 05:36:275642 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075643 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5644 TestCompletionCallback callback;
5645 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5646 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5647 // Allow the TCP job to fail.
5648 base::RunLoop().RunUntilIdle();
5649 // Now let the QUIC job fail.
5650 mock_quic_data.Resume();
5651 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5652 ExpectQuicAlternateProtocolMapping();
5653 NetErrorDetails details;
5654 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525655 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075656}
5657
[email protected]1e960032013-12-20 19:00:205658TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455659 // Alternate-protocol job
5660 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025661 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455662 };
Ryan Sleevib8d7ea02018-05-07 20:01:015663 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455664 socket_factory_.AddSocketDataProvider(&quic_data);
5665
[email protected]c92c1b52014-05-31 04:16:065666 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015667 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065668 socket_factory_.AddSocketDataProvider(&quic_data2);
5669
[email protected]4d283b32013-10-17 12:57:275670 // Final job that will proceed when the QUIC job fails.
5671 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025672 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5673 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5674 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275675
Ryan Sleevib8d7ea02018-05-07 20:01:015676 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275677 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565678 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275679
rtennetiafccbc062016-05-16 18:21:145680 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325681 CreateSession();
[email protected]77c6c162013-08-17 02:57:455682
Ryan Hamilton9835e662018-08-02 05:36:275683 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455684
[email protected]4d283b32013-10-17 12:57:275685 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455686
5687 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275688
rch37de576c2015-05-17 20:28:175689 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5690 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455691}
5692
[email protected]93b31772014-06-19 08:03:355693TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035694 // Alternate-protocol job
5695 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595696 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035697 };
Ryan Sleevib8d7ea02018-05-07 20:01:015698 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035699 socket_factory_.AddSocketDataProvider(&quic_data);
5700
5701 // Main job that will proceed when the QUIC job fails.
5702 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025703 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5704 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5705 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035706
Ryan Sleevib8d7ea02018-05-07 20:01:015707 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035708 socket_factory_.AddSocketDataProvider(&http_data);
5709
rtennetib8e80fb2016-05-16 00:12:095710 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325711 CreateSession();
[email protected]65768442014-06-06 23:37:035712
Ryan Hamilton9835e662018-08-02 05:36:275713 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035714
5715 SendRequestAndExpectHttpResponse("hello from http");
5716}
5717
[email protected]eb71ab62014-05-23 07:57:535718TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335719 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015720 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495721 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335722 socket_factory_.AddSocketDataProvider(&quic_data);
5723
5724 // Main job which will succeed even though the alternate job fails.
5725 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025726 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5727 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5728 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335729
Ryan Sleevib8d7ea02018-05-07 20:01:015730 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335731 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565732 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335733
rch3f4b8452016-02-23 16:59:325734 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275735 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335736 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535737
5738 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335739}
5740
[email protected]4fee9672014-01-08 14:47:155741TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155742 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435743 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
5744 mock_quic_data.AddWrite(SYNCHRONOUS,
5745 ConstructClientRequestHeadersPacket(
5746 1, GetNthClientInitiatedStreamId(0), true, true,
5747 GetRequestHeaders("GET", "https", "/")));
5748 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
rcha5399e02015-04-21 19:32:045749 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155750
5751 // When the QUIC connection fails, we will try the request again over HTTP.
5752 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485753 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565754 MockRead("hello world"),
5755 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5756 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155757
Ryan Sleevib8d7ea02018-05-07 20:01:015758 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155759 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565760 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155761
5762 // In order for a new QUIC session to be established via alternate-protocol
5763 // without racing an HTTP connection, we need the host resolution to happen
5764 // synchronously.
5765 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295766 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565767 "");
rch9ae5b3b2016-02-11 00:36:295768 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155769 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105770 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585771 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5772 CompletionOnceCallback(), &request,
5773 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415774 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155775
rch3f4b8452016-02-23 16:59:325776 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275777 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]4fee9672014-01-08 14:47:155778 SendRequestAndExpectHttpResponse("hello world");
5779}
5780
tbansalc3308d72016-08-27 10:25:045781// For an alternative proxy that supports QUIC, test that the request is
5782// successfully fetched by the main job when the alternate proxy job encounters
5783// an error.
5784TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5785 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5786}
5787TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5788 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5789}
5790TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5791 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5792}
5793TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5794 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5795}
5796TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5797 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5798}
5799TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5800 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5801}
5802TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5803 TestAlternativeProxy(ERR_IO_PENDING);
5804}
5805TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5806 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5807}
5808
5809TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5810 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435811 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
5812 mock_quic_data.AddWrite(SYNCHRONOUS,
5813 ConstructClientRequestHeadersPacket(
5814 1, GetNthClientInitiatedStreamId(0), true, true,
5815 GetRequestHeaders("GET", "https", "/")));
5816 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045817 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5818
5819 // When the QUIC connection fails, we will try the request again over HTTP.
5820 MockRead http_reads[] = {
5821 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5822 MockRead("hello world"),
5823 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5824 MockRead(ASYNC, OK)};
5825
Ryan Sleevib8d7ea02018-05-07 20:01:015826 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045827 socket_factory_.AddSocketDataProvider(&http_data);
5828 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5829
5830 TestProxyDelegate test_proxy_delegate;
5831 const HostPortPair host_port_pair("myproxy.org", 443);
5832 test_proxy_delegate.set_alternative_proxy_server(
5833 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5834 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5835
Ramin Halavatica8d5252018-03-12 05:33:495836 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5837 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525838 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045839 request_.url = GURL("http://mail.example.org/");
5840
5841 // In order for a new QUIC session to be established via alternate-protocol
5842 // without racing an HTTP connection, we need the host resolution to happen
5843 // synchronously.
5844 host_resolver_.set_synchronous_mode(true);
5845 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
5846 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
5847 AddressList address;
5848 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585849 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5850 CompletionOnceCallback(), &request,
5851 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415852 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:045853
5854 CreateSession();
5855 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595856 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165857 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045858}
5859
bnc508835902015-05-12 20:10:295860TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585861 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385862 EXPECT_FALSE(
5863 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295864 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525865 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365866 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435867 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5868 mock_quic_data.AddWrite(
5869 SYNCHRONOUS,
5870 ConstructClientRequestHeadersPacket(
5871 2, GetNthClientInitiatedStreamId(0), true, true,
5872 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
5873 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
5874 1, GetNthClientInitiatedStreamId(0), false,
5875 false, GetResponseHeaders("200 OK")));
5876 mock_quic_data.AddRead(
5877 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
5878 false, true, 0, "hello!"));
5879 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505880 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295881 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5882
bncb07c05532015-05-14 19:07:205883 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095884 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325885 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275886 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295887 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385888 EXPECT_TRUE(
5889 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295890}
5891
zhongyi363c91c2017-03-23 23:16:085892// TODO(zhongyi): disabled this broken test as it was not testing the correct
5893// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5894TEST_P(QuicNetworkTransactionTest,
5895 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275896 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595897 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495898 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045899
5900 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045901
5902 test_proxy_delegate.set_alternative_proxy_server(
5903 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525904 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045905
5906 request_.url = GURL("http://mail.example.org/");
5907
5908 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5909 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015910 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:045911 socket_factory_.AddSocketDataProvider(&socket_data);
5912
5913 // The non-alternate protocol job needs to hang in order to guarantee that
5914 // the alternate-protocol job will "win".
5915 AddHangingNonAlternateProtocolSocketData();
5916
5917 CreateSession();
5918 request_.method = "POST";
5919 ChunkedUploadDataStream upload_data(0);
5920 upload_data.AppendData("1", 1, true);
5921
5922 request_.upload_data_stream = &upload_data;
5923
5924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5925 TestCompletionCallback callback;
5926 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5928 EXPECT_NE(OK, callback.WaitForResult());
5929
5930 // Verify that the alternative proxy server is not marked as broken.
5931 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5932
5933 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:595934 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:275935
5936 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
5937 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
5938 1);
tbansalc3308d72016-08-27 10:25:045939}
5940
rtenneti56977812016-01-15 19:26:565941TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:415942 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:575943 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:565944
5945 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
5946 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:015947 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:565948 socket_factory_.AddSocketDataProvider(&socket_data);
5949
rtennetib8e80fb2016-05-16 00:12:095950 // The non-alternate protocol job needs to hang in order to guarantee that
5951 // the alternate-protocol job will "win".
5952 AddHangingNonAlternateProtocolSocketData();
5953
rtenneti56977812016-01-15 19:26:565954 CreateSession();
5955 request_.method = "POST";
5956 ChunkedUploadDataStream upload_data(0);
5957 upload_data.AppendData("1", 1, true);
5958
5959 request_.upload_data_stream = &upload_data;
5960
bnc691fda62016-08-12 00:43:165961 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:565962 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165963 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:565965 EXPECT_NE(OK, callback.WaitForResult());
5966}
5967
rche11300ef2016-09-02 01:44:285968TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:485969 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:285970 ScopedMockNetworkChangeNotifier network_change_notifier;
5971 MockNetworkChangeNotifier* mock_ncn =
5972 network_change_notifier.mock_network_change_notifier();
5973 mock_ncn->ForceNetworkHandlesSupported();
5974 mock_ncn->SetConnectedNetworksList(
5975 {kDefaultNetworkForTests, kNewNetworkForTests});
5976
mmenke6ddfbea2017-05-31 21:48:415977 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:285978 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:315979 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:285980
5981 MockQuicData socket_data;
5982 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525983 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:435984 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
5985 socket_data.AddWrite(SYNCHRONOUS,
5986 ConstructClientRequestHeadersPacket(
5987 2, GetNthClientInitiatedStreamId(0), true, false,
5988 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:285989 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
5990 socket_data.AddSocketDataToFactory(&socket_factory_);
5991
5992 MockQuicData socket_data2;
5993 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
5994 socket_data2.AddSocketDataToFactory(&socket_factory_);
5995
5996 // The non-alternate protocol job needs to hang in order to guarantee that
5997 // the alternate-protocol job will "win".
5998 AddHangingNonAlternateProtocolSocketData();
5999
6000 CreateSession();
6001 request_.method = "POST";
6002 ChunkedUploadDataStream upload_data(0);
6003
6004 request_.upload_data_stream = &upload_data;
6005
rdsmith1d343be52016-10-21 20:37:506006 std::unique_ptr<HttpNetworkTransaction> trans(
6007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286008 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506009 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286010 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6011
6012 base::RunLoop().RunUntilIdle();
6013 upload_data.AppendData("1", 1, true);
6014 base::RunLoop().RunUntilIdle();
6015
6016 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506017 trans.reset();
rche11300ef2016-09-02 01:44:286018 session_.reset();
6019}
6020
Ryan Hamilton4b3574532017-10-30 20:17:256021TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6022 session_params_.origins_to_force_quic_on.insert(
6023 HostPortPair::FromString("mail.example.org:443"));
6024
6025 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526026 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436027 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256028 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Zhongyi Shi32f2fd02018-04-16 18:23:436029 socket_data.AddWrite(SYNCHRONOUS,
6030 ConstructClientRequestHeadersPacket(
6031 2, GetNthClientInitiatedStreamId(0), true, true,
6032 GetRequestHeaders("GET", "https", "/"), &offset));
6033 socket_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6034 1, GetNthClientInitiatedStreamId(0), false,
6035 false, GetResponseHeaders("200 OK")));
6036 socket_data.AddRead(
6037 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6038 false, true, 0, "hello!"));
6039 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);
Zhongyi Shi32f2fd02018-04-16 18:23:436062 socket_data.AddWrite(SYNCHRONOUS,
6063 ConstructClientRequestHeadersPacket(
6064 2, GetNthClientInitiatedStreamId(0), true, true,
6065 GetRequestHeaders("GET", "https", "/"), &offset));
6066 socket_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6067 1, GetNthClientInitiatedStreamId(0), false,
6068 false, GetResponseHeaders("200 OK")));
6069 socket_data.AddRead(
6070 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6071 false, true, 0, "hello!"));
6072 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256073 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166074 socket_data.AddWrite(
6075 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6076 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6077 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256078
6079 socket_data.AddSocketDataToFactory(&socket_factory_);
6080
6081 CreateSession();
6082
6083 SendRequestAndExpectQuicResponse("hello!");
6084 session_.reset();
6085}
6086
Ryan Hamilton9edcf1a2017-11-22 05:55:176087TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486088 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256089 session_params_.origins_to_force_quic_on.insert(
6090 HostPortPair::FromString("mail.example.org:443"));
6091
6092 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526093 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256094 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436095 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176096 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256097 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6098 }
6099 socket_data.AddSocketDataToFactory(&socket_factory_);
6100
6101 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176102 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6103 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6104 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6105 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256106
Ryan Hamilton8d9ee76e2018-05-29 23:52:526107 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256108 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6109 TestCompletionCallback callback;
6110 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176112 while (!callback.have_result()) {
6113 base::RunLoop().RunUntilIdle();
6114 quic_task_runner_->RunUntilIdle();
6115 }
6116 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256117 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176118 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6119 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6120 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526121 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6122 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256123}
6124
Ryan Hamilton9edcf1a2017-11-22 05:55:176125TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486126 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256127 session_params_.origins_to_force_quic_on.insert(
6128 HostPortPair::FromString("mail.example.org:443"));
6129
6130 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526131 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256132 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436133 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176134 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256135 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6136 }
6137 socket_data.AddSocketDataToFactory(&socket_factory_);
6138
6139 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176140 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6141 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6142 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6143 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256144
Ryan Hamilton8d9ee76e2018-05-29 23:52:526145 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256146 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6147 TestCompletionCallback callback;
6148 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6149 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176150 while (!callback.have_result()) {
6151 base::RunLoop().RunUntilIdle();
6152 quic_task_runner_->RunUntilIdle();
6153 }
6154 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256155 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176156 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6157 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6158 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526159 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6160 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256161}
6162
Cherie Shi7596de632018-02-22 07:28:186163TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486164 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186165 session_params_.origins_to_force_quic_on.insert(
6166 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526167 const quic::QuicString error_details =
6168 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6169 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186170
6171 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526172 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186173 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436174 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186175 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6176 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526177 socket_data.AddWrite(
6178 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6179 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186180 socket_data.AddSocketDataToFactory(&socket_factory_);
6181
6182 CreateSession();
6183
6184 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6185 TestCompletionCallback callback;
6186 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6188 base::RunLoop().RunUntilIdle();
6189 ASSERT_TRUE(callback.have_result());
6190 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6191 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6192 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6193}
6194
ckrasic769733c2016-06-30 00:42:136195// Adds coverage to catch regression such as https://crbug.com/622043
6196TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416197 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136198 HostPortPair::FromString("mail.example.org:443"));
6199
6200 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526201 quic::QuicStreamOffset header_stream_offset = 0;
6202 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436203 mock_quic_data.AddWrite(
6204 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6205 &header_stream_offset));
6206 mock_quic_data.AddWrite(
6207 SYNCHRONOUS,
6208 ConstructClientRequestHeadersPacket(
6209 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
6210 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526211 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436212 mock_quic_data.AddRead(
6213 ASYNC,
6214 ConstructServerPushPromisePacket(
6215 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
6216 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6217 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576218 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266219 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:436220 mock_quic_data.AddWrite(
6221 SYNCHRONOUS,
6222 ConstructClientPriorityPacket(client_packet_number++, false,
6223 GetNthServerInitiatedStreamId(0),
6224 GetNthClientInitiatedStreamId(0),
6225 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576226 }
Zhongyi Shi32f2fd02018-04-16 18:23:436227 mock_quic_data.AddRead(
6228 ASYNC, ConstructServerResponseHeadersPacket(
6229 2, GetNthClientInitiatedStreamId(0), false, false,
6230 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576231 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436232 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6233 mock_quic_data.AddRead(
6234 ASYNC, ConstructServerResponseHeadersPacket(
6235 3, GetNthServerInitiatedStreamId(0), false, false,
6236 GetResponseHeaders("200 OK"), &server_header_offset));
6237 mock_quic_data.AddRead(
6238 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
6239 false, true, 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576240 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436241 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
6242 mock_quic_data.AddRead(
6243 ASYNC, ConstructServerDataPacket(5, GetNthServerInitiatedStreamId(0),
6244 false, true, 0, "and hello!"));
6245 mock_quic_data.AddWrite(
6246 SYNCHRONOUS, ConstructClientAckAndRstPacket(
6247 client_packet_number++, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526248 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136249 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6250 mock_quic_data.AddRead(ASYNC, 0); // EOF
6251 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6252
6253 // The non-alternate protocol job needs to hang in order to guarantee that
6254 // the alternate-protocol job will "win".
6255 AddHangingNonAlternateProtocolSocketData();
6256
6257 CreateSession();
6258
6259 // PUSH_PROMISE handling in the http layer gets exercised here.
6260 SendRequestAndExpectQuicResponse("hello!");
6261
6262 request_.url = GURL("https://mail.example.org/pushed.jpg");
6263 SendRequestAndExpectQuicResponse("and hello!");
6264
6265 // Check that the NetLog was filled reasonably.
6266 TestNetLogEntry::List entries;
6267 net_log_.GetEntries(&entries);
6268 EXPECT_LT(0u, entries.size());
6269
6270 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6271 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006272 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6273 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136274 EXPECT_LT(0, pos);
6275}
6276
rch56ec40a2017-06-23 14:48:446277// Regression test for http://crbug.com/719461 in which a promised stream
6278// is closed before the pushed headers arrive, but after the connection
6279// is closed and before the callbacks are executed.
6280TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486281 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446282 session_params_.origins_to_force_quic_on.insert(
6283 HostPortPair::FromString("mail.example.org:443"));
6284
6285 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526286 quic::QuicStreamOffset header_stream_offset = 0;
6287 quic::QuicPacketNumber client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446288 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436289 mock_quic_data.AddWrite(
6290 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6291 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446292 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436293 mock_quic_data.AddWrite(
6294 SYNCHRONOUS,
6295 ConstructClientRequestHeadersPacket(
6296 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
6297 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526298 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446299 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436300 mock_quic_data.AddRead(
6301 ASYNC,
6302 ConstructServerPushPromisePacket(
6303 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
6304 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6305 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576306 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266307 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:436308 mock_quic_data.AddWrite(
6309 SYNCHRONOUS,
6310 ConstructClientPriorityPacket(client_packet_number++, false,
6311 GetNthServerInitiatedStreamId(0),
6312 GetNthClientInitiatedStreamId(0),
6313 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576314 }
rch56ec40a2017-06-23 14:48:446315 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436316 mock_quic_data.AddRead(
6317 ASYNC, ConstructServerResponseHeadersPacket(
6318 2, GetNthClientInitiatedStreamId(0), false, false,
6319 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446320 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576321 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436322 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446323 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436324 mock_quic_data.AddRead(
6325 ASYNC, ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(0),
6326 false, true, 0, "hello!"));
rch56ec40a2017-06-23 14:48:446327 // Write error for the third request.
6328 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6329 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6330 mock_quic_data.AddRead(ASYNC, 0); // EOF
6331 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6332
6333 CreateSession();
6334
6335 // Send a request which triggers a push promise from the server.
6336 SendRequestAndExpectQuicResponse("hello!");
6337
6338 // Start a push transaction that will be cancelled after the connection
6339 // is closed, but before the callback is executed.
6340 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196341 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446342 session_.get());
6343 TestCompletionCallback callback2;
6344 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6346 base::RunLoop().RunUntilIdle();
6347
6348 // Cause the connection to close on a write error.
6349 HttpRequestInfo request3;
6350 request3.method = "GET";
6351 request3.url = GURL("https://mail.example.org/");
6352 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106353 request3.traffic_annotation =
6354 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446355 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6356 TestCompletionCallback callback3;
6357 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6358 IsError(ERR_IO_PENDING));
6359
6360 base::RunLoop().RunUntilIdle();
6361
6362 // When |trans2| is destroyed, the underlying stream will be closed.
6363 EXPECT_FALSE(callback2.have_result());
6364 trans2 = nullptr;
6365
6366 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6367}
6368
ckrasicda193a82016-07-09 00:39:366369TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416370 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366371 HostPortPair::FromString("mail.example.org:443"));
6372
6373 MockQuicData mock_quic_data;
6374
Ryan Hamilton8d9ee76e2018-05-29 23:52:526375 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436376 mock_quic_data.AddWrite(SYNCHRONOUS,
6377 ConstructInitialSettingsPacket(1, &offset));
ckrasicda193a82016-07-09 00:39:366378
Zhongyi Shi32f2fd02018-04-16 18:23:436379 mock_quic_data.AddWrite(
6380 SYNCHRONOUS,
6381 ConstructClientRequestHeadersAndDataFramesPacket(
6382 2, GetNthClientInitiatedStreamId(0), true, true, DEFAULT_PRIORITY,
6383 GetRequestHeaders("POST", "https", "/"), 0, &offset, nullptr, {"1"}));
ckrasicda193a82016-07-09 00:39:366384
Zhongyi Shi32f2fd02018-04-16 18:23:436385 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6386 1, GetNthClientInitiatedStreamId(0), false,
6387 false, GetResponseHeaders("200 OK")));
ckrasicda193a82016-07-09 00:39:366388
Zhongyi Shi32f2fd02018-04-16 18:23:436389 mock_quic_data.AddRead(
6390 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6391 false, true, 0, "hello!"));
ckrasicda193a82016-07-09 00:39:366392
Zhongyi Shi32f2fd02018-04-16 18:23:436393 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366394
6395 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6396 mock_quic_data.AddRead(ASYNC, 0); // EOF
6397 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6398
6399 // The non-alternate protocol job needs to hang in order to guarantee that
6400 // the alternate-protocol job will "win".
6401 AddHangingNonAlternateProtocolSocketData();
6402
6403 CreateSession();
6404 request_.method = "POST";
6405 ChunkedUploadDataStream upload_data(0);
6406 upload_data.AppendData("1", 1, true);
6407
6408 request_.upload_data_stream = &upload_data;
6409
6410 SendRequestAndExpectQuicResponse("hello!");
6411}
6412
allada71b2efb2016-09-09 04:57:486413class QuicURLRequestContext : public URLRequestContext {
6414 public:
6415 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6416 MockClientSocketFactory* socket_factory)
6417 : storage_(this) {
6418 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076419 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046420 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486421 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046422 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596423 storage_.set_proxy_resolution_service(
6424 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076425 storage_.set_ssl_config_service(
6426 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486427 storage_.set_http_auth_handler_factory(
6428 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6429 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076430 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046431 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486432 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046433 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6434 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6435 false));
allada71b2efb2016-09-09 04:57:486436 }
6437
6438 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6439
6440 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6441
6442 private:
6443 MockClientSocketFactory* socket_factory_;
6444 URLRequestContextStorage storage_;
6445};
6446
6447TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416448 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486449 HostPortPair::FromString("mail.example.org:443"));
6450
6451 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526452 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366453 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436454 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136455 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486456 headers["user-agent"] = "";
6457 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436458 mock_quic_data.AddWrite(SYNCHRONOUS,
6459 ConstructClientRequestHeadersPacket(
6460 2, GetNthClientInitiatedStreamId(0), true, true,
6461 std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486462
Ryan Hamilton8d9ee76e2018-05-29 23:52:526463 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436464 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6465 1, GetNthClientInitiatedStreamId(0), false,
6466 false, GetResponseHeaders("200 OK"),
6467 &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486468
ckrasicbf2f59c2017-05-04 23:54:366469 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436470 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6471 false, true, 0, "Main Resource Data"));
6472 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486473
6474 mock_quic_data.AddRead(ASYNC, 0); // EOF
6475
6476 CreateSession();
6477
6478 TestDelegate delegate;
6479 QuicURLRequestContext quic_url_request_context(std::move(session_),
6480 &socket_factory_);
6481
6482 mock_quic_data.AddSocketDataToFactory(
6483 &quic_url_request_context.socket_factory());
6484 TestNetworkDelegate network_delegate;
6485 quic_url_request_context.set_network_delegate(&network_delegate);
6486
6487 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296488 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6489 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486490 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6491 &ssl_data_);
6492
6493 request->Start();
Wez2a31b222018-06-07 22:07:156494 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486495
6496 EXPECT_LT(0, request->GetTotalSentBytes());
6497 EXPECT_LT(0, request->GetTotalReceivedBytes());
6498 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6499 request->GetTotalSentBytes());
6500 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6501 request->GetTotalReceivedBytes());
6502 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6503 request->raw_header_size());
Wez0e717112018-06-18 23:09:226504
6505 // Pump the message loop to allow all data to be consumed.
6506 base::RunLoop().RunUntilIdle();
6507
allada71b2efb2016-09-09 04:57:486508 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6509 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6510}
6511
6512TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416513 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486514 HostPortPair::FromString("mail.example.org:443"));
6515
6516 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526517 quic::QuicStreamOffset header_stream_offset = 0;
6518 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436519 mock_quic_data.AddWrite(
6520 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6521 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136522 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486523 headers["user-agent"] = "";
6524 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436525 mock_quic_data.AddWrite(
6526 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6527 client_packet_number++, GetNthClientInitiatedStreamId(0),
6528 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486529
Ryan Hamilton8d9ee76e2018-05-29 23:52:526530 quic::QuicStreamOffset server_header_offset = 0;
6531 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486532
Zhongyi Shi32f2fd02018-04-16 18:23:436533 mock_quic_data.AddRead(
6534 ASYNC,
6535 ConstructServerPushPromisePacket(
6536 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
6537 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
6538 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486539
Yixin Wangb470bc882018-02-15 18:43:576540 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266541 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:436542 mock_quic_data.AddWrite(
6543 SYNCHRONOUS,
6544 ConstructClientPriorityPacket(client_packet_number++, false,
6545 GetNthServerInitiatedStreamId(0),
6546 GetNthClientInitiatedStreamId(0),
6547 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576548 }
6549
allada71b2efb2016-09-09 04:57:486550 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436551 mock_quic_data.AddRead(
6552 ASYNC, ConstructServerResponseHeadersPacket(
6553 2, GetNthClientInitiatedStreamId(0), false, false,
6554 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486555 expected_raw_header_response_size =
6556 server_header_offset - expected_raw_header_response_size;
6557
Yixin Wangb470bc882018-02-15 18:43:576558 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436559 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486560
ckrasicbf2f59c2017-05-04 23:54:366561 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436562 ASYNC, ConstructServerResponseHeadersPacket(
6563 3, GetNthServerInitiatedStreamId(0), false, false,
6564 GetResponseHeaders("200 OK"), &server_header_offset));
6565 mock_quic_data.AddRead(
6566 ASYNC, ConstructServerDataPacket(4, GetNthServerInitiatedStreamId(0),
6567 false, true, 0, "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486568
Yixin Wangb470bc882018-02-15 18:43:576569 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436570 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
ckrasicbf2f59c2017-05-04 23:54:366571 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436572 ASYNC, ConstructServerDataPacket(5, GetNthClientInitiatedStreamId(0),
6573 false, true, 0, "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486574
Zhongyi Shi32f2fd02018-04-16 18:23:436575 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486576
6577 CreateSession();
6578
6579 TestDelegate delegate;
6580 QuicURLRequestContext quic_url_request_context(std::move(session_),
6581 &socket_factory_);
6582
6583 mock_quic_data.AddSocketDataToFactory(
6584 &quic_url_request_context.socket_factory());
6585 TestNetworkDelegate network_delegate;
6586 quic_url_request_context.set_network_delegate(&network_delegate);
6587
6588 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296589 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6590 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486591 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6592 &ssl_data_);
6593
6594 request->Start();
Wez2a31b222018-06-07 22:07:156595 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486596
6597 EXPECT_LT(0, request->GetTotalSentBytes());
6598 EXPECT_LT(0, request->GetTotalReceivedBytes());
6599 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6600 request->GetTotalSentBytes());
6601 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6602 request->GetTotalReceivedBytes());
6603 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6604 request->raw_header_size());
Wez0e717112018-06-18 23:09:226605
6606 // Pump the message loop to allow all data to be consumed.
6607 base::RunLoop().RunUntilIdle();
6608
allada71b2efb2016-09-09 04:57:486609 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6610 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6611}
6612
Yixin Wang10f477ed2017-11-21 04:20:206613TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6614 session_params_.quic_host_whitelist.insert("mail.example.org");
6615
6616 MockRead http_reads[] = {
6617 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6618 MockRead("hello world"),
6619 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6620 MockRead(ASYNC, OK)};
6621
Ryan Sleevib8d7ea02018-05-07 20:01:016622 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206623 socket_factory_.AddSocketDataProvider(&http_data);
6624 AddCertificate(&ssl_data_);
6625 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6626
6627 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526628 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206629 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436630 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6631 mock_quic_data.AddWrite(
6632 SYNCHRONOUS,
6633 ConstructClientRequestHeadersPacket(
6634 2, GetNthClientInitiatedStreamId(0), true, true,
6635 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
6636 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
6637 1, GetNthClientInitiatedStreamId(0), false,
6638 false, GetResponseHeaders("200 OK")));
6639 mock_quic_data.AddRead(
6640 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
6641 false, true, 0, "hello!"));
6642 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206643 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6644 mock_quic_data.AddRead(ASYNC, 0); // EOF
6645
6646 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6647
6648 AddHangingNonAlternateProtocolSocketData();
6649 CreateSession();
6650
6651 SendRequestAndExpectHttpResponse("hello world");
6652 SendRequestAndExpectQuicResponse("hello!");
6653}
6654
6655TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6656 session_params_.quic_host_whitelist.insert("mail.example.com");
6657
6658 MockRead http_reads[] = {
6659 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6660 MockRead("hello world"),
6661 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6662 MockRead(ASYNC, OK)};
6663
Ryan Sleevib8d7ea02018-05-07 20:01:016664 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206665 socket_factory_.AddSocketDataProvider(&http_data);
6666 AddCertificate(&ssl_data_);
6667 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6668 socket_factory_.AddSocketDataProvider(&http_data);
6669 AddCertificate(&ssl_data_);
6670 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6671
6672 AddHangingNonAlternateProtocolSocketData();
6673 CreateSession();
6674
6675 SendRequestAndExpectHttpResponse("hello world");
6676 SendRequestAndExpectHttpResponse("hello world");
6677}
6678
bnc359ed2a2016-04-29 20:43:456679class QuicNetworkTransactionWithDestinationTest
6680 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016681 public ::testing::WithParamInterface<PoolingTestParams>,
6682 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456683 protected:
6684 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556685 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056686 client_headers_include_h2_stream_dependency_(
6687 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526688 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456689 destination_type_(GetParam().destination_type),
6690 cert_transparency_verifier_(new MultiLogCTVerifier()),
6691 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596692 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456693 auth_handler_factory_(
6694 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6695 random_generator_(0),
6696 ssl_data_(ASYNC, OK) {}
6697
6698 void SetUp() override {
6699 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556700 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456701
mmenke6ddfbea2017-05-31 21:48:416702 HttpNetworkSession::Params session_params;
6703 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346704 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446705 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056706 session_params.quic_headers_include_h2_stream_dependency =
6707 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416708
6709 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456710
Ryan Hamilton8d9ee76e2018-05-29 23:52:526711 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416712 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456713
6714 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276715 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416716 session_context.quic_crypto_client_stream_factory =
6717 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456718
mmenke6ddfbea2017-05-31 21:48:416719 session_context.quic_random = &random_generator_;
6720 session_context.client_socket_factory = &socket_factory_;
6721 session_context.host_resolver = &host_resolver_;
6722 session_context.cert_verifier = &cert_verifier_;
6723 session_context.transport_security_state = &transport_security_state_;
6724 session_context.cert_transparency_verifier =
6725 cert_transparency_verifier_.get();
6726 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6727 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456728 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416729 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596730 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416731 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6732 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456733
mmenke6ddfbea2017-05-31 21:48:416734 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456735 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456736 }
6737
6738 void TearDown() override {
6739 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6740 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556741 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456742 PlatformTest::TearDown();
6743 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556744 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406745 session_.reset();
bnc359ed2a2016-04-29 20:43:456746 }
6747
zhongyie537a002017-06-27 16:48:216748 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456749 HostPortPair destination;
6750 switch (destination_type_) {
6751 case SAME_AS_FIRST:
6752 destination = HostPortPair(origin1_, 443);
6753 break;
6754 case SAME_AS_SECOND:
6755 destination = HostPortPair(origin2_, 443);
6756 break;
6757 case DIFFERENT:
6758 destination = HostPortPair(kDifferentHostname, 443);
6759 break;
6760 }
bnc3472afd2016-11-17 15:27:216761 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456762 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216763 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456764 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446765 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456766 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526767 std::unique_ptr<quic::QuicEncryptedPacket>
6768 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6769 quic::QuicStreamId stream_id,
6770 bool should_include_version,
6771 quic::QuicStreamOffset* offset,
6772 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486773 return ConstructClientRequestHeadersPacket(
6774 packet_number, stream_id, should_include_version, 0, offset, maker);
6775 }
bnc359ed2a2016-04-29 20:43:456776
Ryan Hamilton8d9ee76e2018-05-29 23:52:526777 std::unique_ptr<quic::QuicEncryptedPacket>
6778 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6779 quic::QuicStreamId stream_id,
6780 bool should_include_version,
6781 quic::QuicStreamId parent_stream_id,
6782 quic::QuicStreamOffset* offset,
6783 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136784 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456785 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136786 spdy::SpdyHeaderBlock headers(
6787 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456788 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6789 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486790 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456791 }
6792
Ryan Hamilton8d9ee76e2018-05-29 23:52:526793 std::unique_ptr<quic::QuicEncryptedPacket>
6794 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6795 quic::QuicStreamId stream_id,
6796 bool should_include_version,
6797 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586798 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456799 packet_number, stream_id, should_include_version, nullptr, maker);
6800 }
6801
Ryan Hamilton8d9ee76e2018-05-29 23:52:526802 std::unique_ptr<quic::QuicEncryptedPacket>
6803 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6804 quic::QuicStreamId stream_id,
6805 quic::QuicStreamOffset* offset,
6806 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136807 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456808 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266809 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456810 }
6811
Ryan Hamilton8d9ee76e2018-05-29 23:52:526812 std::unique_ptr<quic::QuicEncryptedPacket>
6813 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6814 quic::QuicStreamId stream_id,
6815 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586816 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6817 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456818 }
6819
Ryan Hamilton8d9ee76e2018-05-29 23:52:526820 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
6821 quic::QuicPacketNumber packet_number,
6822 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456823 QuicTestPacketMaker* maker) {
6824 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
6825 "hello");
6826 }
6827
Ryan Hamilton8d9ee76e2018-05-29 23:52:526828 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
6829 quic::QuicPacketNumber packet_number,
6830 quic::QuicPacketNumber largest_received,
6831 quic::QuicPacketNumber smallest_received,
6832 quic::QuicPacketNumber least_unacked,
bnc359ed2a2016-04-29 20:43:456833 QuicTestPacketMaker* maker) {
6834 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496835 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456836 }
6837
Ryan Hamilton8d9ee76e2018-05-29 23:52:526838 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
6839 quic::QuicPacketNumber packet_number,
6840 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376841 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366842 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376843 }
6844
bnc359ed2a2016-04-29 20:43:456845 void AddRefusedSocketData() {
6846 std::unique_ptr<StaticSocketDataProvider> refused_data(
6847 new StaticSocketDataProvider());
6848 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6849 refused_data->set_connect_data(refused_connect);
6850 socket_factory_.AddSocketDataProvider(refused_data.get());
6851 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6852 }
6853
6854 void AddHangingSocketData() {
6855 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6856 new StaticSocketDataProvider());
6857 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6858 hanging_data->set_connect_data(hanging_connect);
6859 socket_factory_.AddSocketDataProvider(hanging_data.get());
6860 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6861 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6862 }
6863
6864 bool AllDataConsumed() {
6865 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6866 if (!socket_data_ptr->AllReadDataConsumed() ||
6867 !socket_data_ptr->AllWriteDataConsumed()) {
6868 return false;
6869 }
6870 }
6871 return true;
6872 }
6873
6874 void SendRequestAndExpectQuicResponse(const std::string& host) {
6875 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6876 HttpRequestInfo request;
6877 std::string url("https://");
6878 url.append(host);
6879 request.url = GURL(url);
6880 request.load_flags = 0;
6881 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106882 request.traffic_annotation =
6883 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456884 TestCompletionCallback callback;
6885 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016886 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456887
6888 std::string response_data;
robpercival214763f2016-07-01 23:27:016889 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:456890 EXPECT_EQ("hello", response_data);
6891
6892 const HttpResponseInfo* response = trans.GetResponseInfo();
6893 ASSERT_TRUE(response != nullptr);
6894 ASSERT_TRUE(response->headers.get() != nullptr);
6895 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6896 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:526897 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:446898 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:456899 response->connection_info);
6900 EXPECT_EQ(443, response->socket_address.port());
6901 }
6902
Ryan Hamilton8d9ee76e2018-05-29 23:52:526903 quic::QuicStreamId GetNthClientInitiatedStreamId(int n) {
6904 return quic::test::GetNthClientInitiatedStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:366905 }
6906
Ryan Hamilton8d9ee76e2018-05-29 23:52:526907 quic::MockClock clock_;
6908 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:056909 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526910 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:456911 DestinationType destination_type_;
6912 std::string origin1_;
6913 std::string origin2_;
6914 std::unique_ptr<HttpNetworkSession> session_;
6915 MockClientSocketFactory socket_factory_;
6916 MockHostResolver host_resolver_;
6917 MockCertVerifier cert_verifier_;
6918 TransportSecurityState transport_security_state_;
6919 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:236920 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:456921 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:076922 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:596923 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:456924 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526925 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:456926 HttpServerPropertiesImpl http_server_properties_;
6927 BoundTestNetLog net_log_;
6928 MockCryptoClientStreamFactory crypto_client_stream_factory_;
6929 std::vector<std::unique_ptr<StaticSocketDataProvider>>
6930 static_socket_data_provider_vector_;
6931 SSLSocketDataProvider ssl_data_;
6932};
6933
Bence Békyce380cb2018-04-26 23:39:556934INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:456935 QuicNetworkTransactionWithDestinationTest,
6936 ::testing::ValuesIn(GetPoolingTestParams()));
6937
6938// A single QUIC request fails because the certificate does not match the origin
6939// hostname, regardless of whether it matches the alternative service hostname.
6940TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
6941 if (destination_type_ == DIFFERENT)
6942 return;
6943
6944 GURL url("https://mail.example.com/");
6945 origin1_ = url.host();
6946
6947 // Not used for requests, but this provides a test case where the certificate
6948 // is valid for the hostname of the alternative service.
6949 origin2_ = "mail.example.org";
6950
zhongyie537a002017-06-27 16:48:216951 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:456952
6953 scoped_refptr<X509Certificate> cert(
6954 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246955 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
6956 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:456957
6958 ProofVerifyDetailsChromium verify_details;
6959 verify_details.cert_verify_result.verified_cert = cert;
6960 verify_details.cert_verify_result.is_issued_by_known_root = true;
6961 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6962
6963 MockQuicData mock_quic_data;
6964 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
6965 mock_quic_data.AddRead(ASYNC, 0);
6966
6967 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6968
6969 AddRefusedSocketData();
6970
6971 HttpRequestInfo request;
6972 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:106973 request.traffic_annotation =
6974 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456975
6976 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6977 TestCompletionCallback callback;
6978 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016979 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:456980
6981 EXPECT_TRUE(AllDataConsumed());
6982}
6983
6984// First request opens QUIC session to alternative service. Second request
6985// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:526986// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:456987TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
6988 origin1_ = "mail.example.org";
6989 origin2_ = "news.example.org";
6990
zhongyie537a002017-06-27 16:48:216991 SetQuicAlternativeService(origin1_);
6992 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:456993
6994 scoped_refptr<X509Certificate> cert(
6995 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:246996 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
6997 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
6998 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:456999
7000 ProofVerifyDetailsChromium verify_details;
7001 verify_details.cert_verify_result.verified_cert = cert;
7002 verify_details.cert_verify_result.is_issued_by_known_root = true;
7003 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7004
Yixin Wang079ad542018-01-11 04:06:057005 QuicTestPacketMaker client_maker(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527006 version_, 0, &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057007 client_headers_include_h2_stream_dependency_);
7008 QuicTestPacketMaker server_maker(version_, 0, &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527009 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457010
Ryan Hamilton8d9ee76e2018-05-29 23:52:527011 quic::QuicStreamOffset request_header_offset(0);
7012 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457013
7014 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057015 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437016 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057017 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437018 mock_quic_data.AddWrite(SYNCHRONOUS,
7019 ConstructClientRequestHeadersPacket(
7020 2, GetNthClientInitiatedStreamId(0), true,
7021 &request_header_offset, &client_maker));
7022 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7023 1, GetNthClientInitiatedStreamId(0),
7024 &response_header_offset, &server_maker));
7025 mock_quic_data.AddRead(
7026 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
7027 &server_maker));
7028 mock_quic_data.AddWrite(SYNCHRONOUS,
7029 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457030
Yixin Wang079ad542018-01-11 04:06:057031 client_maker.set_hostname(origin2_);
7032 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457033
Zhongyi Shi32f2fd02018-04-16 18:23:437034 mock_quic_data.AddWrite(
7035 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7036 4, GetNthClientInitiatedStreamId(1), false,
7037 GetNthClientInitiatedStreamId(0), &request_header_offset,
7038 &client_maker));
7039 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7040 3, GetNthClientInitiatedStreamId(1),
7041 &response_header_offset, &server_maker));
7042 mock_quic_data.AddRead(
7043 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(1),
7044 &server_maker));
7045 mock_quic_data.AddWrite(SYNCHRONOUS,
7046 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457047 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7048 mock_quic_data.AddRead(ASYNC, 0); // EOF
7049
7050 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7051
7052 AddHangingSocketData();
7053 AddHangingSocketData();
7054
Fan Yangc9e00dc2018-10-09 14:17:567055 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7056 QuicStreamFactoryPeer::SetAlarmFactory(
7057 session_->quic_stream_factory(),
7058 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7059 &clock_));
7060
bnc359ed2a2016-04-29 20:43:457061 SendRequestAndExpectQuicResponse(origin1_);
7062 SendRequestAndExpectQuicResponse(origin2_);
7063
7064 EXPECT_TRUE(AllDataConsumed());
7065}
7066
7067// First request opens QUIC session to alternative service. Second request does
7068// not pool to it, even though destination matches, because certificate is not
7069// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527070// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457071TEST_P(QuicNetworkTransactionWithDestinationTest,
7072 DoNotPoolIfCertificateInvalid) {
7073 origin1_ = "news.example.org";
7074 origin2_ = "mail.example.com";
7075
zhongyie537a002017-06-27 16:48:217076 SetQuicAlternativeService(origin1_);
7077 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457078
7079 scoped_refptr<X509Certificate> cert1(
7080 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247081 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7082 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7083 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457084
7085 scoped_refptr<X509Certificate> cert2(
7086 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247087 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7088 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457089
7090 ProofVerifyDetailsChromium verify_details1;
7091 verify_details1.cert_verify_result.verified_cert = cert1;
7092 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7093 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7094
7095 ProofVerifyDetailsChromium verify_details2;
7096 verify_details2.cert_verify_result.verified_cert = cert2;
7097 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7098 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7099
Yixin Wang079ad542018-01-11 04:06:057100 QuicTestPacketMaker client_maker1(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527101 version_, 0, &clock_, origin1_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057102 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:557103 QuicTestPacketMaker server_maker1(version_, 0, &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527104 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457105
7106 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527107 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457108 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437109 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7110 &client_maker1));
7111 mock_quic_data1.AddWrite(SYNCHRONOUS,
7112 ConstructClientRequestHeadersPacket(
7113 2, GetNthClientInitiatedStreamId(0), true,
7114 &header_stream_offset1, &client_maker1));
7115 mock_quic_data1.AddRead(
7116 ASYNC, ConstructServerResponseHeadersPacket(
7117 1, GetNthClientInitiatedStreamId(0), &server_maker1));
7118 mock_quic_data1.AddRead(
7119 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
7120 &server_maker1));
7121 mock_quic_data1.AddWrite(
7122 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457123 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7124 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7125
7126 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7127
Yixin Wang079ad542018-01-11 04:06:057128 QuicTestPacketMaker client_maker2(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527129 version_, 0, &clock_, origin2_, quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057130 client_headers_include_h2_stream_dependency_);
rchbf4c26d2017-04-16 23:17:557131 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527132 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457133
7134 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527135 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457136 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437137 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7138 &client_maker2));
7139 mock_quic_data2.AddWrite(SYNCHRONOUS,
7140 ConstructClientRequestHeadersPacket(
7141 2, GetNthClientInitiatedStreamId(0), true,
7142 &header_stream_offset2, &client_maker2));
7143 mock_quic_data2.AddRead(
7144 ASYNC, ConstructServerResponseHeadersPacket(
7145 1, GetNthClientInitiatedStreamId(0), &server_maker2));
7146 mock_quic_data2.AddRead(
7147 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
7148 &server_maker2));
7149 mock_quic_data2.AddWrite(
7150 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457151 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7152 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7153
7154 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7155
bnc359ed2a2016-04-29 20:43:457156 SendRequestAndExpectQuicResponse(origin1_);
7157 SendRequestAndExpectQuicResponse(origin2_);
7158
7159 EXPECT_TRUE(AllDataConsumed());
7160}
7161
ckrasicdee37572017-04-06 22:42:277162// crbug.com/705109 - this confirms that matching request with a body
7163// triggers a crash (pre-fix).
7164TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417165 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277166 HostPortPair::FromString("mail.example.org:443"));
7167
7168 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527169 quic::QuicStreamOffset header_stream_offset = 0;
7170 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437171 mock_quic_data.AddWrite(
7172 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7173 &header_stream_offset));
7174 mock_quic_data.AddWrite(
7175 SYNCHRONOUS,
7176 ConstructClientRequestHeadersPacket(
7177 client_packet_number++, GetNthClientInitiatedStreamId(0), true, true,
7178 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527179 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437180 mock_quic_data.AddRead(
7181 ASYNC,
7182 ConstructServerPushPromisePacket(
7183 1, GetNthClientInitiatedStreamId(0), GetNthServerInitiatedStreamId(0),
7184 false, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7185 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577186 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267187 version_ >= quic::QUIC_VERSION_43) {
Zhongyi Shi32f2fd02018-04-16 18:23:437188 mock_quic_data.AddWrite(
7189 SYNCHRONOUS,
7190 ConstructClientPriorityPacket(client_packet_number++, false,
7191 GetNthServerInitiatedStreamId(0),
7192 GetNthClientInitiatedStreamId(0),
7193 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577194 }
Zhongyi Shi32f2fd02018-04-16 18:23:437195 mock_quic_data.AddRead(
7196 ASYNC, ConstructServerResponseHeadersPacket(
7197 2, GetNthClientInitiatedStreamId(0), false, false,
7198 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577199 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437200 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7201 mock_quic_data.AddRead(
7202 ASYNC, ConstructServerResponseHeadersPacket(
7203 3, GetNthServerInitiatedStreamId(0), false, false,
7204 GetResponseHeaders("200 OK"), &server_header_offset));
7205 mock_quic_data.AddRead(
7206 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
7207 false, true, 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577208 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437209 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
7210 mock_quic_data.AddRead(
7211 ASYNC, ConstructServerDataPacket(5, GetNthServerInitiatedStreamId(0),
7212 false, true, 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:277213
7214 // Because the matching request has a body, we will see the push
7215 // stream get cancelled, and the matching request go out on the
7216 // wire.
Zhongyi Shi32f2fd02018-04-16 18:23:437217 mock_quic_data.AddWrite(
7218 SYNCHRONOUS, ConstructClientAckAndRstPacket(
7219 client_packet_number++, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527220 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277221 const char kBody[] = "1";
Zhongyi Shi32f2fd02018-04-16 18:23:437222 mock_quic_data.AddWrite(
7223 SYNCHRONOUS,
7224 ConstructClientRequestHeadersAndDataFramesPacket(
7225 client_packet_number++, GetNthClientInitiatedStreamId(1), false, true,
7226 DEFAULT_PRIORITY, GetRequestHeaders("GET", "https", "/pushed.jpg"),
7227 GetNthServerInitiatedStreamId(0), &header_stream_offset, nullptr,
7228 {kBody}));
ckrasicdee37572017-04-06 22:42:277229
7230 // We see the same response as for the earlier pushed and cancelled
7231 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437232 mock_quic_data.AddRead(
7233 ASYNC, ConstructServerResponseHeadersPacket(
7234 6, GetNthClientInitiatedStreamId(1), false, false,
7235 GetResponseHeaders("200 OK"), &server_header_offset));
7236 mock_quic_data.AddRead(
7237 ASYNC, ConstructServerDataPacket(7, GetNthClientInitiatedStreamId(1),
7238 false, true, 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:277239
Yixin Wangb470bc882018-02-15 18:43:577240 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437241 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277242 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7243 mock_quic_data.AddRead(ASYNC, 0); // EOF
7244 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7245
7246 // The non-alternate protocol job needs to hang in order to guarantee that
7247 // the alternate-protocol job will "win".
7248 AddHangingNonAlternateProtocolSocketData();
7249
7250 CreateSession();
7251
7252 // PUSH_PROMISE handling in the http layer gets exercised here.
7253 SendRequestAndExpectQuicResponse("hello!");
7254
7255 request_.url = GURL("https://mail.example.org/pushed.jpg");
7256 ChunkedUploadDataStream upload_data(0);
7257 upload_data.AppendData("1", 1, true);
7258 request_.upload_data_stream = &upload_data;
7259 SendRequestAndExpectQuicResponse("and hello!");
7260}
7261
Bence Béky7538a952018-02-01 16:59:527262// Regression test for https://crbug.com/797825: If pushed headers describe a
7263// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7264// not be called (otherwise a DCHECK fails).
7265TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137266 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527267 pushed_request_headers[":authority"] = "";
7268 pushed_request_headers[":method"] = "GET";
7269 pushed_request_headers[":path"] = "/";
7270 pushed_request_headers[":scheme"] = "nosuchscheme";
7271
7272 session_params_.origins_to_force_quic_on.insert(
7273 HostPortPair::FromString("mail.example.org:443"));
7274
7275 MockQuicData mock_quic_data;
7276
Ryan Hamilton8d9ee76e2018-05-29 23:52:527277 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527278 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437279 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7280 mock_quic_data.AddWrite(
7281 SYNCHRONOUS,
7282 ConstructClientRequestHeadersPacket(
7283 2, GetNthClientInitiatedStreamId(0), true, true,
7284 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527285
Ryan Hamilton8d9ee76e2018-05-29 23:52:527286 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437287 mock_quic_data.AddRead(ASYNC, ConstructServerPushPromisePacket(
7288 1, GetNthClientInitiatedStreamId(0),
7289 GetNthServerInitiatedStreamId(0), false,
7290 std::move(pushed_request_headers),
7291 &server_header_offset, &server_maker_));
7292 mock_quic_data.AddWrite(
7293 SYNCHRONOUS, ConstructClientRstPacket(3, GetNthServerInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527294 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527295
Zhongyi Shi32f2fd02018-04-16 18:23:437296 mock_quic_data.AddRead(
7297 ASYNC, ConstructServerResponseHeadersPacket(
7298 2, GetNthClientInitiatedStreamId(0), false, false,
7299 GetResponseHeaders("200 OK"), &server_header_offset));
7300 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527301
Zhongyi Shi32f2fd02018-04-16 18:23:437302 mock_quic_data.AddRead(
7303 ASYNC, ConstructServerResponseHeadersPacket(
7304 3, GetNthServerInitiatedStreamId(0), false, false,
7305 GetResponseHeaders("200 OK"), &server_header_offset));
7306 mock_quic_data.AddRead(
7307 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
7308 false, true, 0, "hello!"));
7309 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527310
7311 mock_quic_data.AddRead(ASYNC, 0);
7312 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7313
7314 // The non-alternate protocol job needs to hang in order to guarantee that
7315 // the alternate-protocol job will "win".
7316 AddHangingNonAlternateProtocolSocketData();
7317
7318 CreateSession();
7319
7320 // PUSH_PROMISE handling in the http layer gets exercised here.
7321 SendRequestAndExpectQuicResponse("hello!");
7322
7323 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7324 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7325}
7326
Yixin Wang46a273ec302018-01-23 17:59:567327// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
7328TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
7329 session_params_.enable_quic = true;
7330 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497331 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567332
7333 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527334 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567335 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437336 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7337 mock_quic_data.AddWrite(SYNCHRONOUS,
7338 ConstructClientRequestHeadersPacket(
7339 2, GetNthClientInitiatedStreamId(0), true, false,
7340 ConnectRequestHeaders("mail.example.org:443"),
7341 &header_stream_offset));
7342 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7343 1, GetNthClientInitiatedStreamId(0), false,
7344 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567345
7346 const char get_request[] =
7347 "GET / HTTP/1.1\r\n"
7348 "Host: mail.example.org\r\n"
7349 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437350 mock_quic_data.AddWrite(
7351 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7352 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527353 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567354 const char get_response[] =
7355 "HTTP/1.1 200 OK\r\n"
7356 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437357 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527358 ASYNC,
7359 ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0), false,
7360 false, 0, quic::QuicStringPiece(get_response)));
7361
7362 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7363 3, GetNthClientInitiatedStreamId(0),
7364 false, false, strlen(get_response),
7365 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437366 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567367 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7368
7369 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527370 SYNCHRONOUS, ConstructClientRstPacket(5, GetNthClientInitiatedStreamId(0),
7371 quic::QUIC_STREAM_CANCELLED,
7372 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567373
7374 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7375
7376 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7377
7378 CreateSession();
7379
7380 request_.url = GURL("https://mail.example.org/");
7381 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7382 HeadersHandler headers_handler;
7383 trans.SetBeforeHeadersSentCallback(
7384 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7385 base::Unretained(&headers_handler)));
7386 RunTransaction(&trans);
7387 CheckWasHttpResponse(&trans);
7388 CheckResponsePort(&trans, 70);
7389 CheckResponseData(&trans, "0123456789");
7390 EXPECT_TRUE(headers_handler.was_proxied());
7391 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7392
7393 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7394 // proxy socket to disconnect.
7395 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7396
7397 base::RunLoop().RunUntilIdle();
7398 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7399 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7400}
7401
7402// Performs an HTTP/2 request over QUIC proxy tunnel.
7403TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
7404 session_params_.enable_quic = true;
7405 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497406 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567407
7408 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527409 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567410 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437411 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7412 mock_quic_data.AddWrite(SYNCHRONOUS,
7413 ConstructClientRequestHeadersPacket(
7414 2, GetNthClientInitiatedStreamId(0), true, false,
7415 ConnectRequestHeaders("mail.example.org:443"),
7416 &header_stream_offset));
7417 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7418 1, GetNthClientInitiatedStreamId(0), false,
7419 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567420
7421 SpdyTestUtil spdy_util;
7422
Ryan Hamilton0239aac2018-05-19 00:03:137423 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567424 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:437425 mock_quic_data.AddWrite(
7426 SYNCHRONOUS,
7427 ConstructClientAckAndDataPacket(
7428 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527429 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Ryan Hamilton0239aac2018-05-19 00:03:137430 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567431 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437432 mock_quic_data.AddRead(
7433 ASYNC, ConstructServerDataPacket(
7434 2, GetNthClientInitiatedStreamId(0), false, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527435 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567436
Ryan Hamilton0239aac2018-05-19 00:03:137437 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197438 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437439 mock_quic_data.AddRead(
7440 SYNCHRONOUS,
7441 ConstructServerDataPacket(
7442 3, GetNthClientInitiatedStreamId(0), false, false, resp_frame.size(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527443 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Zhongyi Shi32f2fd02018-04-16 18:23:437444 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567445 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7446
7447 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437448 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567449 ConstructClientRstPacket(5, GetNthClientInitiatedStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527450 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:567451
7452 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7453
7454 SSLSocketDataProvider ssl_data(ASYNC, OK);
7455 ssl_data.next_proto = kProtoHTTP2;
7456 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7457
7458 CreateSession();
7459
7460 request_.url = GURL("https://mail.example.org/");
7461 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7462 HeadersHandler headers_handler;
7463 trans.SetBeforeHeadersSentCallback(
7464 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7465 base::Unretained(&headers_handler)));
7466 RunTransaction(&trans);
7467 CheckWasSpdyResponse(&trans);
7468 CheckResponsePort(&trans, 70);
7469 CheckResponseData(&trans, "0123456789");
7470 EXPECT_TRUE(headers_handler.was_proxied());
7471 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7472
Wez0e717112018-06-18 23:09:227473 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7474 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567475 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7476
7477 base::RunLoop().RunUntilIdle();
7478 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7479 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7480}
7481
7482// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7483// check that the proxy socket is reused for the second request.
7484TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
7485 session_params_.enable_quic = true;
7486 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497487 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567488
7489 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527490 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567491 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437492 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7493 mock_quic_data.AddWrite(SYNCHRONOUS,
7494 ConstructClientRequestHeadersPacket(
7495 2, GetNthClientInitiatedStreamId(0), true, false,
7496 ConnectRequestHeaders("mail.example.org:443"),
7497 &header_stream_offset));
7498 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7499 1, GetNthClientInitiatedStreamId(0), false,
7500 false, GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567501
Ryan Hamilton8d9ee76e2018-05-29 23:52:527502 quic::QuicStreamOffset client_data_offset = 0;
7503 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567504 const char get_request_1[] =
7505 "GET / HTTP/1.1\r\n"
7506 "Host: mail.example.org\r\n"
7507 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437508 mock_quic_data.AddWrite(
7509 SYNCHRONOUS,
7510 ConstructClientAckAndDataPacket(
7511 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527512 client_data_offset, quic::QuicStringPiece(get_request_1)));
Yixin Wang46a273ec302018-01-23 17:59:567513 client_data_offset += strlen(get_request_1);
7514
7515 const char get_response_1[] =
7516 "HTTP/1.1 200 OK\r\n"
7517 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437518 mock_quic_data.AddRead(
7519 ASYNC, ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0),
7520 false, false, server_data_offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527521 quic::QuicStringPiece(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:567522 server_data_offset += strlen(get_response_1);
7523
Ryan Hamilton8d9ee76e2018-05-29 23:52:527524 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7525 3, GetNthClientInitiatedStreamId(0),
7526 false, false, server_data_offset,
7527 quic::QuicStringPiece("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:567528 server_data_offset += 10;
7529
Zhongyi Shi32f2fd02018-04-16 18:23:437530 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567531
7532 const char get_request_2[] =
7533 "GET /2 HTTP/1.1\r\n"
7534 "Host: mail.example.org\r\n"
7535 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437536 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527537 SYNCHRONOUS,
7538 ConstructClientDataPacket(5, GetNthClientInitiatedStreamId(0), false,
7539 false, client_data_offset,
7540 quic::QuicStringPiece(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567541 client_data_offset += strlen(get_request_2);
7542
7543 const char get_response_2[] =
7544 "HTTP/1.1 200 OK\r\n"
7545 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437546 mock_quic_data.AddRead(
7547 ASYNC, ConstructServerDataPacket(4, GetNthClientInitiatedStreamId(0),
7548 false, false, server_data_offset,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527549 quic::QuicStringPiece(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:567550 server_data_offset += strlen(get_response_2);
7551
Ryan Hamilton8d9ee76e2018-05-29 23:52:527552 mock_quic_data.AddRead(
7553 SYNCHRONOUS, ConstructServerDataPacket(
7554 5, GetNthClientInitiatedStreamId(0), false, false,
7555 server_data_offset, quic::QuicStringPiece("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:567556 server_data_offset += 7;
7557
Zhongyi Shi32f2fd02018-04-16 18:23:437558 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567559 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7560
7561 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527562 SYNCHRONOUS, ConstructClientRstPacket(7, GetNthClientInitiatedStreamId(0),
7563 quic::QUIC_STREAM_CANCELLED,
7564 client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567565
7566 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7567
7568 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7569
7570 CreateSession();
7571
7572 request_.url = GURL("https://mail.example.org/");
7573 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7574 HeadersHandler headers_handler_1;
7575 trans_1.SetBeforeHeadersSentCallback(
7576 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7577 base::Unretained(&headers_handler_1)));
7578 RunTransaction(&trans_1);
7579 CheckWasHttpResponse(&trans_1);
7580 CheckResponsePort(&trans_1, 70);
7581 CheckResponseData(&trans_1, "0123456789");
7582 EXPECT_TRUE(headers_handler_1.was_proxied());
7583 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7584
7585 request_.url = GURL("https://mail.example.org/2");
7586 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7587 HeadersHandler headers_handler_2;
7588 trans_2.SetBeforeHeadersSentCallback(
7589 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7590 base::Unretained(&headers_handler_2)));
7591 RunTransaction(&trans_2);
7592 CheckWasHttpResponse(&trans_2);
7593 CheckResponsePort(&trans_2, 70);
7594 CheckResponseData(&trans_2, "0123456");
7595 EXPECT_TRUE(headers_handler_2.was_proxied());
7596 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7597
7598 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7599 // proxy socket to disconnect.
7600 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7601
7602 base::RunLoop().RunUntilIdle();
7603 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7604 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7605}
7606
7607// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7608// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7609// server is reused for the second request.
7610TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
7611 session_params_.enable_quic = true;
7612 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497613 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567614
7615 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527616 quic::QuicStreamOffset client_header_stream_offset = 0;
7617 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437618 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7619 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567620
7621 // CONNECT request and response for first request
Zhongyi Shi32f2fd02018-04-16 18:23:437622 mock_quic_data.AddWrite(SYNCHRONOUS,
7623 ConstructClientRequestHeadersPacket(
7624 2, GetNthClientInitiatedStreamId(0), true, false,
7625 ConnectRequestHeaders("mail.example.org:443"),
7626 &client_header_stream_offset));
7627 mock_quic_data.AddRead(
7628 ASYNC, ConstructServerResponseHeadersPacket(
7629 1, GetNthClientInitiatedStreamId(0), false, false,
7630 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567631
7632 // GET request, response, and data over QUIC tunnel for first request
7633 const char get_request[] =
7634 "GET / HTTP/1.1\r\n"
7635 "Host: mail.example.org\r\n"
7636 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437637 mock_quic_data.AddWrite(
7638 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7639 3, false, GetNthClientInitiatedStreamId(0), 1, 1, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527640 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567641 const char get_response[] =
7642 "HTTP/1.1 200 OK\r\n"
7643 "Content-Length: 10\r\n\r\n";
7644 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527645 ASYNC,
7646 ConstructServerDataPacket(2, GetNthClientInitiatedStreamId(0), false,
7647 false, 0, quic::QuicStringPiece(get_response)));
7648 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7649 3, GetNthClientInitiatedStreamId(0),
7650 false, false, strlen(get_response),
7651 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437652 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567653
7654 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437655 mock_quic_data.AddWrite(
7656 SYNCHRONOUS,
7657 ConstructClientRequestHeadersPacket(
7658 5, GetNthClientInitiatedStreamId(1), false, false,
7659 ConnectRequestHeaders("different.example.org:443"),
7660 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
7661 mock_quic_data.AddRead(
7662 ASYNC, ConstructServerResponseHeadersPacket(
7663 4, GetNthClientInitiatedStreamId(1), false, false,
7664 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567665
7666 // GET request, response, and data over QUIC tunnel for second request
7667 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137668 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567669 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:437670 mock_quic_data.AddWrite(
7671 SYNCHRONOUS,
7672 ConstructClientAckAndDataPacket(
7673 6, false, GetNthClientInitiatedStreamId(1), 4, 4, 1, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527674 quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567675
Ryan Hamilton0239aac2018-05-19 00:03:137676 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567677 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437678 mock_quic_data.AddRead(
7679 ASYNC, ConstructServerDataPacket(
7680 5, GetNthClientInitiatedStreamId(1), false, false, 0,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527681 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567682
Ryan Hamilton0239aac2018-05-19 00:03:137683 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197684 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437685 mock_quic_data.AddRead(
7686 ASYNC,
7687 ConstructServerDataPacket(
7688 6, GetNthClientInitiatedStreamId(1), false, false, resp_frame.size(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527689 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567690
Zhongyi Shi32f2fd02018-04-16 18:23:437691 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567692 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7693
7694 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527695 SYNCHRONOUS, ConstructClientRstPacket(8, GetNthClientInitiatedStreamId(0),
7696 quic::QUIC_STREAM_CANCELLED,
7697 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567698 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437699 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:567700 ConstructClientRstPacket(9, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527701 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:567702
7703 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7704
7705 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7706
7707 SSLSocketDataProvider ssl_data(ASYNC, OK);
7708 ssl_data.next_proto = kProtoHTTP2;
7709 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7710
7711 CreateSession();
7712
7713 request_.url = GURL("https://mail.example.org/");
7714 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7715 HeadersHandler headers_handler_1;
7716 trans_1.SetBeforeHeadersSentCallback(
7717 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7718 base::Unretained(&headers_handler_1)));
7719 RunTransaction(&trans_1);
7720 CheckWasHttpResponse(&trans_1);
7721 CheckResponsePort(&trans_1, 70);
7722 CheckResponseData(&trans_1, "0123456789");
7723 EXPECT_TRUE(headers_handler_1.was_proxied());
7724 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7725
7726 request_.url = GURL("https://different.example.org/");
7727 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7728 HeadersHandler headers_handler_2;
7729 trans_2.SetBeforeHeadersSentCallback(
7730 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7731 base::Unretained(&headers_handler_2)));
7732 RunTransaction(&trans_2);
7733 CheckWasSpdyResponse(&trans_2);
7734 CheckResponsePort(&trans_2, 70);
7735 CheckResponseData(&trans_2, "0123456");
7736 EXPECT_TRUE(headers_handler_2.was_proxied());
7737 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7738
7739 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7740 // proxy socket to disconnect.
7741 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7742
7743 base::RunLoop().RunUntilIdle();
7744 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7745 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7746}
7747
7748// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
7749TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
7750 session_params_.enable_quic = true;
7751 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497752 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567753
7754 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527755 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567756 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437757 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7758 mock_quic_data.AddWrite(SYNCHRONOUS,
7759 ConstructClientRequestHeadersPacket(
7760 2, GetNthClientInitiatedStreamId(0), true, false,
7761 ConnectRequestHeaders("mail.example.org:443"),
7762 &header_stream_offset));
7763 mock_quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
7764 1, GetNthClientInitiatedStreamId(0), false,
7765 true, GetResponseHeaders("500")));
Yixin Wang46a273ec302018-01-23 17:59:567766 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Ryan Hamilton8d9ee76e2018-05-29 23:52:527767 mock_quic_data.AddWrite(
7768 SYNCHRONOUS,
7769 ConstructClientAckAndRstPacket(3, GetNthClientInitiatedStreamId(0),
7770 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567771
7772 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7773
7774 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7775
7776 CreateSession();
7777
7778 request_.url = GURL("https://mail.example.org/");
7779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7780 HeadersHandler headers_handler;
7781 trans.SetBeforeHeadersSentCallback(
7782 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7783 base::Unretained(&headers_handler)));
7784 TestCompletionCallback callback;
7785 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7786 EXPECT_EQ(ERR_IO_PENDING, rv);
7787 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7788 EXPECT_EQ(false, headers_handler.was_proxied());
7789
7790 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7791 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7792}
7793
7794// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
7795TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
7796 session_params_.enable_quic = true;
7797 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497798 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567799
7800 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527801 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567802 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437803 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7804 mock_quic_data.AddWrite(SYNCHRONOUS,
7805 ConstructClientRequestHeadersPacket(
7806 2, GetNthClientInitiatedStreamId(0), true, false,
7807 ConnectRequestHeaders("mail.example.org:443"),
7808 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567809 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7810
7811 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7812
7813 CreateSession();
7814
7815 request_.url = GURL("https://mail.example.org/");
7816 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7817 HeadersHandler headers_handler;
7818 trans.SetBeforeHeadersSentCallback(
7819 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7820 base::Unretained(&headers_handler)));
7821 TestCompletionCallback callback;
7822 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7823 EXPECT_EQ(ERR_IO_PENDING, rv);
7824 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7825
7826 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7827 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7828}
7829
7830// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
7831// host. Retries request and succeeds.
7832TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
7833 session_params_.enable_quic = true;
7834 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497835 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567836
7837 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527838 quic::QuicStreamOffset client_header_stream_offset = 0;
7839 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437840 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7841 1, &client_header_stream_offset));
7842 mock_quic_data.AddWrite(SYNCHRONOUS,
7843 ConstructClientRequestHeadersPacket(
7844 2, GetNthClientInitiatedStreamId(0), true, false,
7845 ConnectRequestHeaders("mail.example.org:443"),
7846 &client_header_stream_offset));
7847 mock_quic_data.AddRead(
7848 ASYNC, ConstructServerResponseHeadersPacket(
7849 1, GetNthClientInitiatedStreamId(0), false, false,
7850 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527851 mock_quic_data.AddWrite(
7852 SYNCHRONOUS,
7853 ConstructClientAckAndRstPacket(3, GetNthClientInitiatedStreamId(0),
7854 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567855
Zhongyi Shi32f2fd02018-04-16 18:23:437856 mock_quic_data.AddWrite(
7857 SYNCHRONOUS,
7858 ConstructClientRequestHeadersPacket(
7859 4, GetNthClientInitiatedStreamId(1), false, false,
7860 ConnectRequestHeaders("mail.example.org:443"),
7861 GetNthClientInitiatedStreamId(0), &client_header_stream_offset));
7862 mock_quic_data.AddRead(
7863 ASYNC, ConstructServerResponseHeadersPacket(
7864 2, GetNthClientInitiatedStreamId(1), false, false,
7865 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567866
7867 const char get_request[] =
7868 "GET / HTTP/1.1\r\n"
7869 "Host: mail.example.org\r\n"
7870 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437871 mock_quic_data.AddWrite(
7872 SYNCHRONOUS, ConstructClientAckAndDataPacket(
7873 5, false, GetNthClientInitiatedStreamId(1), 2, 2, 1,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527874 false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567875 const char get_response[] =
7876 "HTTP/1.1 200 OK\r\n"
7877 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437878 mock_quic_data.AddRead(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527879 ASYNC,
7880 ConstructServerDataPacket(3, GetNthClientInitiatedStreamId(1), false,
7881 false, 0, quic::QuicStringPiece(get_response)));
7882
7883 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerDataPacket(
7884 4, GetNthClientInitiatedStreamId(1),
7885 false, false, strlen(get_response),
7886 quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437887 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:567888 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7889
7890 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527891 SYNCHRONOUS, ConstructClientRstPacket(7, GetNthClientInitiatedStreamId(1),
7892 quic::QUIC_STREAM_CANCELLED,
7893 strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567894
7895 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7896
7897 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7898 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
7899
7900 SSLSocketDataProvider ssl_data(ASYNC, OK);
7901 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7902
7903 CreateSession();
7904
7905 request_.url = GURL("https://mail.example.org/");
7906 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7907 HeadersHandler headers_handler;
7908 trans.SetBeforeHeadersSentCallback(
7909 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7910 base::Unretained(&headers_handler)));
7911 TestCompletionCallback callback;
7912 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7913 EXPECT_EQ(ERR_IO_PENDING, rv);
7914 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
7915
7916 rv = trans.RestartIgnoringLastError(callback.callback());
7917 EXPECT_EQ(ERR_IO_PENDING, rv);
7918 EXPECT_EQ(OK, callback.WaitForResult());
7919
7920 CheckWasHttpResponse(&trans);
7921 CheckResponsePort(&trans, 70);
7922 CheckResponseData(&trans, "0123456789");
7923 EXPECT_EQ(true, headers_handler.was_proxied());
7924 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7925
7926 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7927 // proxy socket to disconnect.
7928 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7929
7930 base::RunLoop().RunUntilIdle();
7931 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7932 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7933}
7934
7935// Checks if a request's specified "user-agent" header shows up correctly in the
7936// CONNECT request to a QUIC proxy.
7937TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
7938 session_params_.enable_quic = true;
7939 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497940 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567941
7942 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527943 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567944 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437945 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567946
Ryan Hamilton0239aac2018-05-19 00:03:137947 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:567948 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Zhongyi Shi32f2fd02018-04-16 18:23:437949 mock_quic_data.AddWrite(SYNCHRONOUS,
7950 ConstructClientRequestHeadersPacket(
7951 2, GetNthClientInitiatedStreamId(0), true, false,
7952 std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567953 // Return an error, so the transaction stops here (this test isn't interested
7954 // in the rest).
7955 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7956
7957 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7958
7959 CreateSession();
7960
7961 request_.url = GURL("https://mail.example.org/");
7962 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7963 "Chromium Ultra Awesome X Edition");
7964 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7965 HeadersHandler headers_handler;
7966 trans.SetBeforeHeadersSentCallback(
7967 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7968 base::Unretained(&headers_handler)));
7969 TestCompletionCallback callback;
7970 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7971 EXPECT_EQ(ERR_IO_PENDING, rv);
7972 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7973
7974 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7975 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7976}
7977
Yixin Wang00fc44c2018-01-23 21:12:207978// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
7979// HTTP/2 stream dependency and weights given the request priority.
7980TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
7981 session_params_.enable_quic = true;
7982 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497983 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:207984
7985 const RequestPriority request_priority = MEDIUM;
7986
7987 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527988 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:207989 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437990 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7991 mock_quic_data.AddWrite(
7992 SYNCHRONOUS,
7993 ConstructClientRequestHeadersPacket(
7994 2, GetNthClientInitiatedStreamId(0), true, false, request_priority,
7995 ConnectRequestHeaders("mail.example.org:443"), 0,
7996 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:207997 // Return an error, so the transaction stops here (this test isn't interested
7998 // in the rest).
7999 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8000
8001 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8002
8003 CreateSession();
8004
8005 request_.url = GURL("https://mail.example.org/");
8006 HttpNetworkTransaction trans(request_priority, session_.get());
8007 TestCompletionCallback callback;
8008 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8009 EXPECT_EQ(ERR_IO_PENDING, rv);
8010 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8011
8012 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8013 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8014}
8015
Yixin Wang46a273ec302018-01-23 17:59:568016// Test the request-challenge-retry sequence for basic auth, over a QUIC
8017// connection when setting up a QUIC proxy tunnel.
8018TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
8019 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8020 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138021 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568022 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8023
8024 std::unique_ptr<QuicTestPacketMaker> client_maker;
8025 std::unique_ptr<QuicTestPacketMaker> server_maker;
8026
8027 // On the second pass, the body read of the auth challenge is synchronous, so
8028 // IsConnectedAndIdle returns false. The socket should still be drained and
8029 // reused. See http://crbug.com/544255.
8030 for (int i = 0; i < 2; ++i) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:528031 client_maker.reset(
8032 new QuicTestPacketMaker(version_, 0, &clock_, kDefaultServerHostName,
8033 quic::Perspective::IS_CLIENT,
8034 client_headers_include_h2_stream_dependency_));
8035 server_maker.reset(
8036 new QuicTestPacketMaker(version_, 0, &clock_, kDefaultServerHostName,
8037 quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568038
8039 session_params_.enable_quic = true;
8040 proxy_resolution_service_ =
8041 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498042 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568043
8044 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528045 quic::QuicStreamOffset client_header_stream_offset = 0;
8046 quic::QuicStreamOffset server_header_stream_offset = 0;
8047 quic::QuicStreamOffset client_data_offset = 0;
8048 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568049
Zhongyi Shi32f2fd02018-04-16 18:23:438050 mock_quic_data.AddWrite(SYNCHRONOUS,
8051 client_maker->MakeInitialSettingsPacket(
8052 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568053
8054 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438055 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568056 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8057 2, GetNthClientInitiatedStreamId(0), true, false, default_priority,
8058 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8059 &client_header_stream_offset));
8060
Ryan Hamilton0239aac2018-05-19 00:03:138061 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568062 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8063 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8064 headers["content-length"] = "10";
8065 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438066 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
8067 1, GetNthClientInitiatedStreamId(0), false, false,
8068 std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568069
8070 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438071 mock_quic_data.AddRead(
8072 ASYNC, server_maker->MakeDataPacket(
8073 2, GetNthClientInitiatedStreamId(0), false, false,
8074 server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568075 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438076 mock_quic_data.AddRead(
8077 SYNCHRONOUS, server_maker->MakeDataPacket(
8078 2, GetNthClientInitiatedStreamId(0), false, false,
8079 server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568080 }
8081 server_data_offset += 10;
8082
Zhongyi Shi32f2fd02018-04-16 18:23:438083 mock_quic_data.AddWrite(SYNCHRONOUS,
8084 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568085
8086 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:528087 SYNCHRONOUS, client_maker->MakeRstPacket(
8088 4, false, GetNthClientInitiatedStreamId(0),
8089 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:568090
8091 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8092 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8093 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438094 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568095 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8096 5, GetNthClientInitiatedStreamId(1), false, false, default_priority,
8097 std::move(headers), GetNthClientInitiatedStreamId(0),
8098 &client_header_stream_offset));
8099
8100 // Response to wrong password
8101 headers =
8102 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8103 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8104 headers["content-length"] = "10";
8105 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438106 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
8107 3, GetNthClientInitiatedStreamId(1), false, false,
8108 std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568109 mock_quic_data.AddRead(SYNCHRONOUS,
8110 ERR_IO_PENDING); // No more data to read
8111
Zhongyi Shi32f2fd02018-04-16 18:23:438112 mock_quic_data.AddWrite(SYNCHRONOUS,
8113 client_maker->MakeAckAndRstPacket(
8114 6, false, GetNthClientInitiatedStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:528115 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568116
8117 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8118 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8119
8120 CreateSession();
8121
8122 request_.url = GURL("https://mail.example.org/");
8123 // Ensure that proxy authentication is attempted even
8124 // when the no authentication data flag is set.
8125 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8126 {
8127 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8128 HeadersHandler headers_handler;
8129 trans.SetBeforeHeadersSentCallback(
8130 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8131 base::Unretained(&headers_handler)));
8132 RunTransaction(&trans);
8133
8134 const HttpResponseInfo* response = trans.GetResponseInfo();
8135 ASSERT_TRUE(response != nullptr);
8136 ASSERT_TRUE(response->headers.get() != nullptr);
8137 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8138 response->headers->GetStatusLine());
8139 EXPECT_TRUE(response->headers->IsKeepAlive());
8140 EXPECT_EQ(407, response->headers->response_code());
8141 EXPECT_EQ(10, response->headers->GetContentLength());
8142 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8143 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8144 ASSERT_TRUE(auth_challenge != nullptr);
8145 EXPECT_TRUE(auth_challenge->is_proxy);
8146 EXPECT_EQ("https://proxy.example.org:70",
8147 auth_challenge->challenger.Serialize());
8148 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8149 EXPECT_EQ("basic", auth_challenge->scheme);
8150
8151 TestCompletionCallback callback;
8152 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8153 callback.callback());
8154 EXPECT_EQ(ERR_IO_PENDING, rv);
8155 EXPECT_EQ(OK, callback.WaitForResult());
8156
8157 response = trans.GetResponseInfo();
8158 ASSERT_TRUE(response != nullptr);
8159 ASSERT_TRUE(response->headers.get() != nullptr);
8160 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8161 response->headers->GetStatusLine());
8162 EXPECT_TRUE(response->headers->IsKeepAlive());
8163 EXPECT_EQ(407, response->headers->response_code());
8164 EXPECT_EQ(10, response->headers->GetContentLength());
8165 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8166 auth_challenge = response->auth_challenge.get();
8167 ASSERT_TRUE(auth_challenge != nullptr);
8168 EXPECT_TRUE(auth_challenge->is_proxy);
8169 EXPECT_EQ("https://proxy.example.org:70",
8170 auth_challenge->challenger.Serialize());
8171 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8172 EXPECT_EQ("basic", auth_challenge->scheme);
8173 }
8174 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8175 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8176 // reused because it's not connected).
8177 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8178 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8179 }
8180}
8181
Yixin Wang385652a2018-02-16 02:37:238182TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8183 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8184 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268185 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238186 !client_headers_include_h2_stream_dependency_) {
8187 return;
8188 }
8189
8190 session_params_.origins_to_force_quic_on.insert(
8191 HostPortPair::FromString("mail.example.org:443"));
8192
Ryan Hamilton8d9ee76e2018-05-29 23:52:528193 const quic::QuicStreamId client_stream_0 = GetNthClientInitiatedStreamId(0);
8194 const quic::QuicStreamId client_stream_1 = GetNthClientInitiatedStreamId(1);
8195 const quic::QuicStreamId client_stream_2 = GetNthClientInitiatedStreamId(2);
8196 const quic::QuicStreamId push_stream_0 = GetNthServerInitiatedStreamId(0);
8197 const quic::QuicStreamId push_stream_1 = GetNthServerInitiatedStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238198
8199 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528200 quic::QuicStreamOffset header_stream_offset = 0;
8201 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238202 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438203 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238204
8205 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438206 mock_quic_data.AddWrite(SYNCHRONOUS,
8207 ConstructClientRequestHeadersPacket(
8208 2, client_stream_0, true, true, HIGHEST,
8209 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8210 &header_stream_offset));
8211 mock_quic_data.AddWrite(SYNCHRONOUS,
8212 ConstructClientRequestHeadersPacket(
8213 3, client_stream_1, true, true, MEDIUM,
8214 GetRequestHeaders("GET", "https", "/1.jpg"),
8215 client_stream_0, &header_stream_offset));
8216 mock_quic_data.AddWrite(SYNCHRONOUS,
8217 ConstructClientRequestHeadersPacket(
8218 4, client_stream_2, true, true, MEDIUM,
8219 GetRequestHeaders("GET", "https", "/2.jpg"),
8220 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238221
8222 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438223 mock_quic_data.AddRead(
8224 ASYNC, ConstructServerResponseHeadersPacket(
8225 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8226 &server_header_offset));
8227 mock_quic_data.AddRead(
8228 ASYNC, ConstructServerResponseHeadersPacket(
8229 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8230 &server_header_offset));
8231 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8232 mock_quic_data.AddRead(
8233 ASYNC, ConstructServerResponseHeadersPacket(
8234 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8235 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238236
8237 // Server sends two push promises associated with |client_stream_0|; client
8238 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8239 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438240 mock_quic_data.AddRead(ASYNC,
8241 ConstructServerPushPromisePacket(
8242 4, client_stream_0, push_stream_0, false,
8243 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8244 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238245 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438246 SYNCHRONOUS,
8247 ConstructClientAckAndPriorityFramesPacket(
8248 6, false, 4, 3, 1,
8249 {{push_stream_0, client_stream_2,
8250 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8251 &header_stream_offset));
8252 mock_quic_data.AddRead(ASYNC,
8253 ConstructServerPushPromisePacket(
8254 5, client_stream_0, push_stream_1, false,
8255 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8256 &server_header_offset, &server_maker_));
8257 mock_quic_data.AddWrite(
8258 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238259 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8260 DEFAULT_PRIORITY, &header_stream_offset));
8261
8262 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438263 mock_quic_data.AddRead(
8264 ASYNC, ConstructServerResponseHeadersPacket(
8265 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8266 &server_header_offset));
8267 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8268 mock_quic_data.AddRead(
8269 ASYNC, ConstructServerResponseHeadersPacket(
8270 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8271 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238272
8273 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8274 // priority updates to match the request's priority. Client sends PRIORITY
8275 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438276 mock_quic_data.AddWrite(
8277 SYNCHRONOUS,
8278 ConstructClientAckAndPriorityFramesPacket(
8279 9, false, 7, 7, 1,
8280 {{push_stream_1, client_stream_2,
8281 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8282 {push_stream_0, client_stream_0,
8283 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8284 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238285
8286 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438287 mock_quic_data.AddRead(
8288 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
8289 "hello 0!"));
8290 mock_quic_data.AddRead(
8291 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
8292 "hello 1!"));
8293 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8294 mock_quic_data.AddRead(
8295 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
8296 "hello 2!"));
8297 mock_quic_data.AddRead(
8298 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
8299 "and hello 0!"));
8300 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8301 mock_quic_data.AddRead(
8302 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
8303 "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238304
Yixin Wang385652a2018-02-16 02:37:238305 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8306 mock_quic_data.AddRead(ASYNC, 0); // EOF
8307 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8308
8309 // The non-alternate protocol job needs to hang in order to guarantee that
8310 // the alternate-protocol job will "win".
8311 AddHangingNonAlternateProtocolSocketData();
8312
8313 CreateSession();
8314
8315 request_.url = GURL("https://mail.example.org/0.jpg");
8316 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8317 TestCompletionCallback callback_0;
8318 EXPECT_EQ(ERR_IO_PENDING,
8319 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8320 base::RunLoop().RunUntilIdle();
8321
8322 request_.url = GURL("https://mail.example.org/1.jpg");
8323 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8324 TestCompletionCallback callback_1;
8325 EXPECT_EQ(ERR_IO_PENDING,
8326 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8327 base::RunLoop().RunUntilIdle();
8328
8329 request_.url = GURL("https://mail.example.org/2.jpg");
8330 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8331 TestCompletionCallback callback_2;
8332 EXPECT_EQ(ERR_IO_PENDING,
8333 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8334 base::RunLoop().RunUntilIdle();
8335
8336 // Client makes request that matches resource pushed in |pushed_stream_0|.
8337 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8338 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8339 TestCompletionCallback callback_3;
8340 EXPECT_EQ(ERR_IO_PENDING,
8341 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8342 base::RunLoop().RunUntilIdle();
8343
8344 EXPECT_TRUE(callback_0.have_result());
8345 EXPECT_EQ(OK, callback_0.WaitForResult());
8346 EXPECT_TRUE(callback_1.have_result());
8347 EXPECT_EQ(OK, callback_1.WaitForResult());
8348 EXPECT_TRUE(callback_2.have_result());
8349 EXPECT_EQ(OK, callback_2.WaitForResult());
8350
8351 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8352 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8353 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8354 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8355
8356 mock_quic_data.Resume();
8357 base::RunLoop().RunUntilIdle();
8358 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8359 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8360}
8361
[email protected]61a527782013-02-21 03:58:008362} // namespace test
8363} // namespace net