blob: 4ebfc92d569f73b1c46209a543e26ecdd9a92014 [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_,
Fan Yang32c5a112018-12-10 20:06:33263 quic::EmptyQuicConnectionId(),
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_,
Fan Yang32c5a112018-12-10 20:06:33269 quic::EmptyQuicConnectionId(),
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
Fan Yang32c5a112018-12-10 20:06:33893 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
894 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:36895 }
896
Fan Yang32c5a112018-12-10 20:06:33897 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
898 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(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(
Fan Yang32c5a112018-12-10 20:06:331042 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431043 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431044 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331045 ASYNC, ConstructServerResponseHeadersPacket(
1046 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1047 GetResponseHeaders("200 OK")));
1048 mock_quic_data.AddRead(
1049 ASYNC, ConstructServerDataPacket(
1050 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1051 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431052 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231053 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1054
1055 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1056
1057 CreateSession();
1058 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(true);
1059
1060 EXPECT_FALSE(
1061 test_socket_performance_watcher_factory_.rtt_notification_received());
1062 SendRequestAndExpectQuicResponse("hello!");
1063 EXPECT_TRUE(
1064 test_socket_performance_watcher_factory_.rtt_notification_received());
1065}
1066
1067TEST_P(QuicNetworkTransactionTest, SocketWatcherDisabled) {
mmenke6ddfbea2017-05-31 21:48:411068 session_params_.origins_to_force_quic_on.insert(
tbansal180587c2017-02-16 15:13:231069 HostPortPair::FromString("mail.example.org:443"));
1070
1071 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521072 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361073 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431074 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1075 mock_quic_data.AddWrite(
1076 SYNCHRONOUS,
1077 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331078 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431079 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431080 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331081 ASYNC, ConstructServerResponseHeadersPacket(
1082 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1083 GetResponseHeaders("200 OK")));
1084 mock_quic_data.AddRead(
1085 ASYNC, ConstructServerDataPacket(
1086 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1087 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431088 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal180587c2017-02-16 15:13:231089 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1090
1091 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1092
1093 CreateSession();
1094 test_socket_performance_watcher_factory_.set_should_notify_updated_rtt(false);
1095
1096 EXPECT_FALSE(
1097 test_socket_performance_watcher_factory_.rtt_notification_received());
1098 SendRequestAndExpectQuicResponse("hello!");
1099 EXPECT_FALSE(
1100 test_socket_performance_watcher_factory_.rtt_notification_received());
1101}
1102
[email protected]1e960032013-12-20 19:00:201103TEST_P(QuicNetworkTransactionTest, ForceQuic) {
mmenke6ddfbea2017-05-31 21:48:411104 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571105 HostPortPair::FromString("mail.example.org:443"));
[email protected]4dca587c2013-03-07 16:54:471106
[email protected]1e960032013-12-20 19:00:201107 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521108 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361109 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431110 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1111 mock_quic_data.AddWrite(
1112 SYNCHRONOUS,
1113 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331114 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431115 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431116 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331117 ASYNC, ConstructServerResponseHeadersPacket(
1118 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1119 GetResponseHeaders("200 OK")));
1120 mock_quic_data.AddRead(
1121 ASYNC, ConstructServerDataPacket(
1122 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1123 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431124 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:591125 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
[email protected]4dca587c2013-03-07 16:54:471126
rcha5399e02015-04-21 19:32:041127 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4dca587c2013-03-07 16:54:471128
[email protected]4dca587c2013-03-07 16:54:471129 CreateSession();
[email protected]4dca587c2013-03-07 16:54:471130
[email protected]aa9b14d2013-05-10 23:45:191131 SendRequestAndExpectQuicResponse("hello!");
[email protected]4dca587c2013-03-07 16:54:471132
[email protected]98b20ce2013-05-10 05:55:261133 // Check that the NetLog was filled reasonably.
mmenke43758e62015-05-04 21:09:461134 TestNetLogEntry::List entries;
[email protected]aa9b14d2013-05-10 23:45:191135 net_log_.GetEntries(&entries);
[email protected]98b20ce2013-05-10 05:55:261136 EXPECT_LT(0u, entries.size());
1137
1138 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291139 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001140 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_RECEIVED,
1141 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261142 EXPECT_LT(0, pos);
1143
rchfd527212015-08-25 00:41:261144 // ... and also a TYPE_QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291145 pos = ExpectLogContainsSomewhere(
rchfd527212015-08-25 00:41:261146 entries, 0,
mikecirone8b85c432016-09-08 19:11:001147 NetLogEventType::QUIC_SESSION_UNAUTHENTICATED_PACKET_HEADER_RECEIVED,
1148 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261149 EXPECT_LT(0, pos);
1150
rtennetia004d332015-08-28 06:44:571151 std::string packet_number;
1152 ASSERT_TRUE(entries[pos].GetStringValue("packet_number", &packet_number));
1153 EXPECT_EQ("1", packet_number);
[email protected]98b20ce2013-05-10 05:55:261154
rchfd527212015-08-25 00:41:261155 // ... and also a TYPE_QUIC_SESSION_PACKET_AUTHENTICATED.
1156 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001157 entries, 0, NetLogEventType::QUIC_SESSION_PACKET_AUTHENTICATED,
1158 NetLogEventPhase::NONE);
rchfd527212015-08-25 00:41:261159 EXPECT_LT(0, pos);
1160
[email protected]98b20ce2013-05-10 05:55:261161 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
ttuttle859dc7a2015-04-23 19:42:291162 pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:001163 entries, 0, NetLogEventType::QUIC_SESSION_STREAM_FRAME_RECEIVED,
1164 NetLogEventPhase::NONE);
[email protected]98b20ce2013-05-10 05:55:261165 EXPECT_LT(0, pos);
1166
1167 int log_stream_id;
1168 ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
Fan Yang7c68f632018-11-06 03:05:381169 EXPECT_EQ(quic::QuicUtils::GetHeadersStreamId(version_),
1170 static_cast<quic::QuicStreamId>(log_stream_id));
[email protected]4dca587c2013-03-07 16:54:471171}
1172
rchbd089ab2017-05-26 23:05:041173TEST_P(QuicNetworkTransactionTest, LargeResponseHeaders) {
mmenke6ddfbea2017-05-31 21:48:411174 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041175 HostPortPair::FromString("mail.example.org:443"));
1176
1177 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521178 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041179 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431180 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1181 mock_quic_data.AddWrite(
1182 SYNCHRONOUS,
1183 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331184 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431185 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131186 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041187 response_headers["key1"] = std::string(30000, 'A');
1188 response_headers["key2"] = std::string(30000, 'A');
1189 response_headers["key3"] = std::string(30000, 'A');
1190 response_headers["key4"] = std::string(30000, 'A');
1191 response_headers["key5"] = std::string(30000, 'A');
1192 response_headers["key6"] = std::string(30000, 'A');
1193 response_headers["key7"] = std::string(30000, 'A');
1194 response_headers["key8"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331195 spdy::SpdyHeadersIR headers_frame(
1196 GetNthClientInitiatedBidirectionalStreamId(0),
1197 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131198 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1199 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041200 response_framer.SerializeFrame(headers_frame);
1201
Ryan Hamilton8d9ee76e2018-05-29 23:52:521202 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041203 size_t chunk_size = 1200;
1204 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1205 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431206 mock_quic_data.AddRead(
1207 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091208 packet_number++,
1209 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521210 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041211 }
1212
1213 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331214 ASYNC, ConstructServerDataPacket(
1215 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
1216 false, true, 0, "hello!"));
rchbd089ab2017-05-26 23:05:041217 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431218 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1219 mock_quic_data.AddWrite(ASYNC,
1220 ConstructClientAckPacket(4, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041221
1222 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1223
1224 CreateSession();
1225
1226 SendRequestAndExpectQuicResponse("hello!");
1227}
1228
1229TEST_P(QuicNetworkTransactionTest, TooLargeResponseHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:481230 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:411231 session_params_.origins_to_force_quic_on.insert(
rchbd089ab2017-05-26 23:05:041232 HostPortPair::FromString("mail.example.org:443"));
1233
1234 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521235 quic::QuicStreamOffset header_stream_offset = 0;
rchbd089ab2017-05-26 23:05:041236 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431237 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1238 mock_quic_data.AddWrite(
1239 SYNCHRONOUS,
1240 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331241 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431242 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:131243 spdy::SpdyHeaderBlock response_headers = GetResponseHeaders("200 OK");
rchbd089ab2017-05-26 23:05:041244 response_headers["key1"] = std::string(30000, 'A');
1245 response_headers["key2"] = std::string(30000, 'A');
1246 response_headers["key3"] = std::string(30000, 'A');
1247 response_headers["key4"] = std::string(30000, 'A');
1248 response_headers["key5"] = std::string(30000, 'A');
1249 response_headers["key6"] = std::string(30000, 'A');
1250 response_headers["key7"] = std::string(30000, 'A');
1251 response_headers["key8"] = std::string(30000, 'A');
1252 response_headers["key9"] = std::string(30000, 'A');
Fan Yang32c5a112018-12-10 20:06:331253 spdy::SpdyHeadersIR headers_frame(
1254 GetNthClientInitiatedBidirectionalStreamId(0),
1255 std::move(response_headers));
Ryan Hamilton0239aac2018-05-19 00:03:131256 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
1257 spdy::SpdySerializedFrame spdy_frame =
rchbd089ab2017-05-26 23:05:041258 response_framer.SerializeFrame(headers_frame);
1259
Ryan Hamilton8d9ee76e2018-05-29 23:52:521260 quic::QuicPacketNumber packet_number = 1;
rchbd089ab2017-05-26 23:05:041261 size_t chunk_size = 1200;
1262 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
1263 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
Zhongyi Shi32f2fd02018-04-16 18:23:431264 mock_quic_data.AddRead(
1265 ASYNC, ConstructServerDataPacket(
Ryan Hamilton47cf9d12018-10-17 04:33:091266 packet_number++,
1267 quic::QuicUtils::GetHeadersStreamId(version_), false, false,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521268 offset, base::StringPiece(spdy_frame.data() + offset, len)));
rchbd089ab2017-05-26 23:05:041269 }
1270
1271 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331272 ASYNC, ConstructServerDataPacket(
1273 packet_number, GetNthClientInitiatedBidirectionalStreamId(0),
1274 false, true, 0, "hello!"));
rchbd089ab2017-05-26 23:05:041275 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:431276 mock_quic_data.AddWrite(ASYNC, ConstructClientAckPacket(3, 2, 1, 1));
1277 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:331278 ASYNC, ConstructClientAckAndRstPacket(
1279 4, GetNthClientInitiatedBidirectionalStreamId(0),
1280 quic::QUIC_HEADERS_TOO_LARGE, packet_number, 3, 1));
rchbd089ab2017-05-26 23:05:041281
1282 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1283
1284 CreateSession();
1285
1286 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1287 TestCompletionCallback callback;
1288 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1289 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1290 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1291}
1292
rcha2bd44b2016-07-02 00:42:551293TEST_P(QuicNetworkTransactionTest, ForceQuicForAll) {
mmenke6ddfbea2017-05-31 21:48:411294 session_params_.origins_to_force_quic_on.insert(HostPortPair());
rcha2bd44b2016-07-02 00:42:551295
Ryan Hamilton9835e662018-08-02 05:36:271296 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
rcha2bd44b2016-07-02 00:42:551297
1298 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521299 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361300 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431301 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1302 mock_quic_data.AddWrite(
1303 SYNCHRONOUS,
1304 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331305 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431306 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431307 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331308 ASYNC, ConstructServerResponseHeadersPacket(
1309 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1310 GetResponseHeaders("200 OK")));
1311 mock_quic_data.AddRead(
1312 ASYNC, ConstructServerDataPacket(
1313 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1314 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431315 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rcha2bd44b2016-07-02 00:42:551316 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
1317
1318 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1319
1320 CreateSession();
1321
1322 SendRequestAndExpectQuicResponse("hello!");
1323 EXPECT_TRUE(
1324 test_socket_performance_watcher_factory_.rtt_notification_received());
1325}
1326
[email protected]cf3e3cd62014-02-05 16:16:161327TEST_P(QuicNetworkTransactionTest, QuicProxy) {
mmenke6ddfbea2017-05-31 21:48:411328 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591329 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491330 "QUIC mail.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cf3e3cd62014-02-05 16:16:161331
[email protected]cf3e3cd62014-02-05 16:16:161332 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521333 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361334 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431335 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1336 mock_quic_data.AddWrite(
1337 SYNCHRONOUS,
1338 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331339 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431340 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431341 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331342 ASYNC, ConstructServerResponseHeadersPacket(
1343 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1344 GetResponseHeaders("200 OK")));
1345 mock_quic_data.AddRead(
1346 ASYNC, ConstructServerDataPacket(
1347 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1348 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431349 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501350 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591351 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]cf3e3cd62014-02-05 16:16:161352
rcha5399e02015-04-21 19:32:041353 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]cf3e3cd62014-02-05 16:16:161354
tbansal0f56a39a2016-04-07 22:03:381355 EXPECT_FALSE(
1356 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161357 // There is no need to set up an alternate protocol job, because
1358 // no attempt will be made to speak to the proxy over TCP.
1359
rch9ae5b3b2016-02-11 00:36:291360 request_.url = GURL("http://mail.example.org/");
[email protected]cf3e3cd62014-02-05 16:16:161361 CreateSession();
1362
bnc62a44f022015-04-02 15:59:411363 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
tbansal0f56a39a2016-04-07 22:03:381364 EXPECT_TRUE(
1365 test_socket_performance_watcher_factory_.rtt_notification_received());
[email protected]cf3e3cd62014-02-05 16:16:161366}
1367
bnc313ba9c2015-06-11 15:42:311368// Regression test for https://crbug.com/492458. Test that for an HTTP
1369// connection through a QUIC proxy, the certificate exhibited by the proxy is
1370// checked against the proxy hostname, not the origin hostname.
1371TEST_P(QuicNetworkTransactionTest, QuicProxyWithCert) {
rch9ae5b3b2016-02-11 00:36:291372 const std::string origin_host = "mail.example.com";
bnc313ba9c2015-06-11 15:42:311373 const std::string proxy_host = "www.example.org";
1374
mmenke6ddfbea2017-05-31 21:48:411375 session_params_.enable_quic = true;
Lily Houghton8c2f97d2018-01-22 05:06:591376 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:491377 "QUIC " + proxy_host + ":70", TRAFFIC_ANNOTATION_FOR_TESTS);
bnc313ba9c2015-06-11 15:42:311378
alyssar2adf3ac2016-05-03 17:12:581379 client_maker_.set_hostname(origin_host);
bnc313ba9c2015-06-11 15:42:311380 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521381 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361382 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431383 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1384 mock_quic_data.AddWrite(
1385 SYNCHRONOUS,
1386 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331387 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431388 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431389 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331390 ASYNC, ConstructServerResponseHeadersPacket(
1391 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1392 GetResponseHeaders("200 OK")));
1393 mock_quic_data.AddRead(
1394 ASYNC, ConstructServerDataPacket(
1395 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1396 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431397 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:501398 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591399 mock_quic_data.AddRead(ASYNC, 0);
bnc313ba9c2015-06-11 15:42:311400 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1401
1402 scoped_refptr<X509Certificate> cert(
rch9ae5b3b2016-02-11 00:36:291403 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bnc313ba9c2015-06-11 15:42:311404 ASSERT_TRUE(cert.get());
1405 // This certificate is valid for the proxy, but not for the origin.
Ryan Sleevidef35f62018-01-23 21:12:241406 EXPECT_TRUE(cert->VerifyNameMatch(proxy_host));
1407 EXPECT_FALSE(cert->VerifyNameMatch(origin_host));
bnc313ba9c2015-06-11 15:42:311408 ProofVerifyDetailsChromium verify_details;
1409 verify_details.cert_verify_result.verified_cert = cert;
1410 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rchf114d982015-10-21 01:34:561411 ProofVerifyDetailsChromium verify_details2;
1412 verify_details2.cert_verify_result.verified_cert = cert;
1413 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
bnc313ba9c2015-06-11 15:42:311414
1415 request_.url = GURL("http://" + origin_host);
rtennetib8e80fb2016-05-16 00:12:091416 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321417 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:271418 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc313ba9c2015-06-11 15:42:311419 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
1420}
1421
rchbe69cb902016-02-11 01:10:481422TEST_P(QuicNetworkTransactionTest, AlternativeServicesDifferentHost) {
Ryan Hamiltonc84473f2017-11-23 03:18:341423 session_params_.quic_allow_remote_alt_svc = true;
rchbe69cb902016-02-11 01:10:481424 HostPortPair origin("www.example.org", 443);
1425 HostPortPair alternative("mail.example.org", 443);
1426
1427 base::FilePath certs_dir = GetTestCertsDirectory();
1428 scoped_refptr<X509Certificate> cert(
1429 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
1430 ASSERT_TRUE(cert.get());
1431 // TODO(rch): the connection should be "to" the origin, so if the cert is
1432 // valid for the origin but not the alternative, that should work too.
Ryan Sleevidef35f62018-01-23 21:12:241433 EXPECT_TRUE(cert->VerifyNameMatch(origin.host()));
1434 EXPECT_TRUE(cert->VerifyNameMatch(alternative.host()));
rchbe69cb902016-02-11 01:10:481435 ProofVerifyDetailsChromium verify_details;
1436 verify_details.cert_verify_result.verified_cert = cert;
1437 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1438
alyssar2adf3ac2016-05-03 17:12:581439 client_maker_.set_hostname(origin.host());
rchbe69cb902016-02-11 01:10:481440 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521441 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361442 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431443 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1444 mock_quic_data.AddWrite(
1445 SYNCHRONOUS,
1446 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331447 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431448 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431449 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331450 ASYNC, ConstructServerResponseHeadersPacket(
1451 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1452 GetResponseHeaders("200 OK")));
1453 mock_quic_data.AddRead(
1454 ASYNC, ConstructServerDataPacket(
1455 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1456 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431457 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchbe69cb902016-02-11 01:10:481458 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1459 mock_quic_data.AddRead(ASYNC, 0);
1460 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1461
1462 request_.url = GURL("https://" + origin.host());
1463 AddQuicRemoteAlternativeServiceMapping(
Ryan Hamilton9835e662018-08-02 05:36:271464 MockCryptoClientStream::CONFIRM_HANDSHAKE, alternative);
rtennetib8e80fb2016-05-16 00:12:091465 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321466 CreateSession();
rchbe69cb902016-02-11 01:10:481467
1468 SendRequestAndExpectQuicResponse("hello!");
1469}
1470
zhongyief3f4ce52017-07-05 23:53:281471TEST_P(QuicNetworkTransactionTest, DoNotUseQuicForUnsupportedVersion) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521472 quic::QuicTransportVersion unsupported_version =
1473 quic::QUIC_VERSION_UNSUPPORTED;
zhongyief3f4ce52017-07-05 23:53:281474 // Add support for another QUIC version besides |version_|. Also find a
1475 // unsupported version.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521476 for (const quic::QuicTransportVersion& version :
1477 quic::AllSupportedTransportVersions()) {
zhongyief3f4ce52017-07-05 23:53:281478 if (version == version_)
1479 continue;
1480 if (supported_versions_.size() != 2) {
1481 supported_versions_.push_back(version);
1482 continue;
1483 }
1484 unsupported_version = version;
1485 break;
1486 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521487 DCHECK_NE(unsupported_version, quic::QUIC_VERSION_UNSUPPORTED);
zhongyief3f4ce52017-07-05 23:53:281488
1489 // Set up alternative service to use QUIC with a version that is not
1490 // supported.
1491 url::SchemeHostPort server(request_.url);
1492 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1493 443);
1494 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
1495 http_server_properties_.SetQuicAlternativeService(
1496 server, alternative_service, expiration, {unsupported_version});
1497
1498 AlternativeServiceInfoVector alt_svc_info_vector =
1499 http_server_properties_.GetAlternativeServiceInfos(server);
1500 EXPECT_EQ(1u, alt_svc_info_vector.size());
1501 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1502 EXPECT_EQ(1u, alt_svc_info_vector[0].advertised_versions().size());
1503 EXPECT_EQ(unsupported_version,
1504 alt_svc_info_vector[0].advertised_versions()[0]);
1505
1506 // First request should still be sent via TCP as the QUIC version advertised
1507 // in the stored AlternativeService is not supported by the client. However,
1508 // the response from the server will advertise new Alt-Svc with supported
1509 // versions.
1510 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:521511 GenerateQuicVersionsListForAltSvcHeader(
1512 quic::AllSupportedTransportVersions());
zhongyief3f4ce52017-07-05 23:53:281513 std::string altsvc_header =
1514 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
1515 advertised_versions_list_str.c_str());
1516 MockRead http_reads[] = {
1517 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
1518 MockRead("hello world"),
1519 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1520 MockRead(ASYNC, OK)};
1521
Ryan Sleevib8d7ea02018-05-07 20:01:011522 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyief3f4ce52017-07-05 23:53:281523 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081524 AddCertificate(&ssl_data_);
zhongyief3f4ce52017-07-05 23:53:281525 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1526
1527 // Second request should be sent via QUIC as a new list of verions supported
1528 // by the client has been advertised by the server.
1529 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521530 quic::QuicStreamOffset header_stream_offset = 0;
zhongyief3f4ce52017-07-05 23:53:281531 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431532 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1533 mock_quic_data.AddWrite(
1534 SYNCHRONOUS,
1535 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331536 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431537 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431538 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331539 ASYNC, ConstructServerResponseHeadersPacket(
1540 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1541 GetResponseHeaders("200 OK")));
1542 mock_quic_data.AddRead(
1543 ASYNC, ConstructServerDataPacket(
1544 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1545 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431546 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyief3f4ce52017-07-05 23:53:281547 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1548 mock_quic_data.AddRead(ASYNC, 0); // EOF
1549
1550 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1551
1552 AddHangingNonAlternateProtocolSocketData();
1553
1554 CreateSession(supported_versions_);
1555
1556 SendRequestAndExpectHttpResponse("hello world");
1557 SendRequestAndExpectQuicResponse("hello!");
1558
1559 // Check alternative service list is updated with new versions.
1560 alt_svc_info_vector =
1561 session_->http_server_properties()->GetAlternativeServiceInfos(server);
1562 EXPECT_EQ(1u, alt_svc_info_vector.size());
1563 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
1564 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
1565 // Advertised versions will be lised in a sorted order.
1566 std::sort(supported_versions_.begin(), supported_versions_.end());
1567 EXPECT_EQ(supported_versions_[0],
1568 alt_svc_info_vector[0].advertised_versions()[0]);
1569 EXPECT_EQ(supported_versions_[1],
1570 alt_svc_info_vector[0].advertised_versions()[1]);
1571}
1572
bncaccd4962017-04-06 21:00:261573// Regression test for https://crbug.com/546991.
1574// The server might not be able to serve a request on an alternative connection,
1575// and might send a 421 Misdirected Request response status to indicate this.
1576// HttpNetworkTransaction should reset the request and retry without using
1577// alternative services.
1578TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) {
1579 // Set up alternative service to use QUIC.
1580 // Note that |origins_to_force_quic_on| cannot be used in this test, because
1581 // that overrides |enable_alternative_services|.
1582 url::SchemeHostPort server(request_.url);
1583 AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName,
1584 443);
1585 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:211586 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:441587 server, alternative_service, expiration, supported_versions_);
bncaccd4962017-04-06 21:00:261588
davidbena4449722017-05-05 23:30:531589 // First try: The alternative job uses QUIC and reports an HTTP 421
1590 // Misdirected Request error. The main job uses TCP, but |http_data| below is
1591 // paused at Connect(), so it will never exit the socket pool. This ensures
1592 // that the alternate job always wins the race and keeps whether the
1593 // |http_data| exits the socket pool before the main job is aborted
1594 // deterministic. The first main job gets aborted without the socket pool ever
1595 // dispensing the socket, making it available for the second try.
bncaccd4962017-04-06 21:00:261596 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521597 quic::QuicStreamOffset request_header_offset = 0;
rch5cb522462017-04-25 20:18:361598 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431599 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
1600 mock_quic_data.AddWrite(
1601 SYNCHRONOUS,
1602 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331603 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431604 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
Fan Yang32c5a112018-12-10 20:06:331605 mock_quic_data.AddRead(
1606 ASYNC, ConstructServerResponseHeadersPacket(
1607 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1608 GetResponseHeaders("421"), nullptr));
bncaccd4962017-04-06 21:00:261609 mock_quic_data.AddRead(ASYNC, OK);
1610 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1611
davidbena4449722017-05-05 23:30:531612 // Second try: The main job uses TCP, and there is no alternate job. Once the
1613 // Connect() is unblocked, |http_data| will leave the socket pool, binding to
1614 // the main job of the second request. It then succeeds over HTTP/1.1.
bncaccd4962017-04-06 21:00:261615 // Note that if there was an alternative QUIC Job created for the second try,
1616 // that would read these data, and would fail with ERR_QUIC_PROTOCOL_ERROR.
1617 // Therefore this test ensures that no alternative Job is created on retry.
davidbena4449722017-05-05 23:30:531618 MockWrite writes[] = {MockWrite(ASYNC, 0, "GET / HTTP/1.1\r\n"),
1619 MockWrite(ASYNC, 1, "Host: mail.example.org\r\n"),
1620 MockWrite(ASYNC, 2, "Connection: keep-alive\r\n\r\n")};
1621 MockRead reads[] = {MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1622 MockRead(ASYNC, 4, "hello!"), MockRead(ASYNC, OK, 5)};
1623 SequencedSocketData http_data(MockConnect(ASYNC, ERR_IO_PENDING) /* pause */,
Ryan Sleevib8d7ea02018-05-07 20:01:011624 reads, writes);
bncaccd4962017-04-06 21:00:261625 socket_factory_.AddSocketDataProvider(&http_data);
1626 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1627
bncaccd4962017-04-06 21:00:261628 CreateSession();
1629 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
davidbena4449722017-05-05 23:30:531630
1631 // Run until |mock_quic_data| has failed and |http_data| has paused.
1632 TestCompletionCallback callback;
1633 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1634 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1635 base::RunLoop().RunUntilIdle();
1636
1637 // |mock_quic_data| must have run to completion.
1638 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
1639 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
1640
1641 // Now that the QUIC data has been consumed, unblock |http_data|.
1642 http_data.socket()->OnConnectComplete(MockConnect());
1643
1644 // The retry logic must hide the 421 status. The transaction succeeds on
1645 // |http_data|.
1646 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncaccd4962017-04-06 21:00:261647 CheckWasHttpResponse(&trans);
1648 CheckResponsePort(&trans, 443);
1649 CheckResponseData(&trans, "hello!");
1650}
1651
[email protected]1e960032013-12-20 19:00:201652TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
mmenke6ddfbea2017-05-31 21:48:411653 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571654 HostPortPair::FromString("mail.example.org:443"));
[email protected]cebe3282013-05-22 23:49:301655
tbansalfdf5665b2015-09-21 22:46:401656 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521657 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361658 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431659 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
tbansalfdf5665b2015-09-21 22:46:401660 mock_quic_data1.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
tbansalfdf5665b2015-09-21 22:46:401661 MockQuicData mock_quic_data2;
fayang3bcb8b502016-12-07 21:44:371662 header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361663 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431664 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
zhongyi32569c62016-01-08 02:54:301665 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401666 mock_quic_data2.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
rch6faa4d42016-01-05 20:48:431667 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
tbansalfdf5665b2015-09-21 22:46:401668
1669 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
1670 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
[email protected]cebe3282013-05-22 23:49:301671
1672 CreateSession();
1673
tbansal0f56a39a2016-04-07 22:03:381674 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalfdf5665b2015-09-21 22:46:401675 for (size_t i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:161676 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
tbansalfdf5665b2015-09-21 22:46:401677 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:161678 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:011679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1680 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
tbansal0f56a39a2016-04-07 22:03:381681 EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count());
Ryan Hamiltone316e482017-08-17 02:48:531682
1683 NetErrorDetails details;
1684 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521685 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
tbansalfdf5665b2015-09-21 22:46:401686 }
[email protected]cebe3282013-05-22 23:49:301687}
1688
tbansalc8a94ea2015-11-02 23:58:511689TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
1690 // Attempt to "force" quic on 443, which will not be honored.
mmenke6ddfbea2017-05-31 21:48:411691 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:571692 HostPortPair::FromString("www.google.com:443"));
tbansalc8a94ea2015-11-02 23:58:511693
1694 MockRead http_reads[] = {
1695 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
1696 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1697 MockRead(ASYNC, OK)};
1698
Ryan Sleevib8d7ea02018-05-07 20:01:011699 StaticSocketDataProvider data(http_reads, base::span<MockWrite>());
tbansalc8a94ea2015-11-02 23:58:511700 socket_factory_.AddSocketDataProvider(&data);
1701 SSLSocketDataProvider ssl(ASYNC, OK);
1702 socket_factory_.AddSSLSocketDataProvider(&ssl);
1703
1704 CreateSession();
1705
1706 SendRequestAndExpectHttpResponse("hello world");
tbansal0f56a39a2016-04-07 22:03:381707 EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count());
tbansalc8a94ea2015-11-02 23:58:511708}
1709
bncc958faa2015-07-31 18:14:521710TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuic) {
bncc958faa2015-07-31 18:14:521711 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:561712 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
1713 MockRead("hello world"),
bncc958faa2015-07-31 18:14:521714 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1715 MockRead(ASYNC, OK)};
1716
Ryan Sleevib8d7ea02018-05-07 20:01:011717 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:521718 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081719 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:561720 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:521721
1722 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521723 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361724 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431725 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1726 mock_quic_data.AddWrite(
1727 SYNCHRONOUS,
1728 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331729 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431730 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431731 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331732 ASYNC, ConstructServerResponseHeadersPacket(
1733 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1734 GetResponseHeaders("200 OK")));
1735 mock_quic_data.AddRead(
1736 ASYNC, ConstructServerDataPacket(
1737 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1738 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431739 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:521740 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:591741 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:521742
1743 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1744
rtennetib8e80fb2016-05-16 00:12:091745 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:321746 CreateSession();
bncc958faa2015-07-31 18:14:521747
1748 SendRequestAndExpectHttpResponse("hello world");
1749 SendRequestAndExpectQuicResponse("hello!");
1750}
1751
zhongyia00ca012017-07-06 23:36:391752TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic1) {
1753 // Both server advertises and client supports two QUIC versions.
1754 // Only |version_| is advertised and supported.
1755 // The QuicStreamFactoy will pick up |version_|, which is verified as the
1756 // PacketMakers are using |version_|.
1757
1758 // Add support for another QUIC version besides |version_| on the client side.
1759 // Also find a different version advertised by the server.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521760 quic::QuicTransportVersion advertised_version_2 =
1761 quic::QUIC_VERSION_UNSUPPORTED;
1762 for (const quic::QuicTransportVersion& version :
1763 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391764 if (version == version_)
1765 continue;
1766 if (supported_versions_.size() != 2) {
1767 supported_versions_.push_back(version);
1768 continue;
1769 }
1770 advertised_version_2 = version;
1771 break;
1772 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521773 DCHECK_NE(advertised_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391774
1775 std::string QuicAltSvcWithVersionHeader =
1776 base::StringPrintf("Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n",
1777 advertised_version_2, version_);
1778
1779 MockRead http_reads[] = {
1780 MockRead("HTTP/1.1 200 OK\r\n"),
1781 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1782 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1783 MockRead(ASYNC, OK)};
1784
Ryan Sleevib8d7ea02018-05-07 20:01:011785 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391786 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081787 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391788 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1789
1790 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521791 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391792 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431793 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1794 mock_quic_data.AddWrite(
1795 SYNCHRONOUS,
1796 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331797 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431798 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431799 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331800 ASYNC, ConstructServerResponseHeadersPacket(
1801 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1802 GetResponseHeaders("200 OK")));
1803 mock_quic_data.AddRead(
1804 ASYNC, ConstructServerDataPacket(
1805 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1806 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431807 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391808 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1809 mock_quic_data.AddRead(ASYNC, 0); // EOF
1810
1811 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1812
1813 AddHangingNonAlternateProtocolSocketData();
1814 CreateSession(supported_versions_);
1815
1816 SendRequestAndExpectHttpResponse("hello world");
1817 SendRequestAndExpectQuicResponse("hello!");
1818}
1819
1820TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceWithVersionForQuic2) {
1821 // Client and server mutually support more than one QUIC_VERSION.
1822 // The QuicStreamFactoy will pick the preferred QUIC_VERSION: |version_|,
1823 // which is verified as the PacketMakers are using |version_|.
1824
Ryan Hamilton8d9ee76e2018-05-29 23:52:521825 quic::QuicTransportVersion common_version_2 = quic::QUIC_VERSION_UNSUPPORTED;
1826 for (const quic::QuicTransportVersion& version :
1827 quic::AllSupportedTransportVersions()) {
zhongyia00ca012017-07-06 23:36:391828 if (version == version_)
1829 continue;
1830 common_version_2 = version;
1831 break;
1832 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521833 DCHECK_NE(common_version_2, quic::QUIC_VERSION_UNSUPPORTED);
zhongyia00ca012017-07-06 23:36:391834
1835 supported_versions_.push_back(
1836 common_version_2); // Supported but unpreferred.
1837
1838 std::string QuicAltSvcWithVersionHeader = base::StringPrintf(
1839 "Alt-Svc: quic=\":443\";v=\"%d,%d\"\r\n\r\n", common_version_2, version_);
1840
1841 MockRead http_reads[] = {
1842 MockRead("HTTP/1.1 200 OK\r\n"),
1843 MockRead(QuicAltSvcWithVersionHeader.c_str()), MockRead("hello world"),
1844 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1845 MockRead(ASYNC, OK)};
1846
Ryan Sleevib8d7ea02018-05-07 20:01:011847 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyia00ca012017-07-06 23:36:391848 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081849 AddCertificate(&ssl_data_);
zhongyia00ca012017-07-06 23:36:391850 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1851
1852 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521853 quic::QuicStreamOffset header_stream_offset = 0;
zhongyia00ca012017-07-06 23:36:391854 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431855 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1856 mock_quic_data.AddWrite(
1857 SYNCHRONOUS,
1858 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331859 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431860 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431861 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331862 ASYNC, ConstructServerResponseHeadersPacket(
1863 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1864 GetResponseHeaders("200 OK")));
1865 mock_quic_data.AddRead(
1866 ASYNC, ConstructServerDataPacket(
1867 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1868 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431869 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyia00ca012017-07-06 23:36:391870 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1871 mock_quic_data.AddRead(ASYNC, 0); // EOF
1872
1873 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1874
1875 AddHangingNonAlternateProtocolSocketData();
1876 CreateSession(supported_versions_);
1877
1878 SendRequestAndExpectHttpResponse("hello world");
1879 SendRequestAndExpectQuicResponse("hello!");
1880}
1881
rchf47265dc2016-03-21 21:33:121882TEST_P(QuicNetworkTransactionTest,
1883 UseAlternativeServiceWithProbabilityForQuic) {
1884 MockRead http_reads[] = {
1885 MockRead("HTTP/1.1 200 OK\r\n"),
1886 MockRead(kQuicAlternativeServiceWithProbabilityHeader),
1887 MockRead("hello world"),
1888 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1889 MockRead(ASYNC, OK)};
1890
Ryan Sleevib8d7ea02018-05-07 20:01:011891 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
rchf47265dc2016-03-21 21:33:121892 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081893 AddCertificate(&ssl_data_);
rchf47265dc2016-03-21 21:33:121894 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1895
1896 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:521897 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:361898 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:431899 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
1900 mock_quic_data.AddWrite(
1901 SYNCHRONOUS,
1902 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:331903 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:431904 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:431905 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:331906 ASYNC, ConstructServerResponseHeadersPacket(
1907 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
1908 GetResponseHeaders("200 OK")));
1909 mock_quic_data.AddRead(
1910 ASYNC, ConstructServerDataPacket(
1911 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
1912 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:431913 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchf47265dc2016-03-21 21:33:121914 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
1915 mock_quic_data.AddRead(ASYNC, 0); // EOF
1916
1917 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
1918
rtennetib8e80fb2016-05-16 00:12:091919 AddHangingNonAlternateProtocolSocketData();
rchf47265dc2016-03-21 21:33:121920 CreateSession();
1921
1922 SendRequestAndExpectHttpResponse("hello world");
1923 SendRequestAndExpectQuicResponse("hello!");
1924}
1925
zhongyi3d4a55e72016-04-22 20:36:461926TEST_P(QuicNetworkTransactionTest, SetAlternativeServiceWithScheme) {
1927 MockRead http_reads[] = {
1928 MockRead("HTTP/1.1 200 OK\r\n"),
1929 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1930 MockRead("hello world"),
1931 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1932 MockRead(ASYNC, OK)};
1933
Ryan Sleevib8d7ea02018-05-07 20:01:011934 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi3d4a55e72016-04-22 20:36:461935 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:081936 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461937 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1938
1939 CreateSession();
bncb26024382016-06-29 02:39:451940 // Send https request, ignore alternative service advertising if response
zhongyi3d4a55e72016-04-22 20:36:461941 // header advertises alternative service for mail.example.org.
bncb26024382016-06-29 02:39:451942 request_.url = GURL("https://mail.example.org:443");
zhongyi3d4a55e72016-04-22 20:36:461943 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401944 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461945 session_->http_server_properties();
1946 url::SchemeHostPort http_server("http", "mail.example.org", 443);
1947 url::SchemeHostPort https_server("https", "mail.example.org", 443);
1948 // Check alternative service is set for the correct origin.
zhongyi3d4a55e72016-04-22 20:36:461949 EXPECT_EQ(
zhongyic4de03032017-05-19 04:07:341950 2u,
1951 http_server_properties->GetAlternativeServiceInfos(https_server).size());
bncb26024382016-06-29 02:39:451952 EXPECT_TRUE(
zhongyic4de03032017-05-19 04:07:341953 http_server_properties->GetAlternativeServiceInfos(http_server).empty());
zhongyi3d4a55e72016-04-22 20:36:461954}
1955
1956TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) {
1957 MockRead http_reads[] = {
1958 MockRead("HTTP/1.1 200 OK\r\n"),
1959 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
1960 MockRead("hello world"),
1961 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1962 MockRead(ASYNC, OK)};
1963
Ryan Sleevib8d7ea02018-05-07 20:01:011964 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:081965 AddCertificate(&ssl_data_);
zhongyi3d4a55e72016-04-22 20:36:461966
1967 socket_factory_.AddSocketDataProvider(&http_data);
1968 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1969 socket_factory_.AddSocketDataProvider(&http_data);
1970 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1971
1972 CreateSession();
1973
1974 // Send https request and set alternative services if response header
1975 // advertises alternative service for mail.example.org.
1976 SendRequestAndExpectHttpResponse("hello world");
bnc525e175a2016-06-20 12:36:401977 HttpServerProperties* http_server_properties =
zhongyi3d4a55e72016-04-22 20:36:461978 session_->http_server_properties();
1979
1980 const url::SchemeHostPort https_server(request_.url);
1981 // Check alternative service is set.
zhongyic4de03032017-05-19 04:07:341982 EXPECT_EQ(
1983 2u,
1984 http_server_properties->GetAlternativeServiceInfos(https_server).size());
zhongyi3d4a55e72016-04-22 20:36:461985
1986 // Send http request to the same origin but with diffrent scheme, should not
1987 // use QUIC.
1988 request_.url = GURL("http://mail.example.org:443");
1989 SendRequestAndExpectHttpResponse("hello world");
1990}
1991
zhongyie537a002017-06-27 16:48:211992TEST_P(QuicNetworkTransactionTest,
1993 StoreMutuallySupportedVersionsWhenProcessAltSvc) {
zhongyi86838d52017-06-30 01:19:441994 // Add support for another QUIC version besides |version_|.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521995 for (const quic::QuicTransportVersion& version :
1996 quic::AllSupportedTransportVersions()) {
zhongyi86838d52017-06-30 01:19:441997 if (version == version_)
1998 continue;
1999 supported_versions_.push_back(version);
2000 break;
2001 }
2002
zhongyie537a002017-06-27 16:48:212003 std::string advertised_versions_list_str =
Ryan Hamilton8d9ee76e2018-05-29 23:52:522004 GenerateQuicVersionsListForAltSvcHeader(
2005 quic::AllSupportedTransportVersions());
zhongyie537a002017-06-27 16:48:212006 std::string altsvc_header =
2007 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n",
2008 advertised_versions_list_str.c_str());
2009 MockRead http_reads[] = {
2010 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2011 MockRead("hello world"),
2012 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2013 MockRead(ASYNC, OK)};
2014
Ryan Sleevib8d7ea02018-05-07 20:01:012015 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyie537a002017-06-27 16:48:212016 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082017 AddCertificate(&ssl_data_);
zhongyie537a002017-06-27 16:48:212018 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2019
2020 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522021 quic::QuicStreamOffset header_stream_offset = 0;
zhongyie537a002017-06-27 16:48:212022 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432023 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2024 mock_quic_data.AddWrite(
2025 SYNCHRONOUS,
2026 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332027 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432028 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432029 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332030 ASYNC, ConstructServerResponseHeadersPacket(
2031 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2032 GetResponseHeaders("200 OK")));
2033 mock_quic_data.AddRead(
2034 ASYNC, ConstructServerDataPacket(
2035 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2036 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432037 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyie537a002017-06-27 16:48:212038 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2039 mock_quic_data.AddRead(ASYNC, 0); // EOF
2040
2041 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2042
2043 AddHangingNonAlternateProtocolSocketData();
2044
zhongyi86838d52017-06-30 01:19:442045 CreateSession(supported_versions_);
zhongyie537a002017-06-27 16:48:212046
2047 SendRequestAndExpectHttpResponse("hello world");
2048 SendRequestAndExpectQuicResponse("hello!");
2049
2050 // Check alternative service is set with only mutually supported versions.
2051 const url::SchemeHostPort https_server(request_.url);
2052 const AlternativeServiceInfoVector alt_svc_info_vector =
2053 session_->http_server_properties()->GetAlternativeServiceInfos(
2054 https_server);
2055 EXPECT_EQ(1u, alt_svc_info_vector.size());
2056 EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service().protocol);
2057 EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size());
2058 // Advertised versions will be lised in a sorted order.
zhongyi86838d52017-06-30 01:19:442059 std::sort(supported_versions_.begin(), supported_versions_.end());
2060 EXPECT_EQ(supported_versions_[0],
zhongyie537a002017-06-27 16:48:212061 alt_svc_info_vector[0].advertised_versions()[0]);
zhongyi86838d52017-06-30 01:19:442062 EXPECT_EQ(supported_versions_[1],
zhongyie537a002017-06-27 16:48:212063 alt_svc_info_vector[0].advertised_versions()[1]);
2064}
2065
danzh3134c2562016-08-12 14:07:522066TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) {
bnc90be5dd782016-11-09 16:28:442067 std::string altsvc_header =
2068 base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_);
bnc8be55ebb2015-10-30 14:12:072069 MockRead http_reads[] = {
2070 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2071 MockRead("hello world"),
2072 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2073 MockRead(ASYNC, OK)};
2074
Ryan Sleevib8d7ea02018-05-07 20:01:012075 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:072076 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:082077 AddCertificate(&ssl_data_);
bnc8be55ebb2015-10-30 14:12:072078 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2079
2080 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522081 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362082 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432083 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2084 mock_quic_data.AddWrite(
2085 SYNCHRONOUS,
2086 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332087 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432088 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:432089 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:332090 ASYNC, ConstructServerResponseHeadersPacket(
2091 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2092 GetResponseHeaders("200 OK")));
2093 mock_quic_data.AddRead(
2094 ASYNC, ConstructServerDataPacket(
2095 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2096 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:432097 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc8be55ebb2015-10-30 14:12:072098 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:592099 mock_quic_data.AddRead(ASYNC, 0); // EOF
bnc8be55ebb2015-10-30 14:12:072100
2101 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2102
rtennetib8e80fb2016-05-16 00:12:092103 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:322104 CreateSession();
bnc8be55ebb2015-10-30 14:12:072105
2106 SendRequestAndExpectHttpResponse("hello world");
2107 SendRequestAndExpectQuicResponse("hello!");
2108}
2109
zhongyi6b5a3892016-03-12 04:46:202110TEST_P(QuicNetworkTransactionTest, GoAwayWithConnectionMigrationOnPortsOnly) {
Frank Kastenholz6e4c5382018-06-21 23:00:092111 if (version_ == quic::QUIC_VERSION_99) {
2112 // Not available under version 99
2113 return;
2114 }
zhongyi6b5a3892016-03-12 04:46:202115 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522116 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:362117 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:432118 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2119 mock_quic_data.AddWrite(
2120 SYNCHRONOUS,
2121 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332122 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432123 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332124 mock_quic_data.AddRead(
2125 ASYNC, ConstructServerResponseHeadersPacket(
2126 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2127 GetResponseHeaders("200 OK")));
zhongyi6b5a3892016-03-12 04:46:202128 // Read a GoAway packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:522129 // quic::QuicErrorCode: quic::QUIC_ERROR_MIGRATING_PORT from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:432130 mock_quic_data.AddRead(SYNCHRONOUS,
2131 ConstructServerGoAwayPacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522132 2, quic::QUIC_ERROR_MIGRATING_PORT,
Zhongyi Shi32f2fd02018-04-16 18:23:432133 "connection migration with port change only"));
2134 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Fan Yang32c5a112018-12-10 20:06:332135 mock_quic_data.AddRead(
2136 SYNCHRONOUS, ConstructServerDataPacket(
2137 3, GetNthClientInitiatedBidirectionalStreamId(0), false,
2138 true, 0, "hello!"));
2139 mock_quic_data.AddWrite(SYNCHRONOUS,
2140 ConstructClientAckAndRstPacket(
2141 4, GetNthClientInitiatedBidirectionalStreamId(0),
2142 quic::QUIC_STREAM_CANCELLED, 3, 3, 1));
zhongyi6b5a3892016-03-12 04:46:202143 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2144 mock_quic_data.AddRead(ASYNC, 0); // EOF
2145
2146 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2147
2148 // The non-alternate protocol job needs to hang in order to guarantee that
2149 // the alternate-protocol job will "win".
2150 AddHangingNonAlternateProtocolSocketData();
2151
2152 // In order for a new QUIC session to be established via alternate-protocol
2153 // without racing an HTTP connection, we need the host resolution to happen
2154 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2155 // connection to the the server, in this test we require confirmation
2156 // before encrypting so the HTTP job will still start.
2157 host_resolver_.set_synchronous_mode(true);
2158 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2159 "");
2160 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2161 AddressList address;
maksim.sisov31452af2016-07-27 06:38:102162 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582163 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2164 CompletionOnceCallback(), &request,
2165 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412166 EXPECT_THAT(rv, IsOk());
zhongyi6b5a3892016-03-12 04:46:202167
2168 CreateSession();
2169 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:272170 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyi6b5a3892016-03-12 04:46:202171
bnc691fda62016-08-12 00:43:162172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyi6b5a3892016-03-12 04:46:202173 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412174 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:012175 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyi6b5a3892016-03-12 04:46:202176
2177 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522178 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:012179 EXPECT_THAT(callback.WaitForResult(), IsOk());
zhongyi6b5a3892016-03-12 04:46:202180
2181 // Check whether this transaction is correctly marked as received a go-away
2182 // because of migrating port.
2183 NetErrorDetails details;
2184 EXPECT_FALSE(details.quic_port_migration_detected);
bnc691fda62016-08-12 00:43:162185 trans.PopulateNetErrorDetails(&details);
zhongyi6b5a3892016-03-12 04:46:202186 EXPECT_TRUE(details.quic_port_migration_detected);
2187}
2188
Zhongyi Shia6b68d112018-09-24 07:49:032189// This test verifies that a new QUIC connection will be attempted on the
2190// alternate network if the original QUIC connection fails with idle timeout
2191// before handshake is confirmed. If TCP succeeds and QUIC fails on the
2192// alternate network as well, QUIC is marked as broken and the brokenness will
2193// not expire when default network changes.
2194TEST_P(QuicNetworkTransactionTest, QuicFailsOnBothNetworksWhileTCPSucceeds) {
2195 SetUpTestForRetryConnectionOnAlternateNetwork();
2196
2197 std::string request_data;
2198 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2199 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2200
2201 // The request will initially go out over QUIC.
2202 MockQuicData quic_data;
2203 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2204 int packet_num = 1;
2205 quic_data.AddWrite(SYNCHRONOUS,
2206 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2207 // Retranmit the handshake messages.
2208 quic_data.AddWrite(SYNCHRONOUS,
2209 client_maker_.MakeDummyCHLOPacket(packet_num++));
2210 quic_data.AddWrite(SYNCHRONOUS,
2211 client_maker_.MakeDummyCHLOPacket(packet_num++));
2212 quic_data.AddWrite(SYNCHRONOUS,
2213 client_maker_.MakeDummyCHLOPacket(packet_num++));
2214 quic_data.AddWrite(SYNCHRONOUS,
2215 client_maker_.MakeDummyCHLOPacket(packet_num++));
2216 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2217 if (version_ <= quic::QUIC_VERSION_39) {
2218 quic_data.AddWrite(SYNCHRONOUS,
2219 client_maker_.MakeDummyCHLOPacket(packet_num++));
2220 }
2221 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2222 quic_data.AddWrite(SYNCHRONOUS,
2223 client_maker_.MakeConnectionClosePacket(
2224 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2225 "No recent network activity."));
2226 quic_data.AddSocketDataToFactory(&socket_factory_);
2227
2228 // Add successful TCP data so that TCP job will succeed.
2229 MockWrite http_writes[] = {
2230 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2231 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2232 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2233
2234 MockRead http_reads[] = {
2235 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2236 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2237 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2238 SequencedSocketData http_data(http_reads, http_writes);
2239 socket_factory_.AddSocketDataProvider(&http_data);
2240 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2241
2242 // Add data for the second QUIC connection to fail.
2243 MockQuicData quic_data2;
2244 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2245 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE); // Write error.
2246 quic_data2.AddSocketDataToFactory(&socket_factory_);
2247
2248 // Resolve the host resolution synchronously.
2249 host_resolver_.set_synchronous_mode(true);
2250 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2251 "");
2252 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2253 AddressList address;
2254 std::unique_ptr<HostResolver::Request> request;
2255 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2256 CompletionOnceCallback(), &request,
2257 net_log_.bound());
2258 EXPECT_THAT(rv, IsOk());
2259
2260 CreateSession();
2261 session_->quic_stream_factory()->set_require_confirmation(true);
2262 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2263 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2264 QuicStreamFactoryPeer::SetAlarmFactory(
2265 session_->quic_stream_factory(),
2266 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2267 &clock_));
2268 // Add alternate protocol mapping to race QUIC and TCP.
2269 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2270 // peer.
2271 AddQuicAlternateProtocolMapping(
2272 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2273
2274 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2275 TestCompletionCallback callback;
2276 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2278
2279 // Pump the message loop to get the request started.
2280 // Request will be served with TCP job.
2281 base::RunLoop().RunUntilIdle();
2282 EXPECT_THAT(callback.WaitForResult(), IsOk());
2283 CheckResponseData(&trans, "TCP succeeds");
2284
2285 // Fire the retransmission alarm, from this point, connection will idle
2286 // timeout after 4 seconds.
Zhongyi Shia15736c2018-09-25 00:31:182287 if (!quic::GetQuicReloadableFlag(
2288 quic_fix_time_of_first_packet_sent_after_receiving)) {
2289 quic_task_runner_->RunNextTask();
2290 }
Zhongyi Shia6b68d112018-09-24 07:49:032291 // Fast forward to idle timeout the original connection. A new connection will
2292 // be kicked off on the alternate network.
2293 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2294 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2295 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2296
2297 // Run the message loop to execute posted tasks, which will report job status.
2298 base::RunLoop().RunUntilIdle();
2299
2300 // Verify that QUIC is marked as broken.
2301 ExpectBrokenAlternateProtocolMapping();
2302
2303 // Deliver a message to notify the new network becomes default, the brokenness
2304 // will not expire as QUIC is broken on both networks.
2305 scoped_mock_change_notifier_->mock_network_change_notifier()
2306 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2307 ExpectBrokenAlternateProtocolMapping();
2308
2309 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2310 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2311}
2312
2313// This test verifies that a new QUIC connection will be attempted on the
2314// alternate network if the original QUIC connection fails with idle timeout
2315// before handshake is confirmed. If TCP succeeds and QUIC succeeds on the
2316// alternate network, QUIC is marked as broken. The brokenness will expire when
2317// the default network changes.
2318TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPSucceeds) {
2319 SetUpTestForRetryConnectionOnAlternateNetwork();
2320
2321 std::string request_data;
2322 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2323 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2324
2325 // The request will initially go out over QUIC.
2326 MockQuicData quic_data;
2327 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2328 int packet_num = 1;
2329 quic_data.AddWrite(SYNCHRONOUS,
2330 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2331 // Retranmit the handshake messages.
2332 quic_data.AddWrite(SYNCHRONOUS,
2333 client_maker_.MakeDummyCHLOPacket(packet_num++));
2334 quic_data.AddWrite(SYNCHRONOUS,
2335 client_maker_.MakeDummyCHLOPacket(packet_num++));
2336 quic_data.AddWrite(SYNCHRONOUS,
2337 client_maker_.MakeDummyCHLOPacket(packet_num++));
2338 quic_data.AddWrite(SYNCHRONOUS,
2339 client_maker_.MakeDummyCHLOPacket(packet_num++));
2340 // TODO(zhongyi): remove condition check once b/115926584 is fixed.
2341 if (version_ <= quic::QUIC_VERSION_39) {
2342 quic_data.AddWrite(SYNCHRONOUS,
2343 client_maker_.MakeDummyCHLOPacket(packet_num++));
2344 }
2345 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2346 quic_data.AddWrite(SYNCHRONOUS,
2347 client_maker_.MakeConnectionClosePacket(
2348 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2349 "No recent network activity."));
2350 quic_data.AddSocketDataToFactory(&socket_factory_);
2351
2352 // Add successful TCP data so that TCP job will succeed.
2353 MockWrite http_writes[] = {
2354 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2355 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2356 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2357
2358 MockRead http_reads[] = {
2359 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2360 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2361 MockRead(SYNCHRONOUS, 5, "TCP succeeds"), MockRead(SYNCHRONOUS, OK, 6)};
2362 SequencedSocketData http_data(http_reads, http_writes);
2363 socket_factory_.AddSocketDataProvider(&http_data);
2364 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2365
2366 // Quic connection will be retried on the alternate network after the initial
2367 // one fails on the default network.
2368 MockQuicData quic_data2;
2369 quic::QuicStreamOffset header_stream_offset = 0;
2370 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Handing read.
2371 quic_data2.AddWrite(SYNCHRONOUS,
2372 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2373
2374 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2375 quic_data2.AddWrite(SYNCHRONOUS,
2376 ConstructInitialSettingsPacket(2, &header_stream_offset));
2377 quic_data2.AddSocketDataToFactory(&socket_factory_);
2378
2379 // Resolve the host resolution synchronously.
2380 host_resolver_.set_synchronous_mode(true);
2381 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2382 "");
2383 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2384 AddressList address;
2385 std::unique_ptr<HostResolver::Request> request;
2386 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2387 CompletionOnceCallback(), &request,
2388 net_log_.bound());
2389 EXPECT_THAT(rv, IsOk());
2390
2391 CreateSession();
2392 session_->quic_stream_factory()->set_require_confirmation(true);
2393 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2394 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2395 QuicStreamFactoryPeer::SetAlarmFactory(
2396 session_->quic_stream_factory(),
2397 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2398 &clock_));
2399 // Add alternate protocol mapping to race QUIC and TCP.
2400 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2401 // peer.
2402 AddQuicAlternateProtocolMapping(
2403 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2404
2405 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2406 TestCompletionCallback callback;
2407 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2409
2410 // Pump the message loop to get the request started.
2411 // Request will be served with TCP job.
2412 base::RunLoop().RunUntilIdle();
2413 EXPECT_THAT(callback.WaitForResult(), IsOk());
2414 CheckResponseData(&trans, "TCP succeeds");
2415
2416 // Fire the retransmission alarm, after which connection will idle
2417 // timeout after 4 seconds.
Zhongyi Shia15736c2018-09-25 00:31:182418 if (!quic::GetQuicReloadableFlag(
2419 quic_fix_time_of_first_packet_sent_after_receiving)) {
2420 quic_task_runner_->RunNextTask();
2421 }
Zhongyi Shia6b68d112018-09-24 07:49:032422 // Fast forward to idle timeout the original connection. A new connection will
2423 // be kicked off on the alternate network.
2424 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2425 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2426 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2427
2428 // The second connection hasn't finish handshake, verify that QUIC is not
2429 // marked as broken.
2430 ExpectQuicAlternateProtocolMapping();
2431 // Explicitly confirm the handshake on the second connection.
2432 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2433 quic::QuicSession::HANDSHAKE_CONFIRMED);
2434 // Run message loop to execute posted tasks, which will notify JoController
2435 // about the orphaned job status.
2436 base::RunLoop().RunUntilIdle();
2437
2438 // Verify that QUIC is marked as broken.
2439 ExpectBrokenAlternateProtocolMapping();
2440
2441 // Deliver a message to notify the new network becomes default, the previous
2442 // brokenness will be clear as the brokenness is bond with old default
2443 // network.
2444 scoped_mock_change_notifier_->mock_network_change_notifier()
2445 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2446 ExpectQuicAlternateProtocolMapping();
2447
2448 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2449 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2450}
2451
2452// This test verifies that a new QUIC connection will be attempted on the
2453// alternate network if the original QUIC connection fails with idle timeout
2454// before handshake is confirmed. If TCP doesn't succeed but QUIC on the
2455// alternative network succeeds, QUIC is not marked as broken.
2456TEST_P(QuicNetworkTransactionTest, RetryOnAlternateNetworkWhileTCPHanging) {
2457 SetUpTestForRetryConnectionOnAlternateNetwork();
2458
2459 std::string request_data;
2460 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2461 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
2462
2463 // The request will initially go out over QUIC.
2464 MockQuicData quic_data;
2465 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read
2466 int packet_num = 1;
2467 quic_data.AddWrite(SYNCHRONOUS,
2468 client_maker_.MakeDummyCHLOPacket(packet_num++)); // CHLO
2469 // Retranmit the handshake messages.
2470 quic_data.AddWrite(SYNCHRONOUS,
2471 client_maker_.MakeDummyCHLOPacket(packet_num++));
2472 quic_data.AddWrite(SYNCHRONOUS,
2473 client_maker_.MakeDummyCHLOPacket(packet_num++));
2474 quic_data.AddWrite(SYNCHRONOUS,
2475 client_maker_.MakeDummyCHLOPacket(packet_num++));
2476 quic_data.AddWrite(SYNCHRONOUS,
2477 client_maker_.MakeDummyCHLOPacket(packet_num++));
2478 // TODO(zhongyi): remove condition check once b/115926584 is fixed, i.e.,
2479 // quic_fix_has_pending_crypto_data is introduced and enabled.
2480 if (version_ <= quic::QUIC_VERSION_39) {
2481 quic_data.AddWrite(SYNCHRONOUS,
2482 client_maker_.MakeDummyCHLOPacket(packet_num++));
2483 }
2484 // After timeout, connection will be closed with QUIC_NETWORK_IDLE_TIMEOUT.
2485 quic_data.AddWrite(SYNCHRONOUS,
2486 client_maker_.MakeConnectionClosePacket(
2487 packet_num++, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
2488 "No recent network activity."));
2489 quic_data.AddSocketDataToFactory(&socket_factory_);
2490
2491 // Add hanging TCP data so that TCP job will never succeeded.
2492 AddHangingNonAlternateProtocolSocketData();
2493
2494 // Quic connection will then be retried on the alternate network.
2495 MockQuicData quic_data2;
2496 quic::QuicStreamOffset header_stream_offset = 0;
2497 quic_data2.AddWrite(SYNCHRONOUS,
2498 client_maker_.MakeDummyCHLOPacket(1)); // CHLO
2499
2500 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
2501 quic_data2.AddWrite(SYNCHRONOUS,
2502 ConstructInitialSettingsPacket(2, &header_stream_offset));
2503 quic_data2.AddWrite(
2504 SYNCHRONOUS,
2505 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332506 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shia6b68d112018-09-24 07:49:032507 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shia6b68d112018-09-24 07:49:032508 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332509 ASYNC, ConstructServerResponseHeadersPacket(
2510 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
2511 GetResponseHeaders("200 OK")));
2512 quic_data2.AddRead(
2513 ASYNC, ConstructServerDataPacket(
2514 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
2515 0, "hello!"));
Zhongyi Shia6b68d112018-09-24 07:49:032516 quic_data2.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
2517 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
2518 quic_data2.AddSocketDataToFactory(&socket_factory_);
2519
2520 // Resolve the host resolution synchronously.
2521 host_resolver_.set_synchronous_mode(true);
2522 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2523 "");
2524 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2525 AddressList address;
2526 std::unique_ptr<HostResolver::Request> request;
2527 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2528 CompletionOnceCallback(), &request,
2529 net_log_.bound());
2530 EXPECT_THAT(rv, IsOk());
2531
2532 CreateSession();
2533 session_->quic_stream_factory()->set_require_confirmation(true);
2534 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2535 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
2536 QuicStreamFactoryPeer::SetAlarmFactory(
2537 session_->quic_stream_factory(),
2538 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2539 &clock_));
2540 // Add alternate protocol mapping to race QUIC and TCP.
2541 // QUIC connection requires handshake to be confirmed and sends CHLO to the
2542 // peer.
2543 AddQuicAlternateProtocolMapping(
2544 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
2545
2546 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2547 TestCompletionCallback callback;
2548 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2549 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2550
2551 // Pump the message loop to get the request started.
2552 base::RunLoop().RunUntilIdle();
Zhongyi Shia15736c2018-09-25 00:31:182553 if (!quic::GetQuicReloadableFlag(
2554 quic_fix_time_of_first_packet_sent_after_receiving)) {
2555 quic_task_runner_->RunNextTask();
2556 }
Zhongyi Shia6b68d112018-09-24 07:49:032557
2558 // Fast forward to idle timeout the original connection. A new connection will
2559 // be kicked off on the alternate network.
2560 quic_task_runner_->FastForwardBy(quic::QuicTime::Delta::FromSeconds(4));
2561 ASSERT_TRUE(quic_data.AllReadDataConsumed());
2562 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2563
2564 // Verify that QUIC is not marked as broken.
2565 ExpectQuicAlternateProtocolMapping();
2566 // Explicitly confirm the handshake on the second connection.
2567 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2568 quic::QuicSession::HANDSHAKE_CONFIRMED);
2569
2570 // Read the response.
2571 EXPECT_THAT(callback.WaitForResult(), IsOk());
2572 CheckResponseData(&trans, "hello!");
2573 // Verify that QUIC is not marked as broken.
2574 ExpectQuicAlternateProtocolMapping();
2575
2576 // Deliver a message to notify the new network becomes default.
2577 scoped_mock_change_notifier_->mock_network_change_notifier()
2578 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2579 ExpectQuicAlternateProtocolMapping();
2580 ASSERT_TRUE(quic_data2.AllReadDataConsumed());
2581 ASSERT_TRUE(quic_data2.AllWriteDataConsumed());
2582}
2583
rch9ecde09b2017-04-08 00:18:232584// Verify that if a QUIC connection times out, the QuicHttpStream will
2585// return QUIC_PROTOCOL_ERROR.
2586TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482587 session_params_.retry_without_alt_svc_on_quic_errors = false;
mmenke6ddfbea2017-05-31 21:48:412588 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:232589
2590 // The request will initially go out over QUIC.
2591 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522592 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132593 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232594 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2595
2596 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522597 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2598 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432599 quic_data.AddWrite(SYNCHRONOUS,
2600 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332601 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2602 true, priority, GetRequestHeaders("GET", "https", "/"),
2603 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232604
2605 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522606 quic::QuicStreamOffset settings_offset = header_stream_offset;
2607 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432608 quic_data.AddWrite(SYNCHRONOUS,
2609 client_maker_.MakeInitialSettingsPacketAndSaveData(
2610 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232611 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092612 quic_data.AddWrite(SYNCHRONOUS,
2613 client_maker_.MakeDataPacket(
2614 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2615 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232616 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092617 quic_data.AddWrite(SYNCHRONOUS,
2618 client_maker_.MakeDataPacket(
2619 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2620 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232621 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092622 quic_data.AddWrite(SYNCHRONOUS,
2623 client_maker_.MakeDataPacket(
2624 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2625 false, 0, request_data));
2626 quic_data.AddWrite(SYNCHRONOUS,
2627 client_maker_.MakeDataPacket(
2628 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2629 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232630 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092631 quic_data.AddWrite(SYNCHRONOUS,
2632 client_maker_.MakeDataPacket(
2633 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2634 false, 0, request_data));
2635 quic_data.AddWrite(SYNCHRONOUS,
2636 client_maker_.MakeDataPacket(
2637 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2638 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232639 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092640 quic_data.AddWrite(SYNCHRONOUS,
2641 client_maker_.MakeDataPacket(
2642 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2643 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522644 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092645 SYNCHRONOUS, client_maker_.MakeDataPacket(
2646 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2647 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232648
Zhongyi Shi32f2fd02018-04-16 18:23:432649 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522650 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:432651 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:222652
rch9ecde09b2017-04-08 00:18:232653 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
2654 quic_data.AddRead(ASYNC, OK);
2655 quic_data.AddSocketDataToFactory(&socket_factory_);
2656
2657 // In order for a new QUIC session to be established via alternate-protocol
2658 // without racing an HTTP connection, we need the host resolution to happen
2659 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2660 // connection to the the server, in this test we require confirmation
2661 // before encrypting so the HTTP job will still start.
2662 host_resolver_.set_synchronous_mode(true);
2663 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2664 "");
2665 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2666 AddressList address;
2667 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582668 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2669 CompletionOnceCallback(), &request,
2670 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412671 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232672
2673 CreateSession();
2674 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552675 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232676 QuicStreamFactoryPeer::SetAlarmFactory(
2677 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192678 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552679 &clock_));
rch9ecde09b2017-04-08 00:18:232680
Ryan Hamilton9835e662018-08-02 05:36:272681 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232682
2683 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2684 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412685 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2687
2688 // Pump the message loop to get the request started.
2689 base::RunLoop().RunUntilIdle();
2690 // Explicitly confirm the handshake.
2691 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522692 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232693
2694 // Run the QUIC session to completion.
2695 quic_task_runner_->RunUntilIdle();
2696
2697 ExpectQuicAlternateProtocolMapping();
2698 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2699 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2700}
2701
2702// Verify that if a QUIC connection RTOs, the QuicHttpStream will
2703// return QUIC_PROTOCOL_ERROR.
2704TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482705 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522706 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232707
2708 // The request will initially go out over QUIC.
2709 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522710 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132711 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232712 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2713
2714 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522715 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2716 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432717 quic_data.AddWrite(SYNCHRONOUS,
2718 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332719 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2720 true, priority, GetRequestHeaders("GET", "https", "/"),
2721 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232722
2723 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522724 quic::QuicStreamOffset settings_offset = header_stream_offset;
2725 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432726 quic_data.AddWrite(SYNCHRONOUS,
2727 client_maker_.MakeInitialSettingsPacketAndSaveData(
2728 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232729 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092730 quic_data.AddWrite(SYNCHRONOUS,
2731 client_maker_.MakeDataPacket(
2732 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
2733 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232734 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092735 quic_data.AddWrite(SYNCHRONOUS,
2736 client_maker_.MakeDataPacket(
2737 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2738 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232739 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:092740 quic_data.AddWrite(SYNCHRONOUS,
2741 client_maker_.MakeDataPacket(
2742 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2743 false, 0, request_data));
2744 quic_data.AddWrite(SYNCHRONOUS,
2745 client_maker_.MakeDataPacket(
2746 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
2747 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232748 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092749 quic_data.AddWrite(SYNCHRONOUS,
2750 client_maker_.MakeDataPacket(
2751 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2752 false, 0, request_data));
2753 quic_data.AddWrite(SYNCHRONOUS,
2754 client_maker_.MakeDataPacket(
2755 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2756 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232757 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:092758 quic_data.AddWrite(SYNCHRONOUS,
2759 client_maker_.MakeDataPacket(
2760 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
2761 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522762 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092763 SYNCHRONOUS, client_maker_.MakeDataPacket(
2764 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2765 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232766 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:522767 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092768 SYNCHRONOUS, client_maker_.MakeDataPacket(
2769 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2770 false, 0, request_data));
2771 quic_data.AddWrite(
2772 SYNCHRONOUS, client_maker_.MakeDataPacket(
2773 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
2774 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232775 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432776 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522777 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432778 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232779
2780 quic_data.AddRead(ASYNC, OK);
2781 quic_data.AddSocketDataToFactory(&socket_factory_);
2782
2783 // In order for a new QUIC session to be established via alternate-protocol
2784 // without racing an HTTP connection, we need the host resolution to happen
2785 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2786 // connection to the the server, in this test we require confirmation
2787 // before encrypting so the HTTP job will still start.
2788 host_resolver_.set_synchronous_mode(true);
2789 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2790 "");
2791 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2792 AddressList address;
2793 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582794 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2795 CompletionOnceCallback(), &request,
2796 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412797 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232798
2799 CreateSession();
2800 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552801 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232802 QuicStreamFactoryPeer::SetAlarmFactory(
2803 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192804 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552805 &clock_));
rch9ecde09b2017-04-08 00:18:232806
Ryan Hamilton9835e662018-08-02 05:36:272807 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232808
2809 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2810 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412811 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232812 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2813
2814 // Pump the message loop to get the request started.
2815 base::RunLoop().RunUntilIdle();
2816 // Explicitly confirm the handshake.
2817 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522818 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232819
2820 // Run the QUIC session to completion.
2821 quic_task_runner_->RunUntilIdle();
2822
2823 ExpectQuicAlternateProtocolMapping();
2824 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2825 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
2826}
2827
2828// Verify that if a QUIC connection RTOs, while there are no active streams
2829// QUIC will not be marked as broken.
2830TEST_P(QuicNetworkTransactionTest,
2831 TooManyRtosAfterHandshakeConfirmedAndStreamReset) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:522832 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:232833
2834 // The request will initially go out over QUIC.
2835 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522836 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:132837 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:232838 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2839
2840 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522841 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2842 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432843 quic_data.AddWrite(SYNCHRONOUS,
2844 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:332845 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
2846 true, priority, GetRequestHeaders("GET", "https", "/"),
2847 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:232848
2849 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522850 quic::QuicStreamOffset settings_offset = header_stream_offset;
2851 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432852 quic_data.AddWrite(SYNCHRONOUS,
2853 client_maker_.MakeInitialSettingsPacketAndSaveData(
2854 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:232855
Fan Yang32c5a112018-12-10 20:06:332856 quic_data.AddWrite(SYNCHRONOUS,
2857 client_maker_.MakeRstPacket(
2858 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
2859 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232860 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:092861 quic_data.AddWrite(SYNCHRONOUS,
2862 client_maker_.MakeDataPacket(
2863 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
2864 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232865 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:092866 quic_data.AddWrite(SYNCHRONOUS,
2867 client_maker_.MakeDataPacket(
2868 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
2869 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232870 // RTO 1
Fan Yang32c5a112018-12-10 20:06:332871 quic_data.AddWrite(SYNCHRONOUS,
2872 client_maker_.MakeRstPacket(
2873 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
2874 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:092875 quic_data.AddWrite(SYNCHRONOUS,
2876 client_maker_.MakeDataPacket(
2877 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
2878 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232879 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:092880 quic_data.AddWrite(SYNCHRONOUS,
2881 client_maker_.MakeDataPacket(
2882 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
2883 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:332884 quic_data.AddWrite(SYNCHRONOUS,
2885 client_maker_.MakeRstPacket(
2886 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
2887 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:232888 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:522889 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092890 SYNCHRONOUS, client_maker_.MakeDataPacket(
2891 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
2892 false, 0, request_data));
2893 quic_data.AddWrite(
2894 SYNCHRONOUS, client_maker_.MakeDataPacket(
2895 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
2896 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:232897 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:432898 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332899 SYNCHRONOUS, client_maker_.MakeRstPacket(
2900 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
2901 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522902 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:092903 SYNCHRONOUS, client_maker_.MakeDataPacket(
2904 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
2905 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:232906 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:432907 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522908 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:432909 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:232910
2911 quic_data.AddRead(ASYNC, OK);
2912 quic_data.AddSocketDataToFactory(&socket_factory_);
2913
2914 // In order for a new QUIC session to be established via alternate-protocol
2915 // without racing an HTTP connection, we need the host resolution to happen
2916 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2917 // connection to the the server, in this test we require confirmation
2918 // before encrypting so the HTTP job will still start.
2919 host_resolver_.set_synchronous_mode(true);
2920 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2921 "");
2922 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2923 AddressList address;
2924 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:582925 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
2926 CompletionOnceCallback(), &request,
2927 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:412928 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:232929
2930 CreateSession();
2931 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:552932 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:232933 QuicStreamFactoryPeer::SetAlarmFactory(
2934 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:192935 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:552936 &clock_));
rch9ecde09b2017-04-08 00:18:232937
Ryan Hamilton9835e662018-08-02 05:36:272938 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:232939
Jeremy Roman0579ed62017-08-29 15:56:192940 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:232941 session_.get());
2942 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:412943 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:232944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2945
2946 // Pump the message loop to get the request started.
2947 base::RunLoop().RunUntilIdle();
2948 // Explicitly confirm the handshake.
2949 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522950 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:232951
2952 // Now cancel the request.
2953 trans.reset();
2954
2955 // Run the QUIC session to completion.
2956 quic_task_runner_->RunUntilIdle();
2957
2958 ExpectQuicAlternateProtocolMapping();
2959
2960 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2961}
2962
rch2f2991c2017-04-13 19:28:172963// Verify that if a QUIC protocol error occurs after the handshake is confirmed
2964// the request fails with QUIC_PROTOCOL_ERROR.
2965TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
Ryan Hamiltonb3827e882018-03-27 03:07:482966 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch2f2991c2017-04-13 19:28:172967 // The request will initially go out over QUIC.
2968 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:522969 quic::QuicStreamOffset header_stream_offset = 0;
2970 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
2971 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:432972 quic_data.AddWrite(
2973 SYNCHRONOUS,
2974 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:332975 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:432976 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:522977 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:432978 quic_data.AddWrite(SYNCHRONOUS,
2979 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:172980 // Peer sending data from an non-existing stream causes this end to raise
2981 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:332982 quic_data.AddRead(
2983 ASYNC, ConstructServerRstPacket(
2984 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
2985 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:172986 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:432987 quic_data.AddWrite(SYNCHRONOUS,
2988 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522989 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
2990 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:172991 quic_data.AddSocketDataToFactory(&socket_factory_);
2992
2993 // In order for a new QUIC session to be established via alternate-protocol
2994 // without racing an HTTP connection, we need the host resolution to happen
2995 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2996 // connection to the the server, in this test we require confirmation
2997 // before encrypting so the HTTP job will still start.
2998 host_resolver_.set_synchronous_mode(true);
2999 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3000 "");
3001 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3002 AddressList address;
3003 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583004 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3005 CompletionOnceCallback(), &request,
3006 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413007 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173008
3009 CreateSession();
3010
Ryan Hamilton9835e662018-08-02 05:36:273011 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173012
3013 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3014 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413015 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173016 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3017
3018 // Pump the message loop to get the request started.
3019 base::RunLoop().RunUntilIdle();
3020 // Explicitly confirm the handshake.
3021 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523022 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173023
3024 ASSERT_FALSE(quic_data.AllReadDataConsumed());
3025
3026 // Run the QUIC session to completion.
3027 base::RunLoop().RunUntilIdle();
3028 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3029 ASSERT_TRUE(quic_data.AllReadDataConsumed());
3030
3031 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
3032 ExpectQuicAlternateProtocolMapping();
3033 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3034}
3035
rch9ecde09b2017-04-08 00:18:233036// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3037// connection times out, then QUIC will be marked as broken and the request
3038// retried over TCP.
3039TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413040 session_params_.mark_quic_broken_when_network_blackholes = true;
3041 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233042
3043 // The request will initially go out over QUIC.
3044 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523045 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133046 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233047 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3048
3049 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523050 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3051 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433052 quic_data.AddWrite(SYNCHRONOUS,
3053 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333054 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3055 true, priority, GetRequestHeaders("GET", "https", "/"),
3056 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233057
3058 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523059 quic::QuicStreamOffset settings_offset = header_stream_offset;
3060 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433061 quic_data.AddWrite(SYNCHRONOUS,
3062 client_maker_.MakeInitialSettingsPacketAndSaveData(
3063 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233064 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093065 quic_data.AddWrite(SYNCHRONOUS,
3066 client_maker_.MakeDataPacket(
3067 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3068 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233069 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093070 quic_data.AddWrite(SYNCHRONOUS,
3071 client_maker_.MakeDataPacket(
3072 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3073 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233074 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093075 quic_data.AddWrite(SYNCHRONOUS,
3076 client_maker_.MakeDataPacket(
3077 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3078 false, 0, request_data));
3079 quic_data.AddWrite(SYNCHRONOUS,
3080 client_maker_.MakeDataPacket(
3081 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3082 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233083 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093084 quic_data.AddWrite(SYNCHRONOUS,
3085 client_maker_.MakeDataPacket(
3086 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3087 false, 0, request_data));
3088 quic_data.AddWrite(SYNCHRONOUS,
3089 client_maker_.MakeDataPacket(
3090 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3091 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233092 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093093 quic_data.AddWrite(SYNCHRONOUS,
3094 client_maker_.MakeDataPacket(
3095 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3096 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523097 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093098 SYNCHRONOUS, client_maker_.MakeDataPacket(
3099 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3100 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233101
Zhongyi Shi32f2fd02018-04-16 18:23:433102 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523103 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433104 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223105
rch9ecde09b2017-04-08 00:18:233106 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3107 quic_data.AddRead(ASYNC, OK);
3108 quic_data.AddSocketDataToFactory(&socket_factory_);
3109
3110 // After that fails, it will be resent via TCP.
3111 MockWrite http_writes[] = {
3112 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3113 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3114 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3115
3116 MockRead http_reads[] = {
3117 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3118 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3119 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013120 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233121 socket_factory_.AddSocketDataProvider(&http_data);
3122 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3123
3124 // In order for a new QUIC session to be established via alternate-protocol
3125 // without racing an HTTP connection, we need the host resolution to happen
3126 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3127 // connection to the the server, in this test we require confirmation
3128 // before encrypting so the HTTP job will still start.
3129 host_resolver_.set_synchronous_mode(true);
3130 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3131 "");
3132 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3133 AddressList address;
3134 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583135 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3136 CompletionOnceCallback(), &request,
3137 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413138 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233139
3140 CreateSession();
3141 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553142 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233143 QuicStreamFactoryPeer::SetAlarmFactory(
3144 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193145 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553146 &clock_));
rch9ecde09b2017-04-08 00:18:233147
Ryan Hamilton9835e662018-08-02 05:36:273148 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233149
3150 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3151 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413152 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3154
3155 // Pump the message loop to get the request started.
3156 base::RunLoop().RunUntilIdle();
3157 // Explicitly confirm the handshake.
3158 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523159 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233160
3161 // Run the QUIC session to completion.
3162 quic_task_runner_->RunUntilIdle();
3163 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3164
3165 // Let the transaction proceed which will result in QUIC being marked
3166 // as broken and the request falling back to TCP.
3167 EXPECT_THAT(callback.WaitForResult(), IsOk());
3168
3169 ExpectBrokenAlternateProtocolMapping();
3170 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3171 ASSERT_FALSE(http_data.AllReadDataConsumed());
3172
3173 // Read the response body over TCP.
3174 CheckResponseData(&trans, "hello world");
3175 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3176 ASSERT_TRUE(http_data.AllReadDataConsumed());
3177}
3178
rch2f2991c2017-04-13 19:28:173179// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3180// connection times out, then QUIC will be marked as broken and the request
3181// retried over TCP.
3182TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
mmenke6ddfbea2017-05-31 21:48:413183 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173184
3185 // The request will initially go out over QUIC.
3186 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523187 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133188 spdy::SpdyPriority priority =
rch2f2991c2017-04-13 19:28:173189 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3190
3191 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523192 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3193 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433194 quic_data.AddWrite(SYNCHRONOUS,
3195 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333196 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3197 true, priority, GetRequestHeaders("GET", "https", "/"),
3198 0, nullptr, &header_stream_offset, &request_data));
rch2f2991c2017-04-13 19:28:173199
3200 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523201 quic::QuicStreamOffset settings_offset = header_stream_offset;
3202 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433203 quic_data.AddWrite(SYNCHRONOUS,
3204 client_maker_.MakeInitialSettingsPacketAndSaveData(
3205 2, &header_stream_offset, &settings_data));
rch2f2991c2017-04-13 19:28:173206 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093207 quic_data.AddWrite(SYNCHRONOUS,
3208 client_maker_.MakeDataPacket(
3209 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3210 false, 0, request_data));
rch2f2991c2017-04-13 19:28:173211 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093212 quic_data.AddWrite(SYNCHRONOUS,
3213 client_maker_.MakeDataPacket(
3214 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3215 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173216 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093217 quic_data.AddWrite(SYNCHRONOUS,
3218 client_maker_.MakeDataPacket(
3219 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3220 false, 0, request_data));
3221 quic_data.AddWrite(SYNCHRONOUS,
3222 client_maker_.MakeDataPacket(
3223 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3224 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173225 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093226 quic_data.AddWrite(SYNCHRONOUS,
3227 client_maker_.MakeDataPacket(
3228 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3229 false, 0, request_data));
3230 quic_data.AddWrite(SYNCHRONOUS,
3231 client_maker_.MakeDataPacket(
3232 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3233 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173234 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093235 quic_data.AddWrite(SYNCHRONOUS,
3236 client_maker_.MakeDataPacket(
3237 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3238 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523239 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093240 SYNCHRONOUS, client_maker_.MakeDataPacket(
3241 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3242 false, settings_offset, settings_data));
rch2f2991c2017-04-13 19:28:173243
Zhongyi Shi32f2fd02018-04-16 18:23:433244 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523245 11, true, quic::QUIC_NETWORK_IDLE_TIMEOUT,
Zhongyi Shi32f2fd02018-04-16 18:23:433246 "No recent network activity."));
Fan Yang928f1632017-12-14 18:55:223247
rch2f2991c2017-04-13 19:28:173248 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3249 quic_data.AddRead(ASYNC, OK);
3250 quic_data.AddSocketDataToFactory(&socket_factory_);
3251
3252 // After that fails, it will be resent via TCP.
3253 MockWrite http_writes[] = {
3254 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3255 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3256 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3257
3258 MockRead http_reads[] = {
3259 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3260 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3261 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013262 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173263 socket_factory_.AddSocketDataProvider(&http_data);
3264 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3265
3266 // In order for a new QUIC session to be established via alternate-protocol
3267 // without racing an HTTP connection, we need the host resolution to happen
3268 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3269 // connection to the the server, in this test we require confirmation
3270 // before encrypting so the HTTP job will still start.
3271 host_resolver_.set_synchronous_mode(true);
3272 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3273 "");
3274 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3275 AddressList address;
3276 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583277 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3278 CompletionOnceCallback(), &request,
3279 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413280 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173281
3282 CreateSession();
3283 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553284 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch2f2991c2017-04-13 19:28:173285 QuicStreamFactoryPeer::SetAlarmFactory(
3286 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193287 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553288 &clock_));
rch2f2991c2017-04-13 19:28:173289
Ryan Hamilton9835e662018-08-02 05:36:273290 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173291
3292 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3293 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413294 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173295 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3296
3297 // Pump the message loop to get the request started.
3298 base::RunLoop().RunUntilIdle();
3299 // Explicitly confirm the handshake.
3300 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523301 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173302
3303 // Run the QUIC session to completion.
3304 quic_task_runner_->RunUntilIdle();
3305 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3306
3307 ExpectQuicAlternateProtocolMapping();
3308
3309 // Let the transaction proceed which will result in QUIC being marked
3310 // as broken and the request falling back to TCP.
3311 EXPECT_THAT(callback.WaitForResult(), IsOk());
3312
3313 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3314 ASSERT_FALSE(http_data.AllReadDataConsumed());
3315
3316 // Read the response body over TCP.
3317 CheckResponseData(&trans, "hello world");
3318 ExpectBrokenAlternateProtocolMapping();
3319 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3320 ASSERT_TRUE(http_data.AllReadDataConsumed());
3321}
3322
rch9ecde09b2017-04-08 00:18:233323// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3324// connection times out, then QUIC will be marked as broken but the request
3325// will not be retried over TCP.
3326TEST_P(QuicNetworkTransactionTest,
3327 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
mmenke6ddfbea2017-05-31 21:48:413328 session_params_.mark_quic_broken_when_network_blackholes = true;
3329 session_params_.quic_idle_connection_timeout_seconds = 5;
rch9ecde09b2017-04-08 00:18:233330
3331 // The request will initially go out over QUIC.
3332 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523333 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133334 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233335 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3336
3337 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523338 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3339 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433340 quic_data.AddWrite(SYNCHRONOUS,
3341 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333342 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3343 true, priority, GetRequestHeaders("GET", "https", "/"),
3344 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233345
3346 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523347 quic::QuicStreamOffset settings_offset = header_stream_offset;
3348 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433349 quic_data.AddWrite(SYNCHRONOUS,
3350 client_maker_.MakeInitialSettingsPacketAndSaveData(
3351 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233352
Zhongyi Shi32f2fd02018-04-16 18:23:433353 quic_data.AddRead(ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333354 1, GetNthClientInitiatedBidirectionalStreamId(0),
3355 false, false, GetResponseHeaders("200 OK")));
Zhongyi Shi32f2fd02018-04-16 18:23:433356 // quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 1, 1));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523357 quic_data.AddWrite(
3358 SYNCHRONOUS,
3359 ConstructClientAckPacket(3, 1, 1, 1,
3360 quic::QuicTime::Delta::FromMilliseconds(25)));
rch9ecde09b2017-04-08 00:18:233361
3362 // TLP 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523363 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093364 SYNCHRONOUS, client_maker_.MakeDataPacket(
3365 4, quic::QuicUtils::GetHeadersStreamId(version_), false,
3366 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233367 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093368 quic_data.AddWrite(
3369 SYNCHRONOUS, client_maker_.MakeDataPacket(
3370 5, quic::QuicUtils::GetHeadersStreamId(version_), false,
3371 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233372 // RTO 1
Ryan Hamilton8d9ee76e2018-05-29 23:52:523373 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093374 SYNCHRONOUS, client_maker_.MakeDataPacket(
3375 6, quic::QuicUtils::GetHeadersStreamId(version_), false,
3376 false, 0, request_data));
3377 quic_data.AddWrite(
3378 SYNCHRONOUS, client_maker_.MakeDataPacket(
3379 7, quic::QuicUtils::GetHeadersStreamId(version_), false,
3380 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233381 // RTO 2
Ryan Hamilton8d9ee76e2018-05-29 23:52:523382 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093383 SYNCHRONOUS, client_maker_.MakeDataPacket(
3384 8, quic::QuicUtils::GetHeadersStreamId(version_), false,
3385 false, 0, request_data));
3386 quic_data.AddWrite(
3387 SYNCHRONOUS, client_maker_.MakeDataPacket(
3388 9, quic::QuicUtils::GetHeadersStreamId(version_), false,
3389 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233390 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523391 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093392 SYNCHRONOUS, client_maker_.MakeDataPacket(
3393 10, quic::QuicUtils::GetHeadersStreamId(version_), false,
3394 false, 0, request_data));
3395 quic_data.AddWrite(
3396 SYNCHRONOUS, client_maker_.MakeDataPacket(
3397 11, quic::QuicUtils::GetHeadersStreamId(version_), false,
3398 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233399
Zhongyi Shia15736c2018-09-25 00:31:183400 if (quic::GetQuicReloadableFlag(
3401 quic_fix_time_of_first_packet_sent_after_receiving)) {
3402 quic_data.AddWrite(
3403 SYNCHRONOUS,
3404 client_maker_.MakeAckAndConnectionClosePacket(
3405 12, false, quic::QuicTime::Delta::FromMilliseconds(4000), 1, 1, 1,
3406 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3407
3408 } else {
3409 quic_data.AddWrite(
3410 SYNCHRONOUS,
3411 client_maker_.MakeAckAndConnectionClosePacket(
3412 12, false, quic::QuicTime::Delta::FromMilliseconds(4200), 1, 1, 1,
3413 quic::QUIC_NETWORK_IDLE_TIMEOUT, "No recent network activity."));
3414 }
Fan Yang928f1632017-12-14 18:55:223415
rch9ecde09b2017-04-08 00:18:233416 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
3417 quic_data.AddRead(ASYNC, OK);
3418 quic_data.AddSocketDataToFactory(&socket_factory_);
3419
3420 // In order for a new QUIC session to be established via alternate-protocol
3421 // without racing an HTTP connection, we need the host resolution to happen
3422 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3423 // connection to the the server, in this test we require confirmation
3424 // before encrypting so the HTTP job will still start.
3425 host_resolver_.set_synchronous_mode(true);
3426 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3427 "");
3428 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3429 AddressList address;
3430 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583431 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3432 CompletionOnceCallback(), &request,
3433 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413434 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233435
3436 CreateSession();
3437 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553438 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233439 QuicStreamFactoryPeer::SetAlarmFactory(
3440 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193441 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553442 &clock_));
rch9ecde09b2017-04-08 00:18:233443
Ryan Hamilton9835e662018-08-02 05:36:273444 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233445
3446 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3447 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413448 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233449 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3450
3451 // Pump the message loop to get the request started.
3452 base::RunLoop().RunUntilIdle();
3453 // Explicitly confirm the handshake.
3454 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523455 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233456
3457 // Pump the message loop to get the request started.
3458 base::RunLoop().RunUntilIdle();
3459
3460 // Run the QUIC session to completion.
3461 quic_task_runner_->RunUntilIdle();
3462 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3463
3464 // Let the transaction proceed which will result in QUIC being marked
3465 // as broken and the request falling back to TCP.
3466 EXPECT_THAT(callback.WaitForResult(), IsOk());
3467
3468 ExpectBrokenAlternateProtocolMapping();
3469 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3470
3471 std::string response_data;
3472 ASSERT_THAT(ReadTransaction(&trans, &response_data),
3473 IsError(ERR_QUIC_PROTOCOL_ERROR));
3474}
3475
3476// Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
3477// connection RTOs, then QUIC will be marked as broken and the request retried
3478// over TCP.
3479TEST_P(QuicNetworkTransactionTest,
3480 TooManyRtosAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413481 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523482 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233483
3484 // The request will initially go out over QUIC.
3485 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523486 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133487 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233488 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3489
3490 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523491 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3492 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433493 quic_data.AddWrite(SYNCHRONOUS,
3494 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333495 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3496 true, priority, GetRequestHeaders("GET", "https", "/"),
3497 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233498
3499 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523500 quic::QuicStreamOffset settings_offset = header_stream_offset;
3501 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433502 quic_data.AddWrite(SYNCHRONOUS,
3503 client_maker_.MakeInitialSettingsPacketAndSaveData(
3504 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233505 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093506 quic_data.AddWrite(SYNCHRONOUS,
3507 client_maker_.MakeDataPacket(
3508 3, quic::QuicUtils::GetHeadersStreamId(version_), true,
3509 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233510 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093511 quic_data.AddWrite(SYNCHRONOUS,
3512 client_maker_.MakeDataPacket(
3513 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3514 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233515 // RTO 1
Ryan Hamilton47cf9d12018-10-17 04:33:093516 quic_data.AddWrite(SYNCHRONOUS,
3517 client_maker_.MakeDataPacket(
3518 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3519 false, 0, request_data));
3520 quic_data.AddWrite(SYNCHRONOUS,
3521 client_maker_.MakeDataPacket(
3522 6, quic::QuicUtils::GetHeadersStreamId(version_), true,
3523 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233524 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093525 quic_data.AddWrite(SYNCHRONOUS,
3526 client_maker_.MakeDataPacket(
3527 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3528 false, 0, request_data));
3529 quic_data.AddWrite(SYNCHRONOUS,
3530 client_maker_.MakeDataPacket(
3531 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3532 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233533 // RTO 3
Ryan Hamilton47cf9d12018-10-17 04:33:093534 quic_data.AddWrite(SYNCHRONOUS,
3535 client_maker_.MakeDataPacket(
3536 9, quic::QuicUtils::GetHeadersStreamId(version_), true,
3537 false, 0, request_data));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523538 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093539 SYNCHRONOUS, client_maker_.MakeDataPacket(
3540 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3541 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233542 // RTO 4
Ryan Hamilton8d9ee76e2018-05-29 23:52:523543 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093544 SYNCHRONOUS, client_maker_.MakeDataPacket(
3545 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3546 false, 0, request_data));
3547 quic_data.AddWrite(
3548 SYNCHRONOUS, client_maker_.MakeDataPacket(
3549 12, quic::QuicUtils::GetHeadersStreamId(version_), true,
3550 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233551
Zhongyi Shi32f2fd02018-04-16 18:23:433552 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523553 13, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433554 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233555
3556 quic_data.AddRead(ASYNC, OK);
3557 quic_data.AddSocketDataToFactory(&socket_factory_);
3558
3559 // After that fails, it will be resent via TCP.
3560 MockWrite http_writes[] = {
3561 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3562 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3563 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3564
3565 MockRead http_reads[] = {
3566 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3567 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3568 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013569 SequencedSocketData http_data(http_reads, http_writes);
rch9ecde09b2017-04-08 00:18:233570 socket_factory_.AddSocketDataProvider(&http_data);
3571 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3572
3573 // In order for a new QUIC session to be established via alternate-protocol
3574 // without racing an HTTP connection, we need the host resolution to happen
3575 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3576 // connection to the the server, in this test we require confirmation
3577 // before encrypting so the HTTP job will still start.
3578 host_resolver_.set_synchronous_mode(true);
3579 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3580 "");
3581 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3582 AddressList address;
3583 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583584 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3585 CompletionOnceCallback(), &request,
3586 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413587 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233588
3589 CreateSession();
3590 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553591 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233592 QuicStreamFactoryPeer::SetAlarmFactory(
3593 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193594 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553595 &clock_));
rch9ecde09b2017-04-08 00:18:233596
Ryan Hamilton9835e662018-08-02 05:36:273597 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233598
3599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3600 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413601 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233602 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3603
3604 // Pump the message loop to get the request started.
3605 base::RunLoop().RunUntilIdle();
3606 // Explicitly confirm the handshake.
3607 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523608 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233609
3610 // Run the QUIC session to completion.
3611 quic_task_runner_->RunUntilIdle();
3612 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3613
3614 // Let the transaction proceed which will result in QUIC being marked
3615 // as broken and the request falling back to TCP.
3616 EXPECT_THAT(callback.WaitForResult(), IsOk());
3617
3618 ExpectBrokenAlternateProtocolMapping();
3619 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3620 ASSERT_FALSE(http_data.AllReadDataConsumed());
3621
3622 // Read the response body over TCP.
3623 CheckResponseData(&trans, "hello world");
3624 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3625 ASSERT_TRUE(http_data.AllReadDataConsumed());
3626}
3627
3628// Verify that if a QUIC connection RTOs, while there are no active streams
3629// QUIC will be marked as broken.
3630TEST_P(QuicNetworkTransactionTest,
3631 TooManyRtosAfterHandshakeConfirmedAndStreamResetThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413632 session_params_.mark_quic_broken_when_network_blackholes = true;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523633 session_params_.quic_connection_options.push_back(quic::k5RTO);
rch9ecde09b2017-04-08 00:18:233634
3635 // The request will initially go out over QUIC.
3636 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523637 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133638 spdy::SpdyPriority priority =
rch9ecde09b2017-04-08 00:18:233639 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3640
3641 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523642 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3643 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433644 quic_data.AddWrite(SYNCHRONOUS,
3645 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333646 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3647 true, priority, GetRequestHeaders("GET", "https", "/"),
3648 0, nullptr, &header_stream_offset, &request_data));
rch9ecde09b2017-04-08 00:18:233649
3650 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523651 quic::QuicStreamOffset settings_offset = header_stream_offset;
3652 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433653 quic_data.AddWrite(SYNCHRONOUS,
3654 client_maker_.MakeInitialSettingsPacketAndSaveData(
3655 2, &header_stream_offset, &settings_data));
rch9ecde09b2017-04-08 00:18:233656
Fan Yang32c5a112018-12-10 20:06:333657 quic_data.AddWrite(SYNCHRONOUS,
3658 client_maker_.MakeRstPacket(
3659 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
3660 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233661 // TLP 1
Ryan Hamilton47cf9d12018-10-17 04:33:093662 quic_data.AddWrite(SYNCHRONOUS,
3663 client_maker_.MakeDataPacket(
3664 4, quic::QuicUtils::GetHeadersStreamId(version_), true,
3665 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233666 // TLP 2
Ryan Hamilton47cf9d12018-10-17 04:33:093667 quic_data.AddWrite(SYNCHRONOUS,
3668 client_maker_.MakeDataPacket(
3669 5, quic::QuicUtils::GetHeadersStreamId(version_), true,
3670 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233671 // RTO 1
Fan Yang32c5a112018-12-10 20:06:333672 quic_data.AddWrite(SYNCHRONOUS,
3673 client_maker_.MakeRstPacket(
3674 6, true, GetNthClientInitiatedBidirectionalStreamId(0),
3675 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton47cf9d12018-10-17 04:33:093676 quic_data.AddWrite(SYNCHRONOUS,
3677 client_maker_.MakeDataPacket(
3678 7, quic::QuicUtils::GetHeadersStreamId(version_), true,
3679 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233680 // RTO 2
Ryan Hamilton47cf9d12018-10-17 04:33:093681 quic_data.AddWrite(SYNCHRONOUS,
3682 client_maker_.MakeDataPacket(
3683 8, quic::QuicUtils::GetHeadersStreamId(version_), true,
3684 false, settings_offset, settings_data));
Fan Yang32c5a112018-12-10 20:06:333685 quic_data.AddWrite(SYNCHRONOUS,
3686 client_maker_.MakeRstPacket(
3687 9, true, GetNthClientInitiatedBidirectionalStreamId(0),
3688 quic::QUIC_STREAM_CANCELLED));
rch9ecde09b2017-04-08 00:18:233689 // RTO 3
Ryan Hamilton8d9ee76e2018-05-29 23:52:523690 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093691 SYNCHRONOUS, client_maker_.MakeDataPacket(
3692 10, quic::QuicUtils::GetHeadersStreamId(version_), true,
3693 false, 0, request_data));
3694 quic_data.AddWrite(
3695 SYNCHRONOUS, client_maker_.MakeDataPacket(
3696 11, quic::QuicUtils::GetHeadersStreamId(version_), true,
3697 false, settings_offset, settings_data));
rch9ecde09b2017-04-08 00:18:233698 // RTO 4
Zhongyi Shi32f2fd02018-04-16 18:23:433699 quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333700 SYNCHRONOUS, client_maker_.MakeRstPacket(
3701 12, true, GetNthClientInitiatedBidirectionalStreamId(0),
3702 quic::QUIC_STREAM_CANCELLED));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523703 quic_data.AddWrite(
Ryan Hamilton47cf9d12018-10-17 04:33:093704 SYNCHRONOUS, client_maker_.MakeDataPacket(
3705 13, quic::QuicUtils::GetHeadersStreamId(version_), true,
3706 false, 0, request_data));
rch9ecde09b2017-04-08 00:18:233707 // RTO 5
Zhongyi Shi32f2fd02018-04-16 18:23:433708 quic_data.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523709 14, true, quic::QUIC_TOO_MANY_RTOS,
Zhongyi Shi32f2fd02018-04-16 18:23:433710 "5 consecutive retransmission timeouts"));
rch9ecde09b2017-04-08 00:18:233711
3712 quic_data.AddRead(ASYNC, OK);
3713 quic_data.AddSocketDataToFactory(&socket_factory_);
3714
3715 // In order for a new QUIC session to be established via alternate-protocol
3716 // without racing an HTTP connection, we need the host resolution to happen
3717 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3718 // connection to the the server, in this test we require confirmation
3719 // before encrypting so the HTTP job will still start.
3720 host_resolver_.set_synchronous_mode(true);
3721 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3722 "");
3723 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3724 AddressList address;
3725 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583726 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3727 CompletionOnceCallback(), &request,
3728 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413729 EXPECT_THAT(rv, IsOk());
rch9ecde09b2017-04-08 00:18:233730
3731 CreateSession();
3732 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
rchbf4c26d2017-04-16 23:17:553733 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
rch9ecde09b2017-04-08 00:18:233734 QuicStreamFactoryPeer::SetAlarmFactory(
3735 session_->quic_stream_factory(),
Jeremy Roman0579ed62017-08-29 15:56:193736 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
rchbf4c26d2017-04-16 23:17:553737 &clock_));
rch9ecde09b2017-04-08 00:18:233738
Ryan Hamilton9835e662018-08-02 05:36:273739 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch9ecde09b2017-04-08 00:18:233740
Jeremy Roman0579ed62017-08-29 15:56:193741 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch9ecde09b2017-04-08 00:18:233742 session_.get());
3743 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413744 rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rch9ecde09b2017-04-08 00:18:233745 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3746
3747 // Pump the message loop to get the request started.
3748 base::RunLoop().RunUntilIdle();
3749 // Explicitly confirm the handshake.
3750 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523751 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch9ecde09b2017-04-08 00:18:233752
3753 // Now cancel the request.
3754 trans.reset();
3755
3756 // Run the QUIC session to completion.
3757 quic_task_runner_->RunUntilIdle();
3758
3759 ExpectBrokenAlternateProtocolMapping();
3760
3761 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3762}
3763
rch2f2991c2017-04-13 19:28:173764// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3765// protocol error occurs after the handshake is confirmed, the request
3766// retried over TCP and the QUIC will be marked as broken.
3767TEST_P(QuicNetworkTransactionTest,
3768 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
mmenke6ddfbea2017-05-31 21:48:413769 session_params_.quic_idle_connection_timeout_seconds = 5;
rch2f2991c2017-04-13 19:28:173770
3771 // The request will initially go out over QUIC.
3772 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523773 quic::QuicStreamOffset header_stream_offset = 0;
3774 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3775 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433776 quic_data.AddWrite(
3777 SYNCHRONOUS,
3778 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333779 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433780 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:523781 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433782 quic_data.AddWrite(SYNCHRONOUS,
3783 ConstructInitialSettingsPacket(2, &header_stream_offset));
rch2f2991c2017-04-13 19:28:173784 // Peer sending data from an non-existing stream causes this end to raise
3785 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:333786 quic_data.AddRead(
3787 ASYNC, ConstructServerRstPacket(
3788 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
3789 quic::QUIC_STREAM_LAST_ERROR));
rch2f2991c2017-04-13 19:28:173790 std::string quic_error_details = "Data for nonexistent stream";
Zhongyi Shi32f2fd02018-04-16 18:23:433791 quic_data.AddWrite(SYNCHRONOUS,
3792 ConstructClientAckAndConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523793 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
3794 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
rch2f2991c2017-04-13 19:28:173795 quic_data.AddSocketDataToFactory(&socket_factory_);
3796
3797 // After that fails, it will be resent via TCP.
3798 MockWrite http_writes[] = {
3799 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3800 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3801 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3802
3803 MockRead http_reads[] = {
3804 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3805 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3806 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013807 SequencedSocketData http_data(http_reads, http_writes);
rch2f2991c2017-04-13 19:28:173808 socket_factory_.AddSocketDataProvider(&http_data);
3809 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3810
3811 // In order for a new QUIC session to be established via alternate-protocol
3812 // without racing an HTTP connection, we need the host resolution to happen
3813 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3814 // connection to the the server, in this test we require confirmation
3815 // before encrypting so the HTTP job will still start.
3816 host_resolver_.set_synchronous_mode(true);
3817 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3818 "");
3819 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3820 AddressList address;
3821 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583822 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3823 CompletionOnceCallback(), &request,
3824 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413825 EXPECT_THAT(rv, IsOk());
rch2f2991c2017-04-13 19:28:173826
3827 CreateSession();
3828
Ryan Hamilton9835e662018-08-02 05:36:273829 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch2f2991c2017-04-13 19:28:173830
3831 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3832 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413833 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch2f2991c2017-04-13 19:28:173834 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3835
3836 // Pump the message loop to get the request started.
3837 base::RunLoop().RunUntilIdle();
3838 // Explicitly confirm the handshake.
3839 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523840 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch2f2991c2017-04-13 19:28:173841
3842 // Run the QUIC session to completion.
3843 base::RunLoop().RunUntilIdle();
3844 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3845
3846 ExpectQuicAlternateProtocolMapping();
3847
3848 // Let the transaction proceed which will result in QUIC being marked
3849 // as broken and the request falling back to TCP.
3850 EXPECT_THAT(callback.WaitForResult(), IsOk());
3851
3852 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3853 ASSERT_FALSE(http_data.AllReadDataConsumed());
3854
3855 // Read the response body over TCP.
3856 CheckResponseData(&trans, "hello world");
3857 ExpectBrokenAlternateProtocolMapping();
3858 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3859 ASSERT_TRUE(http_data.AllReadDataConsumed());
3860}
3861
rch30943ee2017-06-12 21:28:443862// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
3863// request is reset from, then QUIC will be marked as broken and the request
3864// retried over TCP.
3865TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
rch30943ee2017-06-12 21:28:443866 // The request will initially go out over QUIC.
3867 MockQuicData quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523868 quic::QuicStreamOffset header_stream_offset = 0;
Ryan Hamilton0239aac2018-05-19 00:03:133869 spdy::SpdyPriority priority =
rch30943ee2017-06-12 21:28:443870 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
3871
3872 std::string request_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523873 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
3874 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:433875 quic_data.AddWrite(SYNCHRONOUS,
3876 client_maker_.MakeRequestHeadersPacketAndSaveData(
Fan Yang32c5a112018-12-10 20:06:333877 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
3878 true, priority, GetRequestHeaders("GET", "https", "/"),
3879 0, nullptr, &header_stream_offset, &request_data));
rch30943ee2017-06-12 21:28:443880
3881 std::string settings_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523882 // quic::QuicStreamOffset settings_offset = header_stream_offset;
3883 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
Zhongyi Shi32f2fd02018-04-16 18:23:433884 quic_data.AddWrite(SYNCHRONOUS,
3885 client_maker_.MakeInitialSettingsPacketAndSaveData(
3886 2, &header_stream_offset, &settings_data));
rch30943ee2017-06-12 21:28:443887
Fan Yang32c5a112018-12-10 20:06:333888 quic_data.AddRead(ASYNC,
3889 ConstructServerRstPacket(
3890 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
3891 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:443892
3893 quic_data.AddRead(ASYNC, OK);
3894 quic_data.AddSocketDataToFactory(&socket_factory_);
3895
3896 // After that fails, it will be resent via TCP.
3897 MockWrite http_writes[] = {
3898 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
3899 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
3900 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
3901
3902 MockRead http_reads[] = {
3903 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
3904 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
3905 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:013906 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:443907 socket_factory_.AddSocketDataProvider(&http_data);
3908 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
3909
3910 // In order for a new QUIC session to be established via alternate-protocol
3911 // without racing an HTTP connection, we need the host resolution to happen
3912 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
3913 // connection to the the server, in this test we require confirmation
3914 // before encrypting so the HTTP job will still start.
3915 host_resolver_.set_synchronous_mode(true);
3916 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
3917 "");
3918 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
3919 AddressList address;
3920 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:583921 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
3922 CompletionOnceCallback(), &request,
3923 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:413924 EXPECT_THAT(rv, IsOk());
rch30943ee2017-06-12 21:28:443925
3926 CreateSession();
3927
Ryan Hamilton9835e662018-08-02 05:36:273928 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rch30943ee2017-06-12 21:28:443929
3930 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
3931 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:413932 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
rch30943ee2017-06-12 21:28:443933 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
3934
3935 // Pump the message loop to get the request started.
3936 base::RunLoop().RunUntilIdle();
3937 // Explicitly confirm the handshake.
3938 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:523939 quic::QuicSession::HANDSHAKE_CONFIRMED);
rch30943ee2017-06-12 21:28:443940
3941 // Run the QUIC session to completion.
3942 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3943
3944 ExpectQuicAlternateProtocolMapping();
3945
3946 // Let the transaction proceed which will result in QUIC being marked
3947 // as broken and the request falling back to TCP.
3948 EXPECT_THAT(callback.WaitForResult(), IsOk());
3949
3950 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
3951 ASSERT_FALSE(http_data.AllReadDataConsumed());
3952
3953 // Read the response body over TCP.
3954 CheckResponseData(&trans, "hello world");
3955 ExpectBrokenAlternateProtocolMapping();
3956 ASSERT_TRUE(http_data.AllWriteDataConsumed());
3957 ASSERT_TRUE(http_data.AllReadDataConsumed());
3958}
3959
Ryan Hamilton6c2a2a82017-12-15 02:06:283960// Verify that when an origin has two alt-svc advertisements, one local and one
3961// remote, that when the local is broken the request will go over QUIC via
3962// the remote Alt-Svc.
3963// This is a regression test for crbug/825646.
3964TEST_P(QuicNetworkTransactionTest, RemoteAltSvcWorkingWhileLocalAltSvcBroken) {
3965 session_params_.quic_allow_remote_alt_svc = true;
3966
3967 GURL origin1 = request_.url; // mail.example.org
3968 GURL origin2("https://www.example.org/");
3969 ASSERT_NE(origin1.host(), origin2.host());
3970
3971 scoped_refptr<X509Certificate> cert(
3972 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:243973 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
3974 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
Ryan Hamilton6c2a2a82017-12-15 02:06:283975
3976 ProofVerifyDetailsChromium verify_details;
3977 verify_details.cert_verify_result.verified_cert = cert;
3978 verify_details.cert_verify_result.is_issued_by_known_root = true;
3979 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3980
3981 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:523982 quic::QuicStreamOffset request_header_offset(0);
3983 quic::QuicStreamOffset response_header_offset(0);
Ryan Hamilton6c2a2a82017-12-15 02:06:283984 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433985 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
3986 mock_quic_data.AddWrite(
3987 SYNCHRONOUS,
3988 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333989 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:433990 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
3991 mock_quic_data.AddRead(
3992 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:333993 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:433994 GetResponseHeaders("200 OK"), &response_header_offset));
3995 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:333996 ASYNC, ConstructServerDataPacket(
3997 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
3998 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:433999 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton6c2a2a82017-12-15 02:06:284000 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4001 mock_quic_data.AddRead(ASYNC, 0); // EOF
4002
4003 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4004 MockQuicData mock_quic_data2;
4005 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
4006 AddHangingNonAlternateProtocolSocketData();
4007
4008 CreateSession();
4009
4010 // Set up alternative service for |origin1|.
4011 AlternativeService local_alternative(kProtoQUIC, "mail.example.org", 443);
4012 AlternativeService remote_alternative(kProtoQUIC, "www.example.org", 443);
4013 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
4014 AlternativeServiceInfoVector alternative_services;
4015 alternative_services.push_back(
4016 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4017 local_alternative, expiration,
4018 session_->params().quic_supported_versions));
4019 alternative_services.push_back(
4020 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4021 remote_alternative, expiration,
4022 session_->params().quic_supported_versions));
4023 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin1),
4024 alternative_services);
4025
4026 http_server_properties_.MarkAlternativeServiceBroken(local_alternative);
4027
4028 SendRequestAndExpectQuicResponse("hello!");
4029}
4030
rch30943ee2017-06-12 21:28:444031// Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
4032// request is reset from, then QUIC will be marked as broken and the request
4033// retried over TCP. Then, subsequent requests will go over a new QUIC
4034// connection instead of going back to the broken QUIC connection.
4035// This is a regression tests for crbug/731303.
4036TEST_P(QuicNetworkTransactionTest,
4037 ResetPooledAfterHandshakeConfirmedThenBroken) {
Ryan Hamiltonc84473f2017-11-23 03:18:344038 session_params_.quic_allow_remote_alt_svc = true;
rch30943ee2017-06-12 21:28:444039
4040 GURL origin1 = request_.url;
4041 GURL origin2("https://www.example.org/");
4042 ASSERT_NE(origin1.host(), origin2.host());
4043
4044 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524045 quic::QuicStreamOffset request_header_offset(0);
4046 quic::QuicStreamOffset response_header_offset(0);
rch30943ee2017-06-12 21:28:444047
4048 scoped_refptr<X509Certificate> cert(
4049 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:244050 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org"));
4051 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org"));
rch30943ee2017-06-12 21:28:444052
4053 ProofVerifyDetailsChromium verify_details;
4054 verify_details.cert_verify_result.verified_cert = cert;
4055 verify_details.cert_verify_result.is_issued_by_known_root = true;
4056 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4057
4058 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434059 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
rch30943ee2017-06-12 21:28:444060 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434061 mock_quic_data.AddWrite(
4062 SYNCHRONOUS,
4063 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334064 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434065 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4066 mock_quic_data.AddRead(
4067 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334068 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434069 GetResponseHeaders("200 OK"), &response_header_offset));
4070 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334071 ASYNC, ConstructServerDataPacket(
4072 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4073 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434074 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rch30943ee2017-06-12 21:28:444075
4076 // Second request will go over the pooled QUIC connection, but will be
4077 // reset by the server.
Yixin Wang079ad542018-01-11 04:06:054078 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:334079 version_, quic::EmptyQuicConnectionId(), &clock_, origin2.host(),
4080 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054081 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:334082 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
4083 &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524084 quic::Perspective::IS_SERVER, false);
Zhongyi Shi32f2fd02018-04-16 18:23:434085 mock_quic_data.AddWrite(
4086 SYNCHRONOUS,
4087 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334088 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434089 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334090 GetNthClientInitiatedBidirectionalStreamId(0),
4091 &request_header_offset));
4092 mock_quic_data.AddRead(
4093 ASYNC, ConstructServerRstPacket(
4094 3, false, GetNthClientInitiatedBidirectionalStreamId(1),
4095 quic::QUIC_HEADERS_TOO_LARGE));
rch30943ee2017-06-12 21:28:444096 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4097 mock_quic_data.AddRead(ASYNC, 0); // EOF
4098
4099 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4100
4101 // After that fails, it will be resent via TCP.
4102 MockWrite http_writes[] = {
4103 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
4104 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
4105 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
4106
4107 MockRead http_reads[] = {
4108 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
4109 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
4110 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
Ryan Sleevib8d7ea02018-05-07 20:01:014111 SequencedSocketData http_data(http_reads, http_writes);
rch30943ee2017-06-12 21:28:444112 socket_factory_.AddSocketDataProvider(&http_data);
4113 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4114
Ryan Hamilton6c2a2a82017-12-15 02:06:284115 // Then the next request to the second origin will be sent over TCP.
4116 socket_factory_.AddSocketDataProvider(&http_data);
4117 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
rch30943ee2017-06-12 21:28:444118
4119 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564120 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4121 QuicStreamFactoryPeer::SetAlarmFactory(
4122 session_->quic_stream_factory(),
4123 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4124 &clock_));
rch30943ee2017-06-12 21:28:444125
4126 // Set up alternative service for |origin1|.
4127 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
Ryan Hamiltoncec1cee82017-12-15 00:00:244128 AlternativeService alternative1(kProtoQUIC, origin1.host(), 443);
zhongyie537a002017-06-27 16:48:214129 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244130 url::SchemeHostPort(origin1), alternative1, expiration,
zhongyi86838d52017-06-30 01:19:444131 supported_versions_);
rch30943ee2017-06-12 21:28:444132
4133 // Set up alternative service for |origin2|.
Ryan Hamiltoncec1cee82017-12-15 00:00:244134 AlternativeService alternative2(kProtoQUIC, origin2.host(), 443);
zhongyie537a002017-06-27 16:48:214135 http_server_properties_.SetQuicAlternativeService(
Ryan Hamiltoncec1cee82017-12-15 00:00:244136 url::SchemeHostPort(origin2), alternative2, expiration,
zhongyi86838d52017-06-30 01:19:444137 supported_versions_);
Ryan Hamiltonc84473f2017-11-23 03:18:344138
rch30943ee2017-06-12 21:28:444139 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524140 // with quic::QuicServerId.host() == origin1.host().
rch30943ee2017-06-12 21:28:444141 SendRequestAndExpectQuicResponse("hello!");
4142
4143 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524144 // because certificate matches, even though quic::QuicServerId is different.
rch30943ee2017-06-12 21:28:444145 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
4146 request_.url = origin2;
4147 SendRequestAndExpectHttpResponse("hello world");
Ryan Hamilton6c2a2a82017-12-15 02:06:284148 EXPECT_FALSE(http_server_properties_.IsAlternativeServiceBroken(alternative1))
Ryan Hamiltoncec1cee82017-12-15 00:00:244149 << alternative1.ToString();
Ryan Hamilton6c2a2a82017-12-15 02:06:284150 EXPECT_TRUE(http_server_properties_.IsAlternativeServiceBroken(alternative2))
Ryan Hamiltoncec1cee82017-12-15 00:00:244151 << alternative2.ToString();
rch30943ee2017-06-12 21:28:444152
4153 // The third request should use a new QUIC connection, not the broken
4154 // QUIC connection.
Ryan Hamilton6c2a2a82017-12-15 02:06:284155 SendRequestAndExpectHttpResponse("hello world");
rch30943ee2017-06-12 21:28:444156}
4157
bnc8be55ebb2015-10-30 14:12:074158TEST_P(QuicNetworkTransactionTest,
4159 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
4160 std::string altsvc_header = base::StringPrintf(
bnc90be5dd782016-11-09 16:28:444161 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
bnc8be55ebb2015-10-30 14:12:074162 MockRead http_reads[] = {
4163 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
4164 MockRead("hello world"),
4165 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4166 MockRead(ASYNC, OK)};
4167
Ryan Sleevib8d7ea02018-05-07 20:01:014168 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bnc8be55ebb2015-10-30 14:12:074169 socket_factory_.AddSocketDataProvider(&http_data);
4170 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4171 socket_factory_.AddSocketDataProvider(&http_data);
4172 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4173
rch3f4b8452016-02-23 16:59:324174 CreateSession();
bnc8be55ebb2015-10-30 14:12:074175
4176 SendRequestAndExpectHttpResponse("hello world");
4177 SendRequestAndExpectHttpResponse("hello world");
4178}
4179
Xida Chen9bfe0b62018-04-24 19:52:214180// When multiple alternative services are advertised, HttpStreamFactory should
4181// select the alternative service which uses existing QUIC session if available.
4182// If no existing QUIC session can be used, use the first alternative service
4183// from the list.
zhongyi32569c62016-01-08 02:54:304184TEST_P(QuicNetworkTransactionTest, UseExistingAlternativeServiceForQuic) {
Ryan Hamiltonc84473f2017-11-23 03:18:344185 session_params_.quic_allow_remote_alt_svc = true;
bncc958faa2015-07-31 18:14:524186 MockRead http_reads[] = {
4187 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294188 MockRead("Alt-Svc: quic=\"foo.example.org:443\", quic=\":444\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:524189 MockRead("hello world"),
4190 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4191 MockRead(ASYNC, OK)};
4192
Ryan Sleevib8d7ea02018-05-07 20:01:014193 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524194 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084195 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564196 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524197
Ryan Hamilton8d9ee76e2018-05-29 23:52:524198 quic::QuicStreamOffset request_header_offset = 0;
4199 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304200 // First QUIC request data.
rch9ae5b3b2016-02-11 00:36:294201 // Open a session to foo.example.org:443 using the first entry of the
zhongyi32569c62016-01-08 02:54:304202 // alternative service list.
bncc958faa2015-07-31 18:14:524203 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364204 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434205 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4206 mock_quic_data.AddWrite(
4207 SYNCHRONOUS,
4208 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334209 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434210 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
zhongyi32569c62016-01-08 02:54:304211
4212 std::string alt_svc_list =
rch9ae5b3b2016-02-11 00:36:294213 "quic=\"mail.example.org:444\", quic=\"foo.example.org:443\", "
4214 "quic=\"bar.example.org:445\"";
Zhongyi Shi32f2fd02018-04-16 18:23:434215 mock_quic_data.AddRead(
4216 ASYNC,
4217 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334218 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434219 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
4220 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334221 ASYNC, ConstructServerDataPacket(
4222 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4223 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434224 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304225
4226 // Second QUIC request data.
4227 // Connection pooling, using existing session, no need to include version
4228 // as version negotiation has been completed.
alyssar2adf3ac2016-05-03 17:12:584229 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334230 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4231 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4232 true, GetRequestHeaders("GET", "https", "/"),
4233 GetNthClientInitiatedBidirectionalStreamId(0),
4234 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434235 mock_quic_data.AddRead(
4236 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334237 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434238 GetResponseHeaders("200 OK"), &response_header_offset));
4239 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334240 ASYNC, ConstructServerDataPacket(
4241 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4242 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434243 mock_quic_data.AddWrite(
4244 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bncc958faa2015-07-31 18:14:524245 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594246 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524247
4248 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4249
rtennetib8e80fb2016-05-16 00:12:094250 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324251 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564252 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4253 QuicStreamFactoryPeer::SetAlarmFactory(
4254 session_->quic_stream_factory(),
4255 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4256 &clock_));
bncc958faa2015-07-31 18:14:524257
4258 SendRequestAndExpectHttpResponse("hello world");
zhongyi32569c62016-01-08 02:54:304259
bnc359ed2a2016-04-29 20:43:454260 SendRequestAndExpectQuicResponse("hello!");
4261 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304262}
4263
tbansal6490783c2016-09-20 17:55:274264// Check that an existing QUIC connection to an alternative proxy server is
4265// used.
4266TEST_P(QuicNetworkTransactionTest, UseExistingQUICAlternativeProxy) {
4267 base::HistogramTester histogram_tester;
4268
Ryan Hamilton8d9ee76e2018-05-29 23:52:524269 quic::QuicStreamOffset request_header_offset = 0;
4270 quic::QuicStreamOffset response_header_offset = 0;
tbansal6490783c2016-09-20 17:55:274271 // First QUIC request data.
4272 // Open a session to foo.example.org:443 using the first entry of the
4273 // alternative service list.
4274 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364275 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434276 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
4277 mock_quic_data.AddWrite(
4278 SYNCHRONOUS,
4279 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334280 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434281 GetRequestHeaders("GET", "http", "/"), &request_header_offset));
tbansal6490783c2016-09-20 17:55:274282
4283 std::string alt_svc_list;
Zhongyi Shi32f2fd02018-04-16 18:23:434284 mock_quic_data.AddRead(
4285 ASYNC,
4286 ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334287 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434288 GetResponseHeaders("200 OK", alt_svc_list), &response_header_offset));
4289 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334290 ASYNC, ConstructServerDataPacket(
4291 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4292 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434293 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansal6490783c2016-09-20 17:55:274294
4295 // Second QUIC request data.
4296 // Connection pooling, using existing session, no need to include version
4297 // as version negotiation has been completed.
tbansal6490783c2016-09-20 17:55:274298 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334299 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4300 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4301 true, GetRequestHeaders("GET", "http", "/"),
4302 GetNthClientInitiatedBidirectionalStreamId(0),
4303 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434304 mock_quic_data.AddRead(
4305 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334306 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434307 GetResponseHeaders("200 OK"), &response_header_offset));
4308 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334309 ASYNC, ConstructServerDataPacket(
4310 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4311 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434312 mock_quic_data.AddWrite(
4313 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
tbansal6490783c2016-09-20 17:55:274314 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4315 mock_quic_data.AddRead(ASYNC, 0); // EOF
4316
4317 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4318
4319 AddHangingNonAlternateProtocolSocketData();
4320
4321 TestProxyDelegate test_proxy_delegate;
4322
Lily Houghton8c2f97d2018-01-22 05:06:594323 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494324 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal6490783c2016-09-20 17:55:274325
4326 test_proxy_delegate.set_alternative_proxy_server(
4327 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524328 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansal6490783c2016-09-20 17:55:274329
4330 request_.url = GURL("http://mail.example.org/");
4331
4332 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564333 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4334 QuicStreamFactoryPeer::SetAlarmFactory(
4335 session_->quic_stream_factory(),
4336 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4337 &clock_));
tbansal6490783c2016-09-20 17:55:274338
4339 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4340 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4341 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4342 1);
4343
4344 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4345 histogram_tester.ExpectTotalCount("Net.QuicAlternativeProxy.Usage", 2);
4346 histogram_tester.ExpectBucketCount("Net.QuicAlternativeProxy.Usage",
4347 0 /* ALTERNATIVE_PROXY_USAGE_NO_RACE */,
4348 1);
4349}
4350
Ryan Hamilton8d9ee76e2018-05-29 23:52:524351// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:454352// even if alternative service destination is different.
4353TEST_P(QuicNetworkTransactionTest, PoolByOrigin) {
Ryan Hamiltonc84473f2017-11-23 03:18:344354 session_params_.quic_allow_remote_alt_svc = true;
zhongyi32569c62016-01-08 02:54:304355 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524356 quic::QuicStreamOffset request_header_offset(0);
4357 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454358
rch5cb522462017-04-25 20:18:364359 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434360 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454361 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434362 mock_quic_data.AddWrite(
4363 SYNCHRONOUS,
4364 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334365 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434366 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4367 mock_quic_data.AddRead(
4368 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334369 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434370 GetResponseHeaders("200 OK"), &response_header_offset));
4371 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334372 ASYNC, ConstructServerDataPacket(
4373 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4374 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434375 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
zhongyi32569c62016-01-08 02:54:304376
bnc359ed2a2016-04-29 20:43:454377 // Second request.
alyssar2adf3ac2016-05-03 17:12:584378 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334379 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4380 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
4381 true, GetRequestHeaders("GET", "https", "/"),
4382 GetNthClientInitiatedBidirectionalStreamId(0),
4383 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434384 mock_quic_data.AddRead(
4385 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334386 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434387 GetResponseHeaders("200 OK"), &response_header_offset));
4388 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334389 ASYNC, ConstructServerDataPacket(
4390 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4391 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434392 mock_quic_data.AddWrite(
4393 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304394 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4395 mock_quic_data.AddRead(ASYNC, 0); // EOF
4396
4397 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
bnc359ed2a2016-04-29 20:43:454398
4399 AddHangingNonAlternateProtocolSocketData();
4400 AddHangingNonAlternateProtocolSocketData();
zhongyi32569c62016-01-08 02:54:304401
rch3f4b8452016-02-23 16:59:324402 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564403 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4404 QuicStreamFactoryPeer::SetAlarmFactory(
4405 session_->quic_stream_factory(),
4406 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4407 &clock_));
zhongyi32569c62016-01-08 02:54:304408
bnc359ed2a2016-04-29 20:43:454409 const char destination1[] = "first.example.com";
4410 const char destination2[] = "second.example.com";
4411
4412 // Set up alternative service entry to destination1.
4413 url::SchemeHostPort server(request_.url);
bnc3472afd2016-11-17 15:27:214414 AlternativeService alternative_service(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454415 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214416 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444417 server, alternative_service, expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:454418 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524419 // with quic::QuicServerId.host() == kDefaultServerHostName.
bnc359ed2a2016-04-29 20:43:454420 SendRequestAndExpectQuicResponse("hello!");
4421
4422 // Set up alternative service entry to a different destination.
bnc3472afd2016-11-17 15:27:214423 alternative_service = AlternativeService(kProtoQUIC, destination2, 443);
zhongyie537a002017-06-27 16:48:214424 http_server_properties_.SetQuicAlternativeService(
zhongyi86838d52017-06-30 01:19:444425 server, alternative_service, expiration, supported_versions_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524426 // Second request pools to existing connection with same quic::QuicServerId,
bnc359ed2a2016-04-29 20:43:454427 // even though alternative service destination is different.
4428 SendRequestAndExpectQuicResponse("hello!");
4429}
4430
4431// Pool to existing session with matching destination and matching certificate
4432// even if origin is different, and even if the alternative service with
4433// matching destination is not the first one on the list.
4434TEST_P(QuicNetworkTransactionTest, PoolByDestination) {
Ryan Hamiltonc84473f2017-11-23 03:18:344435 session_params_.quic_allow_remote_alt_svc = true;
bnc359ed2a2016-04-29 20:43:454436 GURL origin1 = request_.url;
4437 GURL origin2("https://www.example.org/");
4438 ASSERT_NE(origin1.host(), origin2.host());
4439
4440 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524441 quic::QuicStreamOffset request_header_offset(0);
4442 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:454443
rch5cb522462017-04-25 20:18:364444 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434445 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
bnc359ed2a2016-04-29 20:43:454446 // First request.
Zhongyi Shi32f2fd02018-04-16 18:23:434447 mock_quic_data.AddWrite(
4448 SYNCHRONOUS,
4449 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334450 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434451 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4452 mock_quic_data.AddRead(
4453 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334454 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434455 GetResponseHeaders("200 OK"), &response_header_offset));
4456 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334457 ASYNC, ConstructServerDataPacket(
4458 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4459 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434460 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bnc359ed2a2016-04-29 20:43:454461
4462 // Second request.
Yixin Wang079ad542018-01-11 04:06:054463 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:334464 version_, quic::EmptyQuicConnectionId(), &clock_, origin2.host(),
4465 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054466 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:334467 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
4468 &clock_, origin2.host(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:524469 quic::Perspective::IS_SERVER, false);
alyssar2adf3ac2016-05-03 17:12:584470 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434471 SYNCHRONOUS,
4472 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334473 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434474 GetRequestHeaders("GET", "https", "/", &client_maker2),
Fan Yang32c5a112018-12-10 20:06:334475 GetNthClientInitiatedBidirectionalStreamId(0),
4476 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434477 mock_quic_data.AddRead(
4478 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334479 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434480 GetResponseHeaders("200 OK"), &response_header_offset));
4481 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334482 ASYNC, ConstructServerDataPacket(
4483 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4484 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434485 mock_quic_data.AddWrite(
4486 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
bnc359ed2a2016-04-29 20:43:454487 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4488 mock_quic_data.AddRead(ASYNC, 0); // EOF
4489
4490 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4491
4492 AddHangingNonAlternateProtocolSocketData();
4493 AddHangingNonAlternateProtocolSocketData();
4494
4495 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564496 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4497 QuicStreamFactoryPeer::SetAlarmFactory(
4498 session_->quic_stream_factory(),
4499 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4500 &clock_));
bnc359ed2a2016-04-29 20:43:454501
4502 const char destination1[] = "first.example.com";
4503 const char destination2[] = "second.example.com";
4504
4505 // Set up alternative service for |origin1|.
bnc3472afd2016-11-17 15:27:214506 AlternativeService alternative_service1(kProtoQUIC, destination1, 443);
bnc359ed2a2016-04-29 20:43:454507 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:214508 http_server_properties_.SetQuicAlternativeService(
4509 url::SchemeHostPort(origin1), alternative_service1, expiration,
zhongyi86838d52017-06-30 01:19:444510 supported_versions_);
bnc359ed2a2016-04-29 20:43:454511
4512 // Set up multiple alternative service entries for |origin2|,
4513 // the first one with a different destination as for |origin1|,
4514 // the second one with the same. The second one should be used,
4515 // because the request can be pooled to that one.
bnc3472afd2016-11-17 15:27:214516 AlternativeService alternative_service2(kProtoQUIC, destination2, 443);
bnc359ed2a2016-04-29 20:43:454517 AlternativeServiceInfoVector alternative_services;
4518 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214519 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4520 alternative_service2, expiration,
4521 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454522 alternative_services.push_back(
zhongyie537a002017-06-27 16:48:214523 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
4524 alternative_service1, expiration,
4525 session_->params().quic_supported_versions));
bnc359ed2a2016-04-29 20:43:454526 http_server_properties_.SetAlternativeServices(url::SchemeHostPort(origin2),
4527 alternative_services);
bnc359ed2a2016-04-29 20:43:454528 // First request opens connection to |destination1|
Ryan Hamilton8d9ee76e2018-05-29 23:52:524529 // with quic::QuicServerId.host() == origin1.host().
bnc359ed2a2016-04-29 20:43:454530 SendRequestAndExpectQuicResponse("hello!");
4531
4532 // Second request pools to existing connection with same destination,
Ryan Hamilton8d9ee76e2018-05-29 23:52:524533 // because certificate matches, even though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:454534 request_.url = origin2;
alyssar2adf3ac2016-05-03 17:12:584535
bnc359ed2a2016-04-29 20:43:454536 SendRequestAndExpectQuicResponse("hello!");
zhongyi32569c62016-01-08 02:54:304537}
4538
4539// Multiple origins have listed the same alternative services. When there's a
4540// existing QUIC session opened by a request to other origin,
4541// if the cert is valid, should select this QUIC session to make the request
4542// if this is also the first existing QUIC session.
4543TEST_P(QuicNetworkTransactionTest,
4544 UseSharedExistingAlternativeServiceForQuicWithValidCert) {
Ryan Hamiltonc84473f2017-11-23 03:18:344545 session_params_.quic_allow_remote_alt_svc = true;
rch9ae5b3b2016-02-11 00:36:294546 // Default cert is valid for *.example.org
zhongyi32569c62016-01-08 02:54:304547
rch9ae5b3b2016-02-11 00:36:294548 // HTTP data for request to www.example.org.
zhongyi32569c62016-01-08 02:54:304549 MockRead http_reads[] = {
4550 MockRead("HTTP/1.1 200 OK\r\n"),
4551 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
rch9ae5b3b2016-02-11 00:36:294552 MockRead("hello world from www.example.org"),
zhongyi32569c62016-01-08 02:54:304553 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4554 MockRead(ASYNC, OK)};
4555
Ryan Sleevib8d7ea02018-05-07 20:01:014556 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304557 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084558 AddCertificate(&ssl_data_);
zhongyi32569c62016-01-08 02:54:304559 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4560
4561 // HTTP data for request to mail.example.org.
4562 MockRead http_reads2[] = {
4563 MockRead("HTTP/1.1 200 OK\r\n"),
rch9ae5b3b2016-02-11 00:36:294564 MockRead("Alt-Svc: quic=\":444\", quic=\"www.example.org:443\"\r\n\r\n"),
zhongyi32569c62016-01-08 02:54:304565 MockRead("hello world from mail.example.org"),
4566 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4567 MockRead(ASYNC, OK)};
4568
Ryan Sleevib8d7ea02018-05-07 20:01:014569 StaticSocketDataProvider http_data2(http_reads2, base::span<MockWrite>());
zhongyi32569c62016-01-08 02:54:304570 socket_factory_.AddSocketDataProvider(&http_data2);
4571 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
4572
Ryan Hamilton8d9ee76e2018-05-29 23:52:524573 quic::QuicStreamOffset request_header_offset = 0;
4574 quic::QuicStreamOffset response_header_offset = 0;
zhongyi32569c62016-01-08 02:54:304575
Yixin Wang079ad542018-01-11 04:06:054576 QuicTestPacketMaker client_maker(
Fan Yang32c5a112018-12-10 20:06:334577 version_, quic::EmptyQuicConnectionId(), &clock_, "mail.example.org",
4578 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:054579 client_headers_include_h2_stream_dependency_);
alyssar2adf3ac2016-05-03 17:12:584580 server_maker_.set_hostname("www.example.org");
4581 client_maker_.set_hostname("www.example.org");
zhongyi32569c62016-01-08 02:54:304582 MockQuicData mock_quic_data;
rch5cb522462017-04-25 20:18:364583 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434584 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &request_header_offset));
zhongyi32569c62016-01-08 02:54:304585 // First QUIC request data.
alyssar2adf3ac2016-05-03 17:12:584586 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434587 SYNCHRONOUS,
4588 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334589 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434590 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
4591
4592 mock_quic_data.AddRead(
4593 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334594 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434595 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334596 mock_quic_data.AddRead(
4597 ASYNC, ConstructServerDataPacket(
4598 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4599 0, "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434600 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
4601 // Second QUIC request data.
4602 mock_quic_data.AddWrite(
4603 SYNCHRONOUS,
4604 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334605 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434606 GetRequestHeaders("GET", "https", "/", &client_maker),
Fan Yang32c5a112018-12-10 20:06:334607 GetNthClientInitiatedBidirectionalStreamId(0),
4608 &request_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434609 mock_quic_data.AddRead(
4610 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334611 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:434612 GetResponseHeaders("200 OK"), &response_header_offset));
Fan Yang32c5a112018-12-10 20:06:334613 mock_quic_data.AddRead(
4614 ASYNC, ConstructServerDataPacket(
4615 4, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
4616 0, "hello from mail QUIC!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434617 mock_quic_data.AddWrite(
4618 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 4, 3, 1));
zhongyi32569c62016-01-08 02:54:304619 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4620 mock_quic_data.AddRead(ASYNC, 0); // EOF
4621
4622 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
zhongyi32569c62016-01-08 02:54:304623
rtennetib8e80fb2016-05-16 00:12:094624 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324625 CreateSession();
Fan Yangc9e00dc2018-10-09 14:17:564626 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
4627 QuicStreamFactoryPeer::SetAlarmFactory(
4628 session_->quic_stream_factory(),
4629 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
4630 &clock_));
zhongyi32569c62016-01-08 02:54:304631
4632 // Send two HTTP requests, responses set up alt-svc lists for the origins.
rch9ae5b3b2016-02-11 00:36:294633 request_.url = GURL("https://www.example.org/");
4634 SendRequestAndExpectHttpResponse("hello world from www.example.org");
zhongyi32569c62016-01-08 02:54:304635 request_.url = GURL("https://mail.example.org/");
4636 SendRequestAndExpectHttpResponse("hello world from mail.example.org");
4637
rch9ae5b3b2016-02-11 00:36:294638 // Open a QUIC session to mail.example.org:443 when making request
4639 // to mail.example.org.
4640 request_.url = GURL("https://www.example.org/");
bnc359ed2a2016-04-29 20:43:454641 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
zhongyi32569c62016-01-08 02:54:304642
rch9ae5b3b2016-02-11 00:36:294643 // Uses the existing QUIC session when making request to www.example.org.
zhongyi32569c62016-01-08 02:54:304644 request_.url = GURL("https://mail.example.org/");
bnc359ed2a2016-04-29 20:43:454645 SendRequestAndExpectQuicResponse("hello from mail QUIC!");
bncc958faa2015-07-31 18:14:524646}
4647
4648TEST_P(QuicNetworkTransactionTest, AlternativeServiceDifferentPort) {
bncc958faa2015-07-31 18:14:524649 MockRead http_reads[] = {
4650 MockRead("HTTP/1.1 200 OK\r\n"),
rchf114d982015-10-21 01:34:564651 MockRead(kQuicAlternativeServiceDifferentPortHeader),
bncc958faa2015-07-31 18:14:524652 MockRead("hello world"),
4653 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4654 MockRead(ASYNC, OK)};
4655
Ryan Sleevib8d7ea02018-05-07 20:01:014656 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524657 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084658 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564659 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524660
rtennetib8e80fb2016-05-16 00:12:094661 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324662 CreateSession();
bncc958faa2015-07-31 18:14:524663
4664 SendRequestAndExpectHttpResponse("hello world");
bnc359ed2a2016-04-29 20:43:454665
4666 url::SchemeHostPort http_server("https", kDefaultServerHostName, 443);
zhongyic4de03032017-05-19 04:07:344667 AlternativeServiceInfoVector alternative_service_info_vector =
4668 http_server_properties_.GetAlternativeServiceInfos(http_server);
4669 ASSERT_EQ(1u, alternative_service_info_vector.size());
4670 const AlternativeService alternative_service =
zhongyi422ce352017-06-09 23:28:544671 alternative_service_info_vector[0].alternative_service();
zhongyic4de03032017-05-19 04:07:344672 EXPECT_EQ(kProtoQUIC, alternative_service.protocol);
4673 EXPECT_EQ(kDefaultServerHostName, alternative_service.host);
4674 EXPECT_EQ(137, alternative_service.port);
bncc958faa2015-07-31 18:14:524675}
4676
4677TEST_P(QuicNetworkTransactionTest, ConfirmAlternativeService) {
bncc958faa2015-07-31 18:14:524678 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564679 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4680 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524681 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4682 MockRead(ASYNC, OK)};
4683
Ryan Sleevib8d7ea02018-05-07 20:01:014684 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524685 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084686 AddCertificate(&ssl_data_);
rchf114d982015-10-21 01:34:564687 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524688
4689 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524690 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364691 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434692 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4693 mock_quic_data.AddWrite(
4694 SYNCHRONOUS,
4695 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334696 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434697 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434698 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334699 ASYNC, ConstructServerResponseHeadersPacket(
4700 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4701 GetResponseHeaders("200 OK")));
4702 mock_quic_data.AddRead(
4703 ASYNC, ConstructServerDataPacket(
4704 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4705 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434706 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524707 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4708 mock_quic_data.AddRead(ASYNC, 0); // EOF
bncc958faa2015-07-31 18:14:524709
4710 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4711
rtennetib8e80fb2016-05-16 00:12:094712 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324713 CreateSession();
bncc958faa2015-07-31 18:14:524714
bnc3472afd2016-11-17 15:27:214715 AlternativeService alternative_service(kProtoQUIC,
bncc958faa2015-07-31 18:14:524716 HostPortPair::FromURL(request_.url));
4717 http_server_properties_.MarkAlternativeServiceRecentlyBroken(
4718 alternative_service);
4719 EXPECT_TRUE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4720 alternative_service));
4721
4722 SendRequestAndExpectHttpResponse("hello world");
4723 SendRequestAndExpectQuicResponse("hello!");
4724
mmenkee24011922015-12-17 22:12:594725 mock_quic_data.Resume();
bncc958faa2015-07-31 18:14:524726
4727 EXPECT_FALSE(http_server_properties_.WasAlternativeServiceRecentlyBroken(
4728 alternative_service));
rchac7f35e2017-03-15 20:42:304729 EXPECT_NE(nullptr,
4730 http_server_properties_.GetServerNetworkStats(
4731 url::SchemeHostPort("https", request_.url.host(), 443)));
bncc958faa2015-07-31 18:14:524732}
4733
bncc958faa2015-07-31 18:14:524734TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceForQuicForHttps) {
bncc958faa2015-07-31 18:14:524735 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564736 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
4737 MockRead("hello world"),
bncc958faa2015-07-31 18:14:524738 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
4739 MockRead(ASYNC, OK)};
4740
Ryan Sleevib8d7ea02018-05-07 20:01:014741 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:524742 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:564743 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
bncc958faa2015-07-31 18:14:524744
4745 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524746 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364747 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434748 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4749 mock_quic_data.AddWrite(
4750 SYNCHRONOUS,
4751 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334752 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434753 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434754 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334755 ASYNC, ConstructServerResponseHeadersPacket(
4756 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4757 GetResponseHeaders("200 OK")));
4758 mock_quic_data.AddRead(
4759 ASYNC, ConstructServerDataPacket(
4760 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4761 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434762 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
bncc958faa2015-07-31 18:14:524763 mock_quic_data.AddRead(SYNCHRONOUS, 0); // EOF
4764
4765 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4766
4767 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324768 CreateSession();
bncc958faa2015-07-31 18:14:524769
4770 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
4771 SendRequestAndExpectHttpResponse("hello world");
4772}
4773
tbansalc3308d72016-08-27 10:25:044774// Tests that the connection to an HTTPS proxy is raced with an available
4775// alternative proxy server.
4776TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
tbansal6490783c2016-09-20 17:55:274777 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:594778 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:494779 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:044780
4781 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524782 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:364783 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:434784 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4785 mock_quic_data.AddWrite(
4786 SYNCHRONOUS,
4787 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334788 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434789 GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434790 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334791 ASYNC, ConstructServerResponseHeadersPacket(
4792 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4793 GetResponseHeaders("200 OK")));
4794 mock_quic_data.AddRead(
4795 ASYNC, ConstructServerDataPacket(
4796 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4797 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434798 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
tbansalc3308d72016-08-27 10:25:044799 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
4800 mock_quic_data.AddRead(ASYNC, 0); // EOF
4801
4802 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
4803
4804 // There is no need to set up main job, because no attempt will be made to
4805 // speak to the proxy over TCP.
4806 request_.url = GURL("http://mail.example.org/");
tbansalc3308d72016-08-27 10:25:044807 TestProxyDelegate test_proxy_delegate;
4808 const HostPortPair host_port_pair("mail.example.org", 443);
4809
4810 test_proxy_delegate.set_alternative_proxy_server(
4811 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:524812 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:044813 CreateSession();
4814 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4815
4816 // The main job needs to hang in order to guarantee that the alternative
4817 // proxy server job will "win".
4818 AddHangingNonAlternateProtocolSocketData();
4819
4820 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 443);
4821
4822 // Verify that the alternative proxy server is not marked as broken.
4823 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
4824
4825 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:594826 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:274827
4828 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
4829 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
4830 1);
tbansalc3308d72016-08-27 10:25:044831}
4832
bnc1c196c6e2016-05-28 13:51:484833TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
[email protected]dda75ab2013-06-22 22:43:304834 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:274835 MockCryptoClientStream::COLD_START);
[email protected]dda75ab2013-06-22 22:43:304836
4837 MockWrite http_writes[] = {
rchf114d982015-10-21 01:34:564838 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
rch9ae5b3b2016-02-11 00:36:294839 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564840 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
[email protected]dda75ab2013-06-22 22:43:304841
4842 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564843 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484844 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564845 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]dda75ab2013-06-22 22:43:304846
Ryan Sleevib8d7ea02018-05-07 20:01:014847 SequencedSocketData http_data(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504848 socket_factory_.AddSocketDataProvider(&http_data);
Bence Béky230ac612017-08-30 19:17:084849 AddCertificate(&ssl_data_);
bnc912a04b2016-04-20 14:19:504850 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304851
4852 // The QUIC transaction will not be allowed to complete.
mmenke651bae7f2015-12-18 21:26:454853 MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 1)};
[email protected]dda75ab2013-06-22 22:43:304854 MockRead quic_reads[] = {
mmenke651bae7f2015-12-18 21:26:454855 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0),
[email protected]dda75ab2013-06-22 22:43:304856 };
Ryan Sleevib8d7ea02018-05-07 20:01:014857 SequencedSocketData quic_data(quic_reads, quic_writes);
bnc912a04b2016-04-20 14:19:504858 socket_factory_.AddSocketDataProvider(&quic_data);
[email protected]dda75ab2013-06-22 22:43:304859
4860 // The HTTP transaction will complete.
Ryan Sleevib8d7ea02018-05-07 20:01:014861 SequencedSocketData http_data2(http_reads, http_writes);
bnc912a04b2016-04-20 14:19:504862 socket_factory_.AddSocketDataProvider(&http_data2);
4863 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]dda75ab2013-06-22 22:43:304864
bnc912a04b2016-04-20 14:19:504865 CreateSession();
[email protected]dda75ab2013-06-22 22:43:304866
4867 // Run the first request.
[email protected]dda75ab2013-06-22 22:43:304868 SendRequestAndExpectHttpResponse("hello world");
rch37de576c2015-05-17 20:28:174869 ASSERT_TRUE(http_data.AllReadDataConsumed());
4870 ASSERT_TRUE(http_data.AllWriteDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304871
4872 // Now run the second request in which the QUIC socket hangs,
4873 // and verify the the transaction continues over HTTP.
[email protected]dda75ab2013-06-22 22:43:304874 SendRequestAndExpectHttpResponse("hello world");
mmenke651bae7f2015-12-18 21:26:454875 base::RunLoop().RunUntilIdle();
[email protected]dda75ab2013-06-22 22:43:304876
rch37de576c2015-05-17 20:28:174877 ASSERT_TRUE(http_data2.AllReadDataConsumed());
4878 ASSERT_TRUE(http_data2.AllWriteDataConsumed());
mmenke651bae7f2015-12-18 21:26:454879 ASSERT_TRUE(quic_data.AllReadDataConsumed());
[email protected]dda75ab2013-06-22 22:43:304880}
4881
[email protected]1e960032013-12-20 19:00:204882TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
[email protected]1e960032013-12-20 19:00:204883 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524884 quic::QuicStreamOffset header_stream_offset = 0;
4885 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4886 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:434887 mock_quic_data.AddWrite(
4888 SYNCHRONOUS,
4889 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:334890 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:434891 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:434892 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334893 ASYNC, ConstructServerResponseHeadersPacket(
4894 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4895 GetResponseHeaders("200 OK")));
4896 mock_quic_data.AddRead(
4897 ASYNC, ConstructServerDataPacket(
4898 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4899 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434900 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504901 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594902 mock_quic_data.AddRead(ASYNC, 0); // EOF
[email protected]8ba81212013-05-03 13:11:484903
rcha5399e02015-04-21 19:32:044904 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]8ba81212013-05-03 13:11:484905
rtennetib8e80fb2016-05-16 00:12:094906 // The non-alternate protocol job needs to hang in order to guarantee that
4907 // the alternate-protocol job will "win".
4908 AddHangingNonAlternateProtocolSocketData();
4909
rch3f4b8452016-02-23 16:59:324910 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274911 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]aa9b14d2013-05-10 23:45:194912 SendRequestAndExpectQuicResponse("hello!");
rchac7f35e2017-03-15 20:42:304913
4914 EXPECT_EQ(nullptr,
4915 http_server_properties_.GetServerNetworkStats(
4916 url::SchemeHostPort("https", request_.url.host(), 443)));
[email protected]8ba81212013-05-03 13:11:484917}
4918
[email protected]1e960032013-12-20 19:00:204919TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
[email protected]1e960032013-12-20 19:00:204920 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:524921 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
4922 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Fan Yang32c5a112018-12-10 20:06:334923 mock_quic_data.AddWrite(
4924 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
4925 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
4926 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:434927 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:334928 ASYNC, ConstructServerResponseHeadersPacket(
4929 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
4930 GetResponseHeaders("200 OK")));
4931 mock_quic_data.AddRead(
4932 ASYNC, ConstructServerDataPacket(
4933 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
4934 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:434935 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
rchb27683c2015-07-29 23:53:504936 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mmenkee24011922015-12-17 22:12:594937 mock_quic_data.AddRead(ASYNC, 0); // EOF
rcha5399e02015-04-21 19:32:044938 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]3a120a6b2013-06-25 01:08:274939
4940 // In order for a new QUIC session to be established via alternate-protocol
4941 // without racing an HTTP connection, we need the host resolution to happen
4942 // synchronously.
4943 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294944 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564945 "");
rch9ae5b3b2016-02-11 00:36:294946 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]3a120a6b2013-06-25 01:08:274947 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104948 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584949 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4950 CompletionOnceCallback(), &request,
4951 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414952 EXPECT_THAT(rv, IsOk());
[email protected]3a120a6b2013-06-25 01:08:274953
rtennetib8e80fb2016-05-16 00:12:094954 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:324955 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274956 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]3a120a6b2013-06-25 01:08:274957 SendRequestAndExpectQuicResponse("hello!");
4958}
4959
[email protected]0fc924b2014-03-31 04:34:154960TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
Ramin Halavatica8d5252018-03-12 05:33:494961 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
4962 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0fc924b2014-03-31 04:34:154963
4964 // Since we are using a proxy, the QUIC job will not succeed.
4965 MockWrite http_writes[] = {
rch9ae5b3b2016-02-11 00:36:294966 MockWrite(SYNCHRONOUS, 0, "GET http://mail.example.org/ HTTP/1.1\r\n"),
4967 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
rchf114d982015-10-21 01:34:564968 MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")};
[email protected]0fc924b2014-03-31 04:34:154969
4970 MockRead http_reads[] = {
rchf114d982015-10-21 01:34:564971 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:484972 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:564973 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
[email protected]0fc924b2014-03-31 04:34:154974
Ryan Sleevib8d7ea02018-05-07 20:01:014975 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]0fc924b2014-03-31 04:34:154976 socket_factory_.AddSocketDataProvider(&http_data);
4977
4978 // In order for a new QUIC session to be established via alternate-protocol
4979 // without racing an HTTP connection, we need the host resolution to happen
4980 // synchronously.
4981 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:294982 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:564983 "");
rch9ae5b3b2016-02-11 00:36:294984 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]0fc924b2014-03-31 04:34:154985 AddressList address;
maksim.sisov31452af2016-07-27 06:38:104986 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:584987 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
4988 CompletionOnceCallback(), &request,
4989 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:414990 EXPECT_THAT(rv, IsOk());
[email protected]0fc924b2014-03-31 04:34:154991
rch9ae5b3b2016-02-11 00:36:294992 request_.url = GURL("http://mail.example.org/");
rch3f4b8452016-02-23 16:59:324993 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:274994 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]0fc924b2014-03-31 04:34:154995 SendRequestAndExpectHttpResponse("hello world");
4996}
4997
[email protected]1e960032013-12-20 19:00:204998TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
[email protected]1e960032013-12-20 19:00:204999 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525000 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365001 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435002 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5003 mock_quic_data.AddWrite(
5004 SYNCHRONOUS,
5005 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335006 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435007 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435008 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335009 ASYNC, ConstructServerResponseHeadersPacket(
5010 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5011 GetResponseHeaders("200 OK")));
5012 mock_quic_data.AddRead(
5013 ASYNC, ConstructServerDataPacket(
5014 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5015 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435016 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
mmenkee24011922015-12-17 22:12:595017 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
rcha5399e02015-04-21 19:32:045018 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]11c05872013-08-20 02:04:125019
rtennetib8e80fb2016-05-16 00:12:095020 // The non-alternate protocol job needs to hang in order to guarantee that
5021 // the alternate-protocol job will "win".
5022 AddHangingNonAlternateProtocolSocketData();
5023
[email protected]11c05872013-08-20 02:04:125024 // In order for a new QUIC session to be established via alternate-protocol
5025 // without racing an HTTP connection, we need the host resolution to happen
5026 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5027 // connection to the the server, in this test we require confirmation
5028 // before encrypting so the HTTP job will still start.
5029 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295030 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565031 "");
rch9ae5b3b2016-02-11 00:36:295032 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]11c05872013-08-20 02:04:125033 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105034 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585035 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5036 CompletionOnceCallback(), &request,
5037 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415038 EXPECT_THAT(rv, IsOk());
[email protected]11c05872013-08-20 02:04:125039
rch3f4b8452016-02-23 16:59:325040 CreateSession();
[email protected]11c05872013-08-20 02:04:125041 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275042 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]11c05872013-08-20 02:04:125043
bnc691fda62016-08-12 00:43:165044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]11c05872013-08-20 02:04:125045 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415046 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015047 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11c05872013-08-20 02:04:125048
5049 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525050 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015051 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchb27683c2015-07-29 23:53:505052
bnc691fda62016-08-12 00:43:165053 CheckWasQuicResponse(&trans);
5054 CheckResponseData(&trans, "hello!");
[email protected]11c05872013-08-20 02:04:125055}
5056
Steven Valdez58097ec32018-07-16 18:29:045057TEST_P(QuicNetworkTransactionTest, ZeroRTTWithTooEarlyResponse) {
5058 MockQuicData mock_quic_data;
5059 quic::QuicStreamOffset client_header_stream_offset = 0;
5060 quic::QuicStreamOffset server_header_stream_offset = 0;
5061 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5062 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045063 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335064 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5065 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5066 true, GetRequestHeaders("GET", "https", "/"),
5067 &client_header_stream_offset));
5068 mock_quic_data.AddRead(
5069 ASYNC,
5070 ConstructServerResponseHeadersPacket(
5071 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5072 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5073 mock_quic_data.AddWrite(SYNCHRONOUS,
5074 ConstructClientAckAndRstPacket(
5075 2, GetNthClientInitiatedBidirectionalStreamId(0),
5076 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045077
5078 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5079
5080 spdy::SpdySettingsIR settings_frame;
5081 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5082 quic::kDefaultMaxUncompressedHeaderSize);
5083 spdy::SpdySerializedFrame spdy_frame(
5084 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5085 mock_quic_data.AddWrite(
5086 SYNCHRONOUS,
5087 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385088 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5089 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045090 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5091 client_header_stream_offset += spdy_frame.size();
5092
5093 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335094 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5095 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5096 true, GetRequestHeaders("GET", "https", "/"),
5097 GetNthClientInitiatedBidirectionalStreamId(0),
5098 &client_header_stream_offset));
Steven Valdez58097ec32018-07-16 18:29:045099 mock_quic_data.AddRead(
5100 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335101 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Steven Valdez58097ec32018-07-16 18:29:045102 GetResponseHeaders("200 OK"), &server_header_stream_offset));
5103 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335104 ASYNC, ConstructServerDataPacket(
5105 3, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
5106 0, "hello!"));
Steven Valdez58097ec32018-07-16 18:29:045107 mock_quic_data.AddWrite(
5108 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(5, 3, 1, 1));
5109 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5110 mock_quic_data.AddRead(ASYNC, 0); // EOF
5111
5112 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5113
5114 // In order for a new QUIC session to be established via alternate-protocol
5115 // without racing an HTTP connection, we need the host resolution to happen
5116 // synchronously.
5117 host_resolver_.set_synchronous_mode(true);
5118 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5119 "");
5120 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5121 AddressList address;
5122 std::unique_ptr<HostResolver::Request> request;
5123 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5124 CompletionOnceCallback(), &request, net_log_.bound());
5125
5126 AddHangingNonAlternateProtocolSocketData();
5127 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275128 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565129 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5130 QuicStreamFactoryPeer::SetAlarmFactory(
5131 session_->quic_stream_factory(),
5132 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5133 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045134
5135 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5136 TestCompletionCallback callback;
5137 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5139
5140 // Confirm the handshake after the 425 Too Early.
5141 base::RunLoop().RunUntilIdle();
5142
5143 // The handshake hasn't been confirmed yet, so the retry should not have
5144 // succeeded.
5145 EXPECT_FALSE(callback.have_result());
5146
5147 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5148 quic::QuicSession::HANDSHAKE_CONFIRMED);
5149
5150 EXPECT_THAT(callback.WaitForResult(), IsOk());
5151 CheckWasQuicResponse(&trans);
5152 CheckResponseData(&trans, "hello!");
5153}
5154
5155TEST_P(QuicNetworkTransactionTest, ZeroRTTWithMultipleTooEarlyResponse) {
5156 MockQuicData mock_quic_data;
5157 quic::QuicStreamOffset client_header_stream_offset = 0;
5158 quic::QuicStreamOffset server_header_stream_offset = 0;
5159 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5160 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Steven Valdez58097ec32018-07-16 18:29:045161 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335162 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5163 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5164 true, GetRequestHeaders("GET", "https", "/"),
5165 &client_header_stream_offset));
5166 mock_quic_data.AddRead(
5167 ASYNC,
5168 ConstructServerResponseHeadersPacket(
5169 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5170 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5171 mock_quic_data.AddWrite(SYNCHRONOUS,
5172 ConstructClientAckAndRstPacket(
5173 2, GetNthClientInitiatedBidirectionalStreamId(0),
5174 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045175
5176 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5177
5178 spdy::SpdySettingsIR settings_frame;
5179 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
5180 quic::kDefaultMaxUncompressedHeaderSize);
5181 spdy::SpdySerializedFrame spdy_frame(
5182 client_maker_.spdy_request_framer()->SerializeFrame(settings_frame));
5183 mock_quic_data.AddWrite(
5184 SYNCHRONOUS,
5185 client_maker_.MakeDataPacket(
Fan Yang7c68f632018-11-06 03:05:385186 3, quic::QuicUtils::GetHeadersStreamId(version_), false, false,
5187 client_header_stream_offset,
Steven Valdez58097ec32018-07-16 18:29:045188 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
5189 client_header_stream_offset += spdy_frame.size();
5190
5191 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335192 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5193 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
5194 true, GetRequestHeaders("GET", "https", "/"),
5195 GetNthClientInitiatedBidirectionalStreamId(0),
5196 &client_header_stream_offset));
5197 mock_quic_data.AddRead(
5198 ASYNC,
5199 ConstructServerResponseHeadersPacket(
5200 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
5201 GetResponseHeaders("425 TOO_EARLY"), &server_header_stream_offset));
5202 mock_quic_data.AddWrite(SYNCHRONOUS,
5203 ConstructClientAckAndRstPacket(
5204 5, GetNthClientInitiatedBidirectionalStreamId(1),
5205 quic::QUIC_STREAM_CANCELLED, 2, 1, 1));
Steven Valdez58097ec32018-07-16 18:29:045206 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5207 mock_quic_data.AddRead(ASYNC, 0); // EOF
5208
5209 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5210
5211 // In order for a new QUIC session to be established via alternate-protocol
5212 // without racing an HTTP connection, we need the host resolution to happen
5213 // synchronously.
5214 host_resolver_.set_synchronous_mode(true);
5215 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5216 "");
5217 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5218 AddressList address;
5219 std::unique_ptr<HostResolver::Request> request;
5220 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5221 CompletionOnceCallback(), &request, net_log_.bound());
5222
5223 AddHangingNonAlternateProtocolSocketData();
5224 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275225 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Fan Yangc9e00dc2018-10-09 14:17:565226 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
5227 QuicStreamFactoryPeer::SetAlarmFactory(
5228 session_->quic_stream_factory(),
5229 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
5230 &clock_));
Steven Valdez58097ec32018-07-16 18:29:045231
5232 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5233 TestCompletionCallback callback;
5234 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5235 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5236
5237 // Confirm the handshake after the 425 Too Early.
5238 base::RunLoop().RunUntilIdle();
5239
5240 // The handshake hasn't been confirmed yet, so the retry should not have
5241 // succeeded.
5242 EXPECT_FALSE(callback.have_result());
5243
5244 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5245 quic::QuicSession::HANDSHAKE_CONFIRMED);
5246
5247 EXPECT_THAT(callback.WaitForResult(), IsOk());
5248 const HttpResponseInfo* response = trans.GetResponseInfo();
5249 ASSERT_TRUE(response != nullptr);
5250 ASSERT_TRUE(response->headers.get() != nullptr);
5251 EXPECT_EQ("HTTP/1.1 425 TOO_EARLY", response->headers->GetStatusLine());
5252 EXPECT_TRUE(response->was_fetched_via_spdy);
5253 EXPECT_TRUE(response->was_alpn_negotiated);
5254 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5255 response->connection_info);
5256}
5257
zhongyica364fbb2015-12-12 03:39:125258TEST_P(QuicNetworkTransactionTest,
5259 LogGranularQuicErrorCodeOnQuicProtocolErrorLocal) {
Ryan Hamiltonb3827e882018-03-27 03:07:485260 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125261 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525262 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365263 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435264 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5265 mock_quic_data.AddWrite(
5266 SYNCHRONOUS,
5267 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335268 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435269 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyica364fbb2015-12-12 03:39:125270 // Read a close connection packet with
Ryan Hamilton8d9ee76e2018-05-29 23:52:525271 // quic::QuicErrorCode: quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED from the peer.
Zhongyi Shi32f2fd02018-04-16 18:23:435272 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(1));
zhongyica364fbb2015-12-12 03:39:125273 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5274
5275 // The non-alternate protocol job needs to hang in order to guarantee that
5276 // the alternate-protocol job will "win".
5277 AddHangingNonAlternateProtocolSocketData();
5278
5279 // In order for a new QUIC session to be established via alternate-protocol
5280 // without racing an HTTP connection, we need the host resolution to happen
5281 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5282 // connection to the the server, in this test we require confirmation
5283 // before encrypting so the HTTP job will still start.
5284 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295285 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125286 "");
rch9ae5b3b2016-02-11 00:36:295287 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125288 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105289 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585290 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5291 CompletionOnceCallback(), &request,
5292 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415293 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125294
rch3f4b8452016-02-23 16:59:325295 CreateSession();
zhongyica364fbb2015-12-12 03:39:125296 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275297 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125298
bnc691fda62016-08-12 00:43:165299 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125300 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415301 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015302 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125303
5304 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525305 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015306 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125307
5308 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525309 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125310
bnc691fda62016-08-12 00:43:165311 trans.PopulateNetErrorDetails(&details);
zhongyica364fbb2015-12-12 03:39:125312 // Verify the error code logged is what sent by the peer.
Ryan Hamilton8d9ee76e2018-05-29 23:52:525313 EXPECT_EQ(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
5314 details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125315}
5316
5317TEST_P(QuicNetworkTransactionTest,
5318 LogGranularQuicErrorCodeOnQuicProtocolErrorRemote) {
Ryan Hamiltonb3827e882018-03-27 03:07:485319 session_params_.retry_without_alt_svc_on_quic_errors = false;
zhongyica364fbb2015-12-12 03:39:125320 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525321 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365322 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435323 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5324 mock_quic_data.AddWrite(
5325 SYNCHRONOUS,
5326 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335327 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435328 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
zhongyif28b4a32016-04-25 21:35:215329 // Peer sending data from an non-existing stream causes this end to raise
5330 // error and close connection.
Fan Yang32c5a112018-12-10 20:06:335331 mock_quic_data.AddRead(
5332 ASYNC, ConstructServerRstPacket(
5333 1, false, GetNthClientInitiatedBidirectionalStreamId(47),
5334 quic::QUIC_STREAM_LAST_ERROR));
zhongyif28b4a32016-04-25 21:35:215335 std::string quic_error_details = "Data for nonexistent stream";
Ryan Hamilton8d9ee76e2018-05-29 23:52:525336 mock_quic_data.AddWrite(
5337 SYNCHRONOUS, ConstructClientAckAndConnectionClosePacket(
5338 3, quic::QuicTime::Delta::Zero(), 1, 1, 1,
5339 quic::QUIC_INVALID_STREAM_ID, quic_error_details));
zhongyica364fbb2015-12-12 03:39:125340 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5341
5342 // The non-alternate protocol job needs to hang in order to guarantee that
5343 // the alternate-protocol job will "win".
5344 AddHangingNonAlternateProtocolSocketData();
5345
5346 // In order for a new QUIC session to be established via alternate-protocol
5347 // without racing an HTTP connection, we need the host resolution to happen
5348 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5349 // connection to the the server, in this test we require confirmation
5350 // before encrypting so the HTTP job will still start.
5351 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295352 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
zhongyica364fbb2015-12-12 03:39:125353 "");
rch9ae5b3b2016-02-11 00:36:295354 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
zhongyica364fbb2015-12-12 03:39:125355 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105356 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585357 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5358 CompletionOnceCallback(), &request,
5359 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415360 EXPECT_THAT(rv, IsOk());
zhongyica364fbb2015-12-12 03:39:125361
rch3f4b8452016-02-23 16:59:325362 CreateSession();
zhongyica364fbb2015-12-12 03:39:125363 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275364 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
zhongyica364fbb2015-12-12 03:39:125365
bnc691fda62016-08-12 00:43:165366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
zhongyica364fbb2015-12-12 03:39:125367 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415368 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015369 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:125370
5371 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525372 quic::QuicSession::HANDSHAKE_CONFIRMED);
robpercival214763f2016-07-01 23:27:015373 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
zhongyica364fbb2015-12-12 03:39:125374 NetErrorDetails details;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525375 EXPECT_EQ(quic::QUIC_NO_ERROR, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125376
bnc691fda62016-08-12 00:43:165377 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525378 EXPECT_EQ(quic::QUIC_INVALID_STREAM_ID, details.quic_connection_error);
zhongyica364fbb2015-12-12 03:39:125379}
5380
rchcd5f1c62016-06-23 02:43:485381TEST_P(QuicNetworkTransactionTest, RstSteamErrorHandling) {
5382 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525383 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365384 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435385 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5386 mock_quic_data.AddWrite(
5387 SYNCHRONOUS,
5388 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335389 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435390 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
rchcd5f1c62016-06-23 02:43:485391 // Read the response headers, then a RST_STREAM frame.
Fan Yang32c5a112018-12-10 20:06:335392 mock_quic_data.AddRead(
5393 ASYNC, ConstructServerResponseHeadersPacket(
5394 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5395 GetResponseHeaders("200 OK")));
5396 mock_quic_data.AddRead(
5397 ASYNC, ConstructServerRstPacket(
5398 2, false, GetNthClientInitiatedBidirectionalStreamId(0),
5399 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi32f2fd02018-04-16 18:23:435400 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchcd5f1c62016-06-23 02:43:485401 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5402 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5403
5404 // The non-alternate protocol job needs to hang in order to guarantee that
5405 // the alternate-protocol job will "win".
5406 AddHangingNonAlternateProtocolSocketData();
5407
5408 // In order for a new QUIC session to be established via alternate-protocol
5409 // without racing an HTTP connection, we need the host resolution to happen
5410 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5411 // connection to the the server, in this test we require confirmation
5412 // before encrypting so the HTTP job will still start.
5413 host_resolver_.set_synchronous_mode(true);
5414 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5415 "");
5416 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5417 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105418 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585419 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5420 CompletionOnceCallback(), &request,
5421 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415422 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485423
5424 CreateSession();
5425 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275426 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485427
bnc691fda62016-08-12 00:43:165428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485429 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415430 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485432
5433 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525434 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485435 // Read the headers.
robpercival214763f2016-07-01 23:27:015436 EXPECT_THAT(callback.WaitForResult(), IsOk());
rchcd5f1c62016-06-23 02:43:485437
bnc691fda62016-08-12 00:43:165438 const HttpResponseInfo* response = trans.GetResponseInfo();
rchcd5f1c62016-06-23 02:43:485439 ASSERT_TRUE(response != nullptr);
5440 ASSERT_TRUE(response->headers.get() != nullptr);
5441 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5442 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:525443 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:445444 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
5445 response->connection_info);
rchcd5f1c62016-06-23 02:43:485446
5447 std::string response_data;
bnc691fda62016-08-12 00:43:165448 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data));
rchcd5f1c62016-06-23 02:43:485449}
5450
5451TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) {
Ryan Hamiltonb3827e882018-03-27 03:07:485452 session_params_.retry_without_alt_svc_on_quic_errors = false;
rchcd5f1c62016-06-23 02:43:485453 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525454 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365455 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435456 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5457 mock_quic_data.AddWrite(
5458 SYNCHRONOUS,
5459 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335460 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435461 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:335462 mock_quic_data.AddRead(
5463 ASYNC, ConstructServerRstPacket(
5464 1, false, GetNthClientInitiatedBidirectionalStreamId(0),
5465 quic::QUIC_STREAM_CANCELLED));
rchcd5f1c62016-06-23 02:43:485466 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
5467 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5468
5469 // The non-alternate protocol job needs to hang in order to guarantee that
5470 // the alternate-protocol job will "win".
5471 AddHangingNonAlternateProtocolSocketData();
5472
5473 // In order for a new QUIC session to be established via alternate-protocol
5474 // without racing an HTTP connection, we need the host resolution to happen
5475 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
5476 // connection to the the server, in this test we require confirmation
5477 // before encrypting so the HTTP job will still start.
5478 host_resolver_.set_synchronous_mode(true);
5479 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
5480 "");
5481 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
5482 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105483 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585484 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5485 CompletionOnceCallback(), &request,
5486 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415487 EXPECT_THAT(rv, IsOk());
rchcd5f1c62016-06-23 02:43:485488
5489 CreateSession();
5490 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275491 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
rchcd5f1c62016-06-23 02:43:485492
bnc691fda62016-08-12 00:43:165493 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rchcd5f1c62016-06-23 02:43:485494 TestCompletionCallback callback;
Bence Béky844d7b12018-06-04 17:30:415495 rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015496 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rchcd5f1c62016-06-23 02:43:485497
5498 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525499 quic::QuicSession::HANDSHAKE_CONFIRMED);
rchcd5f1c62016-06-23 02:43:485500 // Read the headers.
robpercival214763f2016-07-01 23:27:015501 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
rchcd5f1c62016-06-23 02:43:485502}
5503
[email protected]1e960032013-12-20 19:00:205504TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
[email protected]3316d422013-05-03 21:45:305505 // Alternate-protocol job
Ryan Hamilton8d9ee76e2018-05-29 23:52:525506 std::unique_ptr<quic::QuicEncryptedPacket> close(
alyssar2adf3ac2016-05-03 17:12:585507 ConstructServerConnectionClosePacket(1));
[email protected]3316d422013-05-03 21:45:305508 MockRead quic_reads[] = {
rchb27683c2015-07-29 23:53:505509 MockRead(ASYNC, close->data(), close->length()),
5510 MockRead(ASYNC, ERR_IO_PENDING), // No more data to read
5511 MockRead(ASYNC, OK), // EOF
[email protected]3316d422013-05-03 21:45:305512 };
Ryan Sleevib8d7ea02018-05-07 20:01:015513 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305514 socket_factory_.AddSocketDataProvider(&quic_data);
5515
5516 // Main job which will succeed even though the alternate job fails.
5517 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025518 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5519 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5520 MockRead(ASYNC, OK)};
[email protected]3316d422013-05-03 21:45:305521
Ryan Sleevib8d7ea02018-05-07 20:01:015522 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]3316d422013-05-03 21:45:305523 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565524 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]3316d422013-05-03 21:45:305525
rch3f4b8452016-02-23 16:59:325526 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275527 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195528 SendRequestAndExpectHttpResponse("hello from http");
5529 ExpectBrokenAlternateProtocolMapping();
[email protected]3316d422013-05-03 21:45:305530}
5531
[email protected]1e960032013-12-20 19:00:205532TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
[email protected]d03a66d2013-05-06 12:55:595533 // Alternate-protocol job
5534 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025535 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]d03a66d2013-05-06 12:55:595536 };
Ryan Sleevib8d7ea02018-05-07 20:01:015537 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595538 socket_factory_.AddSocketDataProvider(&quic_data);
5539
5540 // Main job which will succeed even though the alternate job fails.
5541 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025542 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5543 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5544 MockRead(ASYNC, OK)};
[email protected]d03a66d2013-05-06 12:55:595545
Ryan Sleevib8d7ea02018-05-07 20:01:015546 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]d03a66d2013-05-06 12:55:595547 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565548 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]d03a66d2013-05-06 12:55:595549
rch3f4b8452016-02-23 16:59:325550 CreateSession();
[email protected]d03a66d2013-05-06 12:55:595551
Ryan Hamilton9835e662018-08-02 05:36:275552 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]aa9b14d2013-05-10 23:45:195553 SendRequestAndExpectHttpResponse("hello from http");
5554 ExpectBrokenAlternateProtocolMapping();
[email protected]d03a66d2013-05-06 12:55:595555}
5556
[email protected]00c159f2014-05-21 22:38:165557TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
[email protected]eb71ab62014-05-23 07:57:535558 // Alternate-protocol job will fail when the session attempts to read.
[email protected]00c159f2014-05-21 22:38:165559 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025560 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165561 };
Ryan Sleevib8d7ea02018-05-07 20:01:015562 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165563 socket_factory_.AddSocketDataProvider(&quic_data);
5564
[email protected]eb71ab62014-05-23 07:57:535565 // Main job will also fail.
[email protected]00c159f2014-05-21 22:38:165566 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025567 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]00c159f2014-05-21 22:38:165568 };
5569
Ryan Sleevib8d7ea02018-05-07 20:01:015570 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]00c159f2014-05-21 22:38:165571 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5572 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565573 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]00c159f2014-05-21 22:38:165574
rtennetib8e80fb2016-05-16 00:12:095575 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325576 CreateSession();
[email protected]00c159f2014-05-21 22:38:165577
Ryan Hamilton9835e662018-08-02 05:36:275578 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
bnc691fda62016-08-12 00:43:165579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
[email protected]00c159f2014-05-21 22:38:165580 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:165581 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:015582 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5583 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED));
[email protected]00c159f2014-05-21 22:38:165584 ExpectQuicAlternateProtocolMapping();
5585}
5586
Zhongyi Shia0cef1082017-08-25 01:49:505587TEST_P(QuicNetworkTransactionTest, DelayTCPOnStartWithQuicSupportOnSameIP) {
5588 // Tests that TCP job is delayed and QUIC job does not require confirmation
5589 // if QUIC was recently supported on the same IP on start.
5590
5591 // Set QUIC support on the last IP address, which is same with the local IP
5592 // address. Require confirmation mode will be turned off immediately when
5593 // local IP address is sorted out after we configure the UDP socket.
5594 http_server_properties_.SetSupportsQuic(true, IPAddress(192, 0, 2, 33));
5595
5596 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525597 quic::QuicStreamOffset header_stream_offset = 0;
5598 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
5599 client_maker_.SetLongHeaderType(quic::ZERO_RTT_PROTECTED);
Zhongyi Shi32f2fd02018-04-16 18:23:435600 mock_quic_data.AddWrite(
5601 SYNCHRONOUS,
5602 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335603 1, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435604 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435605 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335606 ASYNC, ConstructServerResponseHeadersPacket(
5607 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5608 GetResponseHeaders("200 OK")));
5609 mock_quic_data.AddRead(
5610 ASYNC, ConstructServerDataPacket(
5611 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5612 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435613 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505614 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
5615 mock_quic_data.AddRead(ASYNC, 0); // EOF
5616
5617 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5618 // No HTTP data is mocked as TCP job never starts in this case.
5619
5620 CreateSession();
5621 // QuicStreamFactory by default requires confirmation on construction.
5622 session_->quic_stream_factory()->set_require_confirmation(true);
5623
Ryan Hamilton9835e662018-08-02 05:36:275624 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505625
5626 // Stall host resolution so that QUIC job will not succeed synchronously.
5627 // Socket will not be configured immediately and QUIC support is not sorted
5628 // out, TCP job will still be delayed as server properties indicates QUIC
5629 // support on last IP address.
5630 host_resolver_.set_synchronous_mode(false);
5631
5632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5633 TestCompletionCallback callback;
5634 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5635 IsError(ERR_IO_PENDING));
5636 // Complete host resolution in next message loop so that QUIC job could
5637 // proceed.
5638 base::RunLoop().RunUntilIdle();
5639 EXPECT_THAT(callback.WaitForResult(), IsOk());
5640
5641 CheckWasQuicResponse(&trans);
5642 CheckResponseData(&trans, "hello!");
5643}
5644
5645TEST_P(QuicNetworkTransactionTest,
5646 DelayTCPOnStartWithQuicSupportOnDifferentIP) {
5647 // Tests that TCP job is delayed and QUIC job requires confirmation if QUIC
5648 // was recently supported on a different IP address on start.
5649
5650 // Set QUIC support on the last IP address, which is different with the local
5651 // IP address. Require confirmation mode will remain when local IP address is
5652 // sorted out after we configure the UDP socket.
5653 http_server_properties_.SetSupportsQuic(true, IPAddress(1, 2, 3, 4));
5654
5655 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525656 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0cef1082017-08-25 01:49:505657 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435658 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5659 mock_quic_data.AddWrite(
5660 SYNCHRONOUS,
5661 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335662 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435663 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435664 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335665 ASYNC, ConstructServerResponseHeadersPacket(
5666 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5667 GetResponseHeaders("200 OK")));
5668 mock_quic_data.AddRead(
5669 ASYNC, ConstructServerDataPacket(
5670 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5671 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435672 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Zhongyi Shia0cef1082017-08-25 01:49:505673 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
5674 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5675 // No HTTP data is mocked as TCP job will be delayed and never starts.
5676
5677 CreateSession();
5678 session_->quic_stream_factory()->set_require_confirmation(true);
Ryan Hamilton9835e662018-08-02 05:36:275679 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
Zhongyi Shia0cef1082017-08-25 01:49:505680
5681 // Stall host resolution so that QUIC job could not proceed and unblocks TCP.
5682 // Socket will not be configured immediately and QUIC support is not sorted
5683 // out, TCP job will still be delayed as server properties indicates QUIC
5684 // support on last IP address.
5685 host_resolver_.set_synchronous_mode(false);
5686
5687 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5688 TestCompletionCallback callback;
5689 EXPECT_THAT(trans.Start(&request_, callback.callback(), net_log_.bound()),
5690 IsError(ERR_IO_PENDING));
5691
5692 // Complete host resolution in next message loop so that QUIC job could
5693 // proceed.
5694 base::RunLoop().RunUntilIdle();
5695 // Explicitly confirm the handshake so that QUIC job could succeed.
5696 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:525697 quic::QuicSession::HANDSHAKE_CONFIRMED);
Zhongyi Shia0cef1082017-08-25 01:49:505698 EXPECT_THAT(callback.WaitForResult(), IsOk());
5699
5700 CheckWasQuicResponse(&trans);
5701 CheckResponseData(&trans, "hello!");
5702}
5703
Ryan Hamilton75f197262017-08-17 14:00:075704TEST_P(QuicNetworkTransactionTest, NetErrorDetailsSetBeforeHandshake) {
5705 // Test that NetErrorDetails is correctly populated, even if the
5706 // handshake has not yet been confirmed and no stream has been created.
5707
5708 // QUIC job will pause. When resumed, it will fail.
5709 MockQuicData mock_quic_data;
5710 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
5711 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_CLOSED);
5712 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5713
5714 // Main job will also fail.
5715 MockRead http_reads[] = {
5716 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
5717 };
5718
Ryan Sleevib8d7ea02018-05-07 20:01:015719 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Ryan Hamilton75f197262017-08-17 14:00:075720 http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
5721 socket_factory_.AddSocketDataProvider(&http_data);
5722 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5723
5724 AddHangingNonAlternateProtocolSocketData();
5725 CreateSession();
5726 // Require handshake confirmation to ensure that no QUIC streams are
5727 // created, and to ensure that the TCP job does not wait for the QUIC
5728 // job to fail before it starts.
5729 session_->quic_stream_factory()->set_require_confirmation(true);
5730
Ryan Hamilton9835e662018-08-02 05:36:275731 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
Ryan Hamilton75f197262017-08-17 14:00:075732 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
5733 TestCompletionCallback callback;
5734 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
5735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
5736 // Allow the TCP job to fail.
5737 base::RunLoop().RunUntilIdle();
5738 // Now let the QUIC job fail.
5739 mock_quic_data.Resume();
5740 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
5741 ExpectQuicAlternateProtocolMapping();
5742 NetErrorDetails details;
5743 trans.PopulateNetErrorDetails(&details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525744 EXPECT_EQ(quic::QUIC_PACKET_READ_ERROR, details.quic_connection_error);
Ryan Hamilton75f197262017-08-17 14:00:075745}
5746
[email protected]1e960032013-12-20 19:00:205747TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
[email protected]77c6c162013-08-17 02:57:455748 // Alternate-protocol job
5749 MockRead quic_reads[] = {
rjshaded5ced072015-12-18 19:26:025750 MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
[email protected]77c6c162013-08-17 02:57:455751 };
Ryan Sleevib8d7ea02018-05-07 20:01:015752 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]77c6c162013-08-17 02:57:455753 socket_factory_.AddSocketDataProvider(&quic_data);
5754
[email protected]c92c1b52014-05-31 04:16:065755 // Second Alternate-protocol job which will race with the TCP job.
Ryan Sleevib8d7ea02018-05-07 20:01:015756 StaticSocketDataProvider quic_data2(quic_reads, base::span<MockWrite>());
[email protected]c92c1b52014-05-31 04:16:065757 socket_factory_.AddSocketDataProvider(&quic_data2);
5758
[email protected]4d283b32013-10-17 12:57:275759 // Final job that will proceed when the QUIC job fails.
5760 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025761 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5762 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5763 MockRead(ASYNC, OK)};
[email protected]4d283b32013-10-17 12:57:275764
Ryan Sleevib8d7ea02018-05-07 20:01:015765 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d283b32013-10-17 12:57:275766 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565767 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d283b32013-10-17 12:57:275768
rtennetiafccbc062016-05-16 18:21:145769 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325770 CreateSession();
[email protected]77c6c162013-08-17 02:57:455771
Ryan Hamilton9835e662018-08-02 05:36:275772 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]77c6c162013-08-17 02:57:455773
[email protected]4d283b32013-10-17 12:57:275774 SendRequestAndExpectHttpResponse("hello from http");
[email protected]77c6c162013-08-17 02:57:455775
5776 ExpectBrokenAlternateProtocolMapping();
[email protected]4d283b32013-10-17 12:57:275777
rch37de576c2015-05-17 20:28:175778 EXPECT_TRUE(quic_data.AllReadDataConsumed());
5779 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
[email protected]77c6c162013-08-17 02:57:455780}
5781
[email protected]93b31772014-06-19 08:03:355782TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
[email protected]65768442014-06-06 23:37:035783 // Alternate-protocol job
5784 MockRead quic_reads[] = {
mmenkee24011922015-12-17 22:12:595785 MockRead(SYNCHRONOUS, ERR_IO_PENDING),
[email protected]65768442014-06-06 23:37:035786 };
Ryan Sleevib8d7ea02018-05-07 20:01:015787 StaticSocketDataProvider quic_data(quic_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035788 socket_factory_.AddSocketDataProvider(&quic_data);
5789
5790 // Main job that will proceed when the QUIC job fails.
5791 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025792 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5793 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5794 MockRead(ASYNC, OK)};
[email protected]65768442014-06-06 23:37:035795
Ryan Sleevib8d7ea02018-05-07 20:01:015796 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]65768442014-06-06 23:37:035797 socket_factory_.AddSocketDataProvider(&http_data);
5798
rtennetib8e80fb2016-05-16 00:12:095799 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325800 CreateSession();
[email protected]65768442014-06-06 23:37:035801
Ryan Hamilton9835e662018-08-02 05:36:275802 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]65768442014-06-06 23:37:035803
5804 SendRequestAndExpectHttpResponse("hello from http");
5805}
5806
[email protected]eb71ab62014-05-23 07:57:535807TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
[email protected]4d590c9c2014-05-02 05:14:335808 // Alternate-protocol job will fail before creating a QUIC session.
Ryan Sleevib8d7ea02018-05-07 20:01:015809 StaticSocketDataProvider quic_data;
tbansal6b527482017-01-27 19:10:495810 quic_data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
[email protected]4d590c9c2014-05-02 05:14:335811 socket_factory_.AddSocketDataProvider(&quic_data);
5812
5813 // Main job which will succeed even though the alternate job fails.
5814 MockRead http_reads[] = {
rjshaded5ced072015-12-18 19:26:025815 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello from http"),
5816 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5817 MockRead(ASYNC, OK)};
[email protected]4d590c9c2014-05-02 05:14:335818
Ryan Sleevib8d7ea02018-05-07 20:01:015819 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4d590c9c2014-05-02 05:14:335820 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565821 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4d590c9c2014-05-02 05:14:335822
rch3f4b8452016-02-23 16:59:325823 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275824 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
[email protected]4d590c9c2014-05-02 05:14:335825 SendRequestAndExpectHttpResponse("hello from http");
[email protected]eb71ab62014-05-23 07:57:535826
5827 ExpectBrokenAlternateProtocolMapping();
[email protected]4d590c9c2014-05-02 05:14:335828}
5829
[email protected]4fee9672014-01-08 14:47:155830TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
[email protected]4fee9672014-01-08 14:47:155831 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435832 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335833 mock_quic_data.AddWrite(
5834 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5835 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5836 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435837 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
rcha5399e02015-04-21 19:32:045838 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
[email protected]4fee9672014-01-08 14:47:155839
5840 // When the QUIC connection fails, we will try the request again over HTTP.
5841 MockRead http_reads[] = {
bnc1c196c6e2016-05-28 13:51:485842 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
rchf114d982015-10-21 01:34:565843 MockRead("hello world"),
5844 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5845 MockRead(ASYNC, OK)};
[email protected]4fee9672014-01-08 14:47:155846
Ryan Sleevib8d7ea02018-05-07 20:01:015847 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
[email protected]4fee9672014-01-08 14:47:155848 socket_factory_.AddSocketDataProvider(&http_data);
rchf114d982015-10-21 01:34:565849 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
[email protected]4fee9672014-01-08 14:47:155850
5851 // In order for a new QUIC session to be established via alternate-protocol
5852 // without racing an HTTP connection, we need the host resolution to happen
5853 // synchronously.
5854 host_resolver_.set_synchronous_mode(true);
rch9ae5b3b2016-02-11 00:36:295855 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
rchf114d982015-10-21 01:34:565856 "");
rch9ae5b3b2016-02-11 00:36:295857 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
[email protected]4fee9672014-01-08 14:47:155858 AddressList address;
maksim.sisov31452af2016-07-27 06:38:105859 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585860 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5861 CompletionOnceCallback(), &request,
5862 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415863 EXPECT_THAT(rv, IsOk());
[email protected]4fee9672014-01-08 14:47:155864
rch3f4b8452016-02-23 16:59:325865 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275866 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
[email protected]4fee9672014-01-08 14:47:155867 SendRequestAndExpectHttpResponse("hello world");
5868}
5869
tbansalc3308d72016-08-27 10:25:045870// For an alternative proxy that supports QUIC, test that the request is
5871// successfully fetched by the main job when the alternate proxy job encounters
5872// an error.
5873TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxySocketNotConnected) {
5874 TestAlternativeProxy(ERR_SOCKET_NOT_CONNECTED);
5875}
5876TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionFailed) {
5877 TestAlternativeProxy(ERR_CONNECTION_FAILED);
5878}
5879TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionTimedOut) {
5880 TestAlternativeProxy(ERR_CONNECTION_TIMED_OUT);
5881}
5882TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyConnectionRefused) {
5883 TestAlternativeProxy(ERR_CONNECTION_REFUSED);
5884}
5885TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicHandshakeFailed) {
5886 TestAlternativeProxy(ERR_QUIC_HANDSHAKE_FAILED);
5887}
5888TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyQuicProtocolError) {
5889 TestAlternativeProxy(ERR_QUIC_PROTOCOL_ERROR);
5890}
5891TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPending) {
5892 TestAlternativeProxy(ERR_IO_PENDING);
5893}
5894TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
5895 TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
5896}
5897
5898TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
5899 MockQuicData mock_quic_data;
Zhongyi Shi32f2fd02018-04-16 18:23:435900 mock_quic_data.AddRead(SYNCHRONOUS, ConstructServerConnectionClosePacket(1));
Fan Yang32c5a112018-12-10 20:06:335901 mock_quic_data.AddWrite(
5902 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
5903 1, GetNthClientInitiatedBidirectionalStreamId(0), true,
5904 true, GetRequestHeaders("GET", "https", "/")));
Zhongyi Shi32f2fd02018-04-16 18:23:435905 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(2, 1, 1, 1));
tbansalc3308d72016-08-27 10:25:045906 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5907
5908 // When the QUIC connection fails, we will try the request again over HTTP.
5909 MockRead http_reads[] = {
5910 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
5911 MockRead("hello world"),
5912 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
5913 MockRead(ASYNC, OK)};
5914
Ryan Sleevib8d7ea02018-05-07 20:01:015915 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
tbansalc3308d72016-08-27 10:25:045916 socket_factory_.AddSocketDataProvider(&http_data);
5917 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
5918
5919 TestProxyDelegate test_proxy_delegate;
5920 const HostPortPair host_port_pair("myproxy.org", 443);
5921 test_proxy_delegate.set_alternative_proxy_server(
5922 ProxyServer::FromPacString("QUIC myproxy.org:443"));
5923 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
5924
Ramin Halavatica8d5252018-03-12 05:33:495925 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
5926 "HTTPS myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
Eric Roman3d8546a2018-09-10 17:00:525927 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045928 request_.url = GURL("http://mail.example.org/");
5929
5930 // In order for a new QUIC session to be established via alternate-protocol
5931 // without racing an HTTP connection, we need the host resolution to happen
5932 // synchronously.
5933 host_resolver_.set_synchronous_mode(true);
5934 host_resolver_.rules()->AddIPLiteralRule("myproxy.org", "192.168.0.1", "");
5935 HostResolver::RequestInfo info(HostPortPair("myproxy.org", 443));
5936 AddressList address;
5937 std::unique_ptr<HostResolver::Request> request;
Bence Békyd8a21fc32018-06-27 18:29:585938 int rv = host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
5939 CompletionOnceCallback(), &request,
5940 net_log_.bound());
Bence Béky844d7b12018-06-04 17:30:415941 EXPECT_THAT(rv, IsOk());
tbansalc3308d72016-08-27 10:25:045942
5943 CreateSession();
5944 SendRequestAndExpectHttpResponseFromProxy("hello world", true, 443);
Lily Houghton8c2f97d2018-01-22 05:06:595945 EXPECT_THAT(session_->proxy_resolution_service()->proxy_retry_info(),
Reilly Grant89a7e512018-01-20 01:57:165946 ElementsAre(Key("quic://myproxy.org:443")));
tbansalc3308d72016-08-27 10:25:045947}
5948
bnc508835902015-05-12 20:10:295949TEST_P(QuicNetworkTransactionTest, SecureResourceOverSecureQuic) {
alyssar2adf3ac2016-05-03 17:12:585950 client_maker_.set_hostname("www.example.org");
tbansal0f56a39a2016-04-07 22:03:385951 EXPECT_FALSE(
5952 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295953 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:525954 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:365955 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435956 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5957 mock_quic_data.AddWrite(
5958 SYNCHRONOUS,
5959 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:335960 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:435961 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435962 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:335963 ASYNC, ConstructServerResponseHeadersPacket(
5964 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
5965 GetResponseHeaders("200 OK")));
5966 mock_quic_data.AddRead(
5967 ASYNC, ConstructServerDataPacket(
5968 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
5969 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:435970 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
rchb27683c2015-07-29 23:53:505971 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more read data.
bnc508835902015-05-12 20:10:295972 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
5973
bncb07c05532015-05-14 19:07:205974 request_.url = GURL("https://www.example.org:443");
rtennetib8e80fb2016-05-16 00:12:095975 AddHangingNonAlternateProtocolSocketData();
rch3f4b8452016-02-23 16:59:325976 CreateSession();
Ryan Hamilton9835e662018-08-02 05:36:275977 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE);
bnc508835902015-05-12 20:10:295978 SendRequestAndExpectQuicResponse("hello!");
tbansal0f56a39a2016-04-07 22:03:385979 EXPECT_TRUE(
5980 test_socket_performance_watcher_factory_.rtt_notification_received());
bnc508835902015-05-12 20:10:295981}
5982
zhongyi363c91c2017-03-23 23:16:085983// TODO(zhongyi): disabled this broken test as it was not testing the correct
5984// code path. Need a fix to re-enable this test, tracking at crbug.com/704596.
5985TEST_P(QuicNetworkTransactionTest,
5986 DISABLED_QuicUploadToAlternativeProxyServer) {
tbansal6490783c2016-09-20 17:55:275987 base::HistogramTester histogram_tester;
Lily Houghton8c2f97d2018-01-22 05:06:595988 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:495989 "HTTPS mail.example.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansalc3308d72016-08-27 10:25:045990
5991 TestProxyDelegate test_proxy_delegate;
tbansalc3308d72016-08-27 10:25:045992
5993 test_proxy_delegate.set_alternative_proxy_server(
5994 ProxyServer::FromPacString("QUIC mail.example.org:443"));
Eric Roman3d8546a2018-09-10 17:00:525995 proxy_resolution_service_->SetProxyDelegate(&test_proxy_delegate);
tbansalc3308d72016-08-27 10:25:045996
5997 request_.url = GURL("http://mail.example.org/");
5998
5999 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6000 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016001 SequencedSocketData socket_data(reads, writes);
tbansalc3308d72016-08-27 10:25:046002 socket_factory_.AddSocketDataProvider(&socket_data);
6003
6004 // The non-alternate protocol job needs to hang in order to guarantee that
6005 // the alternate-protocol job will "win".
6006 AddHangingNonAlternateProtocolSocketData();
6007
6008 CreateSession();
6009 request_.method = "POST";
6010 ChunkedUploadDataStream upload_data(0);
6011 upload_data.AppendData("1", 1, true);
6012
6013 request_.upload_data_stream = &upload_data;
6014
6015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6016 TestCompletionCallback callback;
6017 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6018 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6019 EXPECT_NE(OK, callback.WaitForResult());
6020
6021 // Verify that the alternative proxy server is not marked as broken.
6022 EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
6023
6024 // Verify that the proxy server is not marked as broken.
Lily Houghton8c2f97d2018-01-22 05:06:596025 EXPECT_TRUE(session_->proxy_resolution_service()->proxy_retry_info().empty());
tbansal6490783c2016-09-20 17:55:276026
6027 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
6028 1 /* ALTERNATIVE_PROXY_USAGE_WON_RACE */,
6029 1);
tbansalc3308d72016-08-27 10:25:046030}
6031
rtenneti56977812016-01-15 19:26:566032TEST_P(QuicNetworkTransactionTest, QuicUpload) {
mmenke6ddfbea2017-05-31 21:48:416033 session_params_.origins_to_force_quic_on.insert(
rtenneti8a2f4632016-03-21 20:26:576034 HostPortPair::FromString("mail.example.org:443"));
rtenneti56977812016-01-15 19:26:566035
6036 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
6037 MockWrite writes[] = {MockWrite(SYNCHRONOUS, ERR_FAILED, 1)};
Ryan Sleevib8d7ea02018-05-07 20:01:016038 SequencedSocketData socket_data(reads, writes);
rtenneti56977812016-01-15 19:26:566039 socket_factory_.AddSocketDataProvider(&socket_data);
6040
rtennetib8e80fb2016-05-16 00:12:096041 // The non-alternate protocol job needs to hang in order to guarantee that
6042 // the alternate-protocol job will "win".
6043 AddHangingNonAlternateProtocolSocketData();
6044
rtenneti56977812016-01-15 19:26:566045 CreateSession();
6046 request_.method = "POST";
6047 ChunkedUploadDataStream upload_data(0);
6048 upload_data.AppendData("1", 1, true);
6049
6050 request_.upload_data_stream = &upload_data;
6051
bnc691fda62016-08-12 00:43:166052 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
rtenneti56977812016-01-15 19:26:566053 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:166054 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016055 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rtenneti56977812016-01-15 19:26:566056 EXPECT_NE(OK, callback.WaitForResult());
6057}
6058
rche11300ef2016-09-02 01:44:286059TEST_P(QuicNetworkTransactionTest, QuicUploadWriteError) {
Ryan Hamiltonb3827e882018-03-27 03:07:486060 session_params_.retry_without_alt_svc_on_quic_errors = false;
rche11300ef2016-09-02 01:44:286061 ScopedMockNetworkChangeNotifier network_change_notifier;
6062 MockNetworkChangeNotifier* mock_ncn =
6063 network_change_notifier.mock_network_change_notifier();
6064 mock_ncn->ForceNetworkHandlesSupported();
6065 mock_ncn->SetConnectedNetworksList(
6066 {kDefaultNetworkForTests, kNewNetworkForTests});
6067
mmenke6ddfbea2017-05-31 21:48:416068 session_params_.origins_to_force_quic_on.insert(
rche11300ef2016-09-02 01:44:286069 HostPortPair::FromString("mail.example.org:443"));
Zhongyi Shic461bdb2018-06-26 22:07:316070 session_params_.quic_migrate_sessions_on_network_change_v2 = true;
rche11300ef2016-09-02 01:44:286071
6072 MockQuicData socket_data;
6073 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526074 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436075 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Fan Yang32c5a112018-12-10 20:06:336076 socket_data.AddWrite(
6077 SYNCHRONOUS,
6078 ConstructClientRequestHeadersPacket(
6079 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
6080 GetRequestHeaders("POST", "https", "/"), &offset));
rche11300ef2016-09-02 01:44:286081 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6082 socket_data.AddSocketDataToFactory(&socket_factory_);
6083
6084 MockQuicData socket_data2;
6085 socket_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_INVALID);
6086 socket_data2.AddSocketDataToFactory(&socket_factory_);
6087
6088 // The non-alternate protocol job needs to hang in order to guarantee that
6089 // the alternate-protocol job will "win".
6090 AddHangingNonAlternateProtocolSocketData();
6091
6092 CreateSession();
6093 request_.method = "POST";
6094 ChunkedUploadDataStream upload_data(0);
6095
6096 request_.upload_data_stream = &upload_data;
6097
rdsmith1d343be52016-10-21 20:37:506098 std::unique_ptr<HttpNetworkTransaction> trans(
6099 new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
rche11300ef2016-09-02 01:44:286100 TestCompletionCallback callback;
rdsmith1d343be52016-10-21 20:37:506101 int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
rche11300ef2016-09-02 01:44:286102 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6103
6104 base::RunLoop().RunUntilIdle();
6105 upload_data.AppendData("1", 1, true);
6106 base::RunLoop().RunUntilIdle();
6107
6108 EXPECT_NE(OK, callback.WaitForResult());
rdsmith1d343be52016-10-21 20:37:506109 trans.reset();
rche11300ef2016-09-02 01:44:286110 session_.reset();
6111}
6112
Ryan Hamilton4b3574532017-10-30 20:17:256113TEST_P(QuicNetworkTransactionTest, RetryAfterAsyncNoBufferSpace) {
6114 session_params_.origins_to_force_quic_on.insert(
6115 HostPortPair::FromString("mail.example.org:443"));
6116
6117 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526118 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436119 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256120 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336121 socket_data.AddWrite(
6122 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6123 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6124 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436125 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336126 ASYNC, ConstructServerResponseHeadersPacket(
6127 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6128 GetResponseHeaders("200 OK")));
6129 socket_data.AddRead(
6130 ASYNC, ConstructServerDataPacket(
6131 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6132 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436133 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256134 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166135 socket_data.AddWrite(
6136 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6137 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6138 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256139
6140 socket_data.AddSocketDataToFactory(&socket_factory_);
6141
6142 CreateSession();
6143
6144 SendRequestAndExpectQuicResponse("hello!");
6145 session_.reset();
6146}
6147
6148TEST_P(QuicNetworkTransactionTest, RetryAfterSynchronousNoBufferSpace) {
6149 session_params_.origins_to_force_quic_on.insert(
6150 HostPortPair::FromString("mail.example.org:443"));
6151
6152 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526153 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436154 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton4b3574532017-10-30 20:17:256155 socket_data.AddWrite(SYNCHRONOUS, ERR_NO_BUFFER_SPACE);
Fan Yang32c5a112018-12-10 20:06:336156 socket_data.AddWrite(
6157 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6158 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6159 true, GetRequestHeaders("GET", "https", "/"), &offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436160 socket_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336161 ASYNC, ConstructServerResponseHeadersPacket(
6162 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6163 GetResponseHeaders("200 OK")));
6164 socket_data.AddRead(
6165 ASYNC, ConstructServerDataPacket(
6166 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6167 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436168 socket_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Ryan Hamilton4b3574532017-10-30 20:17:256169 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Renjieba55fae2018-09-20 03:05:166170 socket_data.AddWrite(
6171 SYNCHRONOUS, client_maker_.MakeAckAndConnectionClosePacket(
6172 4, false, quic::QuicTime::Delta::FromMilliseconds(0), 2,
6173 1, 1, quic::QUIC_CONNECTION_CANCELLED, "net error"));
Ryan Hamilton4b3574532017-10-30 20:17:256174
6175 socket_data.AddSocketDataToFactory(&socket_factory_);
6176
6177 CreateSession();
6178
6179 SendRequestAndExpectQuicResponse("hello!");
6180 session_.reset();
6181}
6182
Ryan Hamilton9edcf1a2017-11-22 05:55:176183TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterAsyncNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486184 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256185 session_params_.origins_to_force_quic_on.insert(
6186 HostPortPair::FromString("mail.example.org:443"));
6187
6188 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526189 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256190 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436191 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176192 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256193 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6194 }
6195 socket_data.AddSocketDataToFactory(&socket_factory_);
6196
6197 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176198 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6199 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6200 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6201 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256202
Ryan Hamilton8d9ee76e2018-05-29 23:52:526203 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256204 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6205 TestCompletionCallback callback;
6206 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176208 while (!callback.have_result()) {
6209 base::RunLoop().RunUntilIdle();
6210 quic_task_runner_->RunUntilIdle();
6211 }
6212 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256213 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176214 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6215 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6216 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526217 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6218 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256219}
6220
Ryan Hamilton9edcf1a2017-11-22 05:55:176221TEST_P(QuicNetworkTransactionTest, MaxRetriesAfterSynchronousNoBufferSpace) {
Ryan Hamiltonb3827e882018-03-27 03:07:486222 session_params_.retry_without_alt_svc_on_quic_errors = false;
Ryan Hamilton4b3574532017-10-30 20:17:256223 session_params_.origins_to_force_quic_on.insert(
6224 HostPortPair::FromString("mail.example.org:443"));
6225
6226 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526227 quic::QuicStreamOffset offset = 0;
Ryan Hamilton4b3574532017-10-30 20:17:256228 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
Zhongyi Shi32f2fd02018-04-16 18:23:436229 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Ryan Hamilton9edcf1a2017-11-22 05:55:176230 for (int i = 0; i < 13; ++i) { // 12 retries then one final failure.
Ryan Hamilton4b3574532017-10-30 20:17:256231 socket_data.AddWrite(ASYNC, ERR_NO_BUFFER_SPACE);
6232 }
6233 socket_data.AddSocketDataToFactory(&socket_factory_);
6234
6235 CreateSession();
Ryan Hamilton9edcf1a2017-11-22 05:55:176236 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
6237 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
6238 QuicStreamFactoryPeer::SetTaskRunner(session_->quic_stream_factory(),
6239 quic_task_runner_.get());
Ryan Hamilton4b3574532017-10-30 20:17:256240
Ryan Hamilton8d9ee76e2018-05-29 23:52:526241 quic::QuicTime start = clock_.Now();
Ryan Hamilton4b3574532017-10-30 20:17:256242 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6243 TestCompletionCallback callback;
6244 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6245 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Ryan Hamilton9edcf1a2017-11-22 05:55:176246 while (!callback.have_result()) {
6247 base::RunLoop().RunUntilIdle();
6248 quic_task_runner_->RunUntilIdle();
6249 }
6250 ASSERT_TRUE(callback.have_result());
Ryan Hamilton4b3574532017-10-30 20:17:256251 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
Ryan Hamilton9edcf1a2017-11-22 05:55:176252 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6253 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6254 // Backoff should take between 4 - 5 seconds.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526255 EXPECT_TRUE(clock_.Now() - start > quic::QuicTime::Delta::FromSeconds(4));
6256 EXPECT_TRUE(clock_.Now() - start < quic::QuicTime::Delta::FromSeconds(5));
Ryan Hamilton4b3574532017-10-30 20:17:256257}
6258
Cherie Shi7596de632018-02-22 07:28:186259TEST_P(QuicNetworkTransactionTest, NoMigrationForMsgTooBig) {
Ryan Hamiltonb3827e882018-03-27 03:07:486260 session_params_.retry_without_alt_svc_on_quic_errors = false;
Cherie Shi7596de632018-02-22 07:28:186261 session_params_.origins_to_force_quic_on.insert(
6262 HostPortPair::FromString("mail.example.org:443"));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526263 const quic::QuicString error_details =
6264 quic::QuicStrCat("Write failed with error: ", ERR_MSG_TOO_BIG, " (",
6265 strerror(ERR_MSG_TOO_BIG), ")");
Cherie Shi7596de632018-02-22 07:28:186266
6267 MockQuicData socket_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526268 quic::QuicStreamOffset offset = 0;
Cherie Shi7596de632018-02-22 07:28:186269 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436270 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(1, &offset));
Cherie Shi7596de632018-02-22 07:28:186271 socket_data.AddWrite(SYNCHRONOUS, ERR_MSG_TOO_BIG);
6272 // Connection close packet will be sent for MSG_TOO_BIG.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526273 socket_data.AddWrite(
6274 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
6275 3, true, quic::QUIC_PACKET_WRITE_ERROR, error_details));
Cherie Shi7596de632018-02-22 07:28:186276 socket_data.AddSocketDataToFactory(&socket_factory_);
6277
6278 CreateSession();
6279
6280 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6281 TestCompletionCallback callback;
6282 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
6283 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6284 base::RunLoop().RunUntilIdle();
6285 ASSERT_TRUE(callback.have_result());
6286 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6287 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6288 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6289}
6290
ckrasic769733c2016-06-30 00:42:136291// Adds coverage to catch regression such as https://crbug.com/622043
6292TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mmenke6ddfbea2017-05-31 21:48:416293 session_params_.origins_to_force_quic_on.insert(
ckrasic769733c2016-06-30 00:42:136294 HostPortPair::FromString("mail.example.org:443"));
6295
6296 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526297 quic::QuicStreamOffset header_stream_offset = 0;
6298 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436299 mock_quic_data.AddWrite(
6300 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6301 &header_stream_offset));
6302 mock_quic_data.AddWrite(
6303 SYNCHRONOUS,
6304 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336305 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6306 true, true, GetRequestHeaders("GET", "https", "/"),
6307 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526308 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436309 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336310 ASYNC, ConstructServerPushPromisePacket(
6311 1, GetNthClientInitiatedBidirectionalStreamId(0),
6312 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6313 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6314 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576315 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266316 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336317 mock_quic_data.AddWrite(SYNCHRONOUS,
6318 ConstructClientPriorityPacket(
6319 client_packet_number++, false,
6320 GetNthServerInitiatedUnidirectionalStreamId(0),
6321 GetNthClientInitiatedBidirectionalStreamId(0),
6322 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576323 }
Zhongyi Shi32f2fd02018-04-16 18:23:436324 mock_quic_data.AddRead(
6325 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336326 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436327 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:576328 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436329 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
6330 mock_quic_data.AddRead(
6331 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336332 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6333 false, GetResponseHeaders("200 OK"), &server_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436334 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336335 ASYNC, ConstructServerDataPacket(
6336 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6337 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:576338 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436339 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
6340 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336341 ASYNC, ConstructServerDataPacket(
6342 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
6343 0, "and hello!"));
6344 mock_quic_data.AddWrite(SYNCHRONOUS,
6345 ConstructClientAckAndRstPacket(
6346 client_packet_number++,
6347 GetNthServerInitiatedUnidirectionalStreamId(0),
6348 quic::QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
ckrasic769733c2016-06-30 00:42:136349 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6350 mock_quic_data.AddRead(ASYNC, 0); // EOF
6351 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6352
6353 // The non-alternate protocol job needs to hang in order to guarantee that
6354 // the alternate-protocol job will "win".
6355 AddHangingNonAlternateProtocolSocketData();
6356
6357 CreateSession();
6358
6359 // PUSH_PROMISE handling in the http layer gets exercised here.
6360 SendRequestAndExpectQuicResponse("hello!");
6361
6362 request_.url = GURL("https://mail.example.org/pushed.jpg");
6363 SendRequestAndExpectQuicResponse("and hello!");
6364
6365 // Check that the NetLog was filled reasonably.
6366 TestNetLogEntry::List entries;
6367 net_log_.GetEntries(&entries);
6368 EXPECT_LT(0u, entries.size());
6369
6370 // Check that we logged a QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM
6371 int pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:006372 entries, 0, NetLogEventType::QUIC_HTTP_STREAM_ADOPTED_PUSH_STREAM,
6373 NetLogEventPhase::NONE);
ckrasic769733c2016-06-30 00:42:136374 EXPECT_LT(0, pos);
6375}
6376
rch56ec40a2017-06-23 14:48:446377// Regression test for http://crbug.com/719461 in which a promised stream
6378// is closed before the pushed headers arrive, but after the connection
6379// is closed and before the callbacks are executed.
6380TEST_P(QuicNetworkTransactionTest, CancelServerPushAfterConnectionClose) {
Ryan Hamiltonb3827e882018-03-27 03:07:486381 session_params_.retry_without_alt_svc_on_quic_errors = false;
rch56ec40a2017-06-23 14:48:446382 session_params_.origins_to_force_quic_on.insert(
6383 HostPortPair::FromString("mail.example.org:443"));
6384
6385 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526386 quic::QuicStreamOffset header_stream_offset = 0;
6387 quic::QuicPacketNumber client_packet_number = 1;
rch56ec40a2017-06-23 14:48:446388 // Initial SETTINGS frame.
Zhongyi Shi32f2fd02018-04-16 18:23:436389 mock_quic_data.AddWrite(
6390 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6391 &header_stream_offset));
rch56ec40a2017-06-23 14:48:446392 // First request: GET https://mail.example.org/
Zhongyi Shi32f2fd02018-04-16 18:23:436393 mock_quic_data.AddWrite(
6394 SYNCHRONOUS,
6395 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336396 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6397 true, true, GetRequestHeaders("GET", "https", "/"),
6398 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:526399 quic::QuicStreamOffset server_header_offset = 0;
rch56ec40a2017-06-23 14:48:446400 // Server promise for: https://mail.example.org/pushed.jpg
Zhongyi Shi32f2fd02018-04-16 18:23:436401 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336402 ASYNC, ConstructServerPushPromisePacket(
6403 1, GetNthClientInitiatedBidirectionalStreamId(0),
6404 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6405 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6406 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:576407 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266408 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336409 mock_quic_data.AddWrite(SYNCHRONOUS,
6410 ConstructClientPriorityPacket(
6411 client_packet_number++, false,
6412 GetNthServerInitiatedUnidirectionalStreamId(0),
6413 GetNthClientInitiatedBidirectionalStreamId(0),
6414 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576415 }
rch56ec40a2017-06-23 14:48:446416 // Response headers for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436417 mock_quic_data.AddRead(
6418 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336419 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436420 GetResponseHeaders("200 OK"), &server_header_offset));
rch56ec40a2017-06-23 14:48:446421 // Client ACKs the response headers.
Yixin Wangb470bc882018-02-15 18:43:576422 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436423 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
rch56ec40a2017-06-23 14:48:446424 // Response body for first request.
Zhongyi Shi32f2fd02018-04-16 18:23:436425 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336426 ASYNC, ConstructServerDataPacket(
6427 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6428 0, "hello!"));
rch56ec40a2017-06-23 14:48:446429 // Write error for the third request.
6430 mock_quic_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
6431 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6432 mock_quic_data.AddRead(ASYNC, 0); // EOF
6433 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6434
6435 CreateSession();
6436
6437 // Send a request which triggers a push promise from the server.
6438 SendRequestAndExpectQuicResponse("hello!");
6439
6440 // Start a push transaction that will be cancelled after the connection
6441 // is closed, but before the callback is executed.
6442 request_.url = GURL("https://mail.example.org/pushed.jpg");
Jeremy Roman0579ed62017-08-29 15:56:196443 auto trans2 = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
rch56ec40a2017-06-23 14:48:446444 session_.get());
6445 TestCompletionCallback callback2;
6446 int rv = trans2->Start(&request_, callback2.callback(), net_log_.bound());
6447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6448 base::RunLoop().RunUntilIdle();
6449
6450 // Cause the connection to close on a write error.
6451 HttpRequestInfo request3;
6452 request3.method = "GET";
6453 request3.url = GURL("https://mail.example.org/");
6454 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106455 request3.traffic_annotation =
6456 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rch56ec40a2017-06-23 14:48:446457 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session_.get());
6458 TestCompletionCallback callback3;
6459 EXPECT_THAT(trans3.Start(&request3, callback3.callback(), net_log_.bound()),
6460 IsError(ERR_IO_PENDING));
6461
6462 base::RunLoop().RunUntilIdle();
6463
6464 // When |trans2| is destroyed, the underlying stream will be closed.
6465 EXPECT_FALSE(callback2.have_result());
6466 trans2 = nullptr;
6467
6468 EXPECT_THAT(callback3.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
6469}
6470
ckrasicda193a82016-07-09 00:39:366471TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
mmenke6ddfbea2017-05-31 21:48:416472 session_params_.origins_to_force_quic_on.insert(
ckrasicda193a82016-07-09 00:39:366473 HostPortPair::FromString("mail.example.org:443"));
6474
6475 MockQuicData mock_quic_data;
6476
Ryan Hamilton8d9ee76e2018-05-29 23:52:526477 quic::QuicStreamOffset offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:436478 mock_quic_data.AddWrite(SYNCHRONOUS,
6479 ConstructInitialSettingsPacket(1, &offset));
ckrasicda193a82016-07-09 00:39:366480
Zhongyi Shi32f2fd02018-04-16 18:23:436481 mock_quic_data.AddWrite(
6482 SYNCHRONOUS,
6483 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yang32c5a112018-12-10 20:06:336484 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
6485 DEFAULT_PRIORITY, GetRequestHeaders("POST", "https", "/"), 0, &offset,
6486 nullptr, {"1"}));
ckrasicda193a82016-07-09 00:39:366487
Zhongyi Shi32f2fd02018-04-16 18:23:436488 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336489 ASYNC, ConstructServerResponseHeadersPacket(
6490 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6491 GetResponseHeaders("200 OK")));
6492
6493 mock_quic_data.AddRead(
6494 ASYNC, ConstructServerDataPacket(
6495 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6496 0, "hello!"));
ckrasicda193a82016-07-09 00:39:366497
Zhongyi Shi32f2fd02018-04-16 18:23:436498 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
ckrasicda193a82016-07-09 00:39:366499
6500 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6501 mock_quic_data.AddRead(ASYNC, 0); // EOF
6502 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6503
6504 // The non-alternate protocol job needs to hang in order to guarantee that
6505 // the alternate-protocol job will "win".
6506 AddHangingNonAlternateProtocolSocketData();
6507
6508 CreateSession();
6509 request_.method = "POST";
6510 ChunkedUploadDataStream upload_data(0);
6511 upload_data.AppendData("1", 1, true);
6512
6513 request_.upload_data_stream = &upload_data;
6514
6515 SendRequestAndExpectQuicResponse("hello!");
6516}
6517
allada71b2efb2016-09-09 04:57:486518class QuicURLRequestContext : public URLRequestContext {
6519 public:
6520 QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
6521 MockClientSocketFactory* socket_factory)
6522 : storage_(this) {
6523 socket_factory_ = socket_factory;
Ryan Sleevib8449e02018-07-15 04:31:076524 storage_.set_host_resolver(std::make_unique<MockHostResolver>());
Bence Béky8f9d7d3952017-10-09 19:58:046525 storage_.set_cert_verifier(std::make_unique<MockCertVerifier>());
allada71b2efb2016-09-09 04:57:486526 storage_.set_transport_security_state(
Bence Béky8f9d7d3952017-10-09 19:58:046527 std::make_unique<TransportSecurityState>());
Lily Houghton8c2f97d2018-01-22 05:06:596528 storage_.set_proxy_resolution_service(
6529 ProxyResolutionService::CreateDirect());
Ryan Sleevib8449e02018-07-15 04:31:076530 storage_.set_ssl_config_service(
6531 std::make_unique<SSLConfigServiceDefaults>());
allada71b2efb2016-09-09 04:57:486532 storage_.set_http_auth_handler_factory(
6533 HttpAuthHandlerFactory::CreateDefault(host_resolver()));
6534 storage_.set_http_server_properties(
Ryan Sleevib8449e02018-07-15 04:31:076535 std::make_unique<HttpServerPropertiesImpl>());
Bence Béky8f9d7d3952017-10-09 19:58:046536 storage_.set_job_factory(std::make_unique<URLRequestJobFactoryImpl>());
allada71b2efb2016-09-09 04:57:486537 storage_.set_http_network_session(std::move(session));
Bence Béky8f9d7d3952017-10-09 19:58:046538 storage_.set_http_transaction_factory(std::make_unique<HttpCache>(
6539 storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0),
6540 false));
allada71b2efb2016-09-09 04:57:486541 }
6542
6543 ~QuicURLRequestContext() override { AssertNoURLRequests(); }
6544
6545 MockClientSocketFactory& socket_factory() { return *socket_factory_; }
6546
6547 private:
6548 MockClientSocketFactory* socket_factory_;
6549 URLRequestContextStorage storage_;
6550};
6551
6552TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
mmenke6ddfbea2017-05-31 21:48:416553 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486554 HostPortPair::FromString("mail.example.org:443"));
6555
6556 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526557 quic::QuicStreamOffset header_stream_offset = 0;
rch5cb522462017-04-25 20:18:366558 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436559 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136560 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486561 headers["user-agent"] = "";
6562 headers["accept-encoding"] = "gzip, deflate";
Fan Yang32c5a112018-12-10 20:06:336563 mock_quic_data.AddWrite(
6564 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
6565 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6566 true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486567
Ryan Hamilton8d9ee76e2018-05-29 23:52:526568 quic::QuicStreamOffset expected_raw_header_response_size = 0;
Fan Yang32c5a112018-12-10 20:06:336569 mock_quic_data.AddRead(
6570 ASYNC,
6571 ConstructServerResponseHeadersPacket(
6572 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6573 GetResponseHeaders("200 OK"), &expected_raw_header_response_size));
allada71b2efb2016-09-09 04:57:486574
ckrasicbf2f59c2017-05-04 23:54:366575 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336576 ASYNC, ConstructServerDataPacket(
6577 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6578 0, "Main Resource Data"));
Zhongyi Shi32f2fd02018-04-16 18:23:436579 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486580
6581 mock_quic_data.AddRead(ASYNC, 0); // EOF
6582
6583 CreateSession();
6584
6585 TestDelegate delegate;
6586 QuicURLRequestContext quic_url_request_context(std::move(session_),
6587 &socket_factory_);
6588
6589 mock_quic_data.AddSocketDataToFactory(
6590 &quic_url_request_context.socket_factory());
6591 TestNetworkDelegate network_delegate;
6592 quic_url_request_context.set_network_delegate(&network_delegate);
6593
6594 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296595 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6596 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486597 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6598 &ssl_data_);
6599
6600 request->Start();
Wez2a31b222018-06-07 22:07:156601 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486602
6603 EXPECT_LT(0, request->GetTotalSentBytes());
6604 EXPECT_LT(0, request->GetTotalReceivedBytes());
6605 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6606 request->GetTotalSentBytes());
6607 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6608 request->GetTotalReceivedBytes());
6609 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6610 request->raw_header_size());
Wez0e717112018-06-18 23:09:226611
6612 // Pump the message loop to allow all data to be consumed.
6613 base::RunLoop().RunUntilIdle();
6614
allada71b2efb2016-09-09 04:57:486615 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6616 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6617}
6618
6619TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
mmenke6ddfbea2017-05-31 21:48:416620 session_params_.origins_to_force_quic_on.insert(
allada71b2efb2016-09-09 04:57:486621 HostPortPair::FromString("mail.example.org:443"));
6622
6623 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526624 quic::QuicStreamOffset header_stream_offset = 0;
6625 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:436626 mock_quic_data.AddWrite(
6627 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
6628 &header_stream_offset));
Ryan Hamilton0239aac2018-05-19 00:03:136629 spdy::SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
allada71b2efb2016-09-09 04:57:486630 headers["user-agent"] = "";
6631 headers["accept-encoding"] = "gzip, deflate";
Zhongyi Shi32f2fd02018-04-16 18:23:436632 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336633 SYNCHRONOUS,
6634 ConstructClientRequestHeadersPacket(
6635 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
6636 true, true, std::move(headers), &header_stream_offset));
allada71b2efb2016-09-09 04:57:486637
Ryan Hamilton8d9ee76e2018-05-29 23:52:526638 quic::QuicStreamOffset server_header_offset = 0;
6639 quic::QuicStreamOffset expected_raw_header_response_size = 0;
allada71b2efb2016-09-09 04:57:486640
Zhongyi Shi32f2fd02018-04-16 18:23:436641 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336642 ASYNC, ConstructServerPushPromisePacket(
6643 1, GetNthClientInitiatedBidirectionalStreamId(0),
6644 GetNthServerInitiatedUnidirectionalStreamId(0), false,
6645 GetRequestHeaders("GET", "https", "/pushed.jpg"),
6646 &server_header_offset, &server_maker_));
allada71b2efb2016-09-09 04:57:486647
Yixin Wangb470bc882018-02-15 18:43:576648 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:266649 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:336650 mock_quic_data.AddWrite(SYNCHRONOUS,
6651 ConstructClientPriorityPacket(
6652 client_packet_number++, false,
6653 GetNthServerInitiatedUnidirectionalStreamId(0),
6654 GetNthClientInitiatedBidirectionalStreamId(0),
6655 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:576656 }
6657
allada71b2efb2016-09-09 04:57:486658 expected_raw_header_response_size = server_header_offset;
Zhongyi Shi32f2fd02018-04-16 18:23:436659 mock_quic_data.AddRead(
6660 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336661 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:436662 GetResponseHeaders("200 OK"), &server_header_offset));
allada71b2efb2016-09-09 04:57:486663 expected_raw_header_response_size =
6664 server_header_offset - expected_raw_header_response_size;
6665
Yixin Wangb470bc882018-02-15 18:43:576666 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436667 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
allada71b2efb2016-09-09 04:57:486668
ckrasicbf2f59c2017-05-04 23:54:366669 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:436670 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336671 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
6672 false, GetResponseHeaders("200 OK"), &server_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436673 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336674 ASYNC, ConstructServerDataPacket(
6675 4, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
6676 0, "Pushed Resource Data"));
allada71b2efb2016-09-09 04:57:486677
Yixin Wangb470bc882018-02-15 18:43:576678 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436679 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
ckrasicbf2f59c2017-05-04 23:54:366680 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336681 ASYNC, ConstructServerDataPacket(
6682 5, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6683 0, "Main Resource Data"));
allada71b2efb2016-09-09 04:57:486684
Zhongyi Shi32f2fd02018-04-16 18:23:436685 mock_quic_data.AddRead(ASYNC, ConstructServerConnectionClosePacket(6));
allada71b2efb2016-09-09 04:57:486686
6687 CreateSession();
6688
6689 TestDelegate delegate;
6690 QuicURLRequestContext quic_url_request_context(std::move(session_),
6691 &socket_factory_);
6692
6693 mock_quic_data.AddSocketDataToFactory(
6694 &quic_url_request_context.socket_factory());
6695 TestNetworkDelegate network_delegate;
6696 quic_url_request_context.set_network_delegate(&network_delegate);
6697
6698 std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
rhalavati9ebaba7e2017-04-27 06:16:296699 GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate,
6700 TRAFFIC_ANNOTATION_FOR_TESTS));
allada71b2efb2016-09-09 04:57:486701 quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
6702 &ssl_data_);
6703
6704 request->Start();
Wez2a31b222018-06-07 22:07:156705 delegate.RunUntilComplete();
allada71b2efb2016-09-09 04:57:486706
6707 EXPECT_LT(0, request->GetTotalSentBytes());
6708 EXPECT_LT(0, request->GetTotalReceivedBytes());
6709 EXPECT_EQ(network_delegate.total_network_bytes_sent(),
6710 request->GetTotalSentBytes());
6711 EXPECT_EQ(network_delegate.total_network_bytes_received(),
6712 request->GetTotalReceivedBytes());
6713 EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
6714 request->raw_header_size());
Wez0e717112018-06-18 23:09:226715
6716 // Pump the message loop to allow all data to be consumed.
6717 base::RunLoop().RunUntilIdle();
6718
allada71b2efb2016-09-09 04:57:486719 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
6720 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
6721}
6722
Yixin Wang10f477ed2017-11-21 04:20:206723TEST_P(QuicNetworkTransactionTest, HostInWhitelist) {
6724 session_params_.quic_host_whitelist.insert("mail.example.org");
6725
6726 MockRead http_reads[] = {
6727 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6728 MockRead("hello world"),
6729 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6730 MockRead(ASYNC, OK)};
6731
Ryan Sleevib8d7ea02018-05-07 20:01:016732 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206733 socket_factory_.AddSocketDataProvider(&http_data);
6734 AddCertificate(&ssl_data_);
6735 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6736
6737 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:526738 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang10f477ed2017-11-21 04:20:206739 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436740 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6741 mock_quic_data.AddWrite(
6742 SYNCHRONOUS,
6743 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:336744 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:436745 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436746 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:336747 ASYNC, ConstructServerResponseHeadersPacket(
6748 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
6749 GetResponseHeaders("200 OK")));
6750 mock_quic_data.AddRead(
6751 ASYNC, ConstructServerDataPacket(
6752 2, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
6753 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:436754 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1));
Yixin Wang10f477ed2017-11-21 04:20:206755 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
6756 mock_quic_data.AddRead(ASYNC, 0); // EOF
6757
6758 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
6759
6760 AddHangingNonAlternateProtocolSocketData();
6761 CreateSession();
6762
6763 SendRequestAndExpectHttpResponse("hello world");
6764 SendRequestAndExpectQuicResponse("hello!");
6765}
6766
6767TEST_P(QuicNetworkTransactionTest, HostNotInWhitelist) {
6768 session_params_.quic_host_whitelist.insert("mail.example.com");
6769
6770 MockRead http_reads[] = {
6771 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(kQuicAlternativeServiceHeader),
6772 MockRead("hello world"),
6773 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
6774 MockRead(ASYNC, OK)};
6775
Ryan Sleevib8d7ea02018-05-07 20:01:016776 StaticSocketDataProvider http_data(http_reads, base::span<MockWrite>());
Yixin Wang10f477ed2017-11-21 04:20:206777 socket_factory_.AddSocketDataProvider(&http_data);
6778 AddCertificate(&ssl_data_);
6779 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6780 socket_factory_.AddSocketDataProvider(&http_data);
6781 AddCertificate(&ssl_data_);
6782 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6783
6784 AddHangingNonAlternateProtocolSocketData();
6785 CreateSession();
6786
6787 SendRequestAndExpectHttpResponse("hello world");
6788 SendRequestAndExpectHttpResponse("hello world");
6789}
6790
bnc359ed2a2016-04-29 20:43:456791class QuicNetworkTransactionWithDestinationTest
6792 : public PlatformTest,
Bence Béky98447b12018-05-08 03:14:016793 public ::testing::WithParamInterface<PoolingTestParams>,
6794 public WithScopedTaskEnvironment {
bnc359ed2a2016-04-29 20:43:456795 protected:
6796 QuicNetworkTransactionWithDestinationTest()
rchbf4c26d2017-04-16 23:17:556797 : version_(GetParam().version),
Yixin Wang079ad542018-01-11 04:06:056798 client_headers_include_h2_stream_dependency_(
6799 GetParam().client_headers_include_h2_stream_dependency),
Ryan Hamilton8d9ee76e2018-05-29 23:52:526800 supported_versions_(quic::test::SupportedTransportVersions(version_)),
bnc359ed2a2016-04-29 20:43:456801 destination_type_(GetParam().destination_type),
6802 cert_transparency_verifier_(new MultiLogCTVerifier()),
6803 ssl_config_service_(new SSLConfigServiceDefaults),
Lily Houghton8c2f97d2018-01-22 05:06:596804 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
bnc359ed2a2016-04-29 20:43:456805 auth_handler_factory_(
6806 HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
6807 random_generator_(0),
6808 ssl_data_(ASYNC, OK) {}
6809
6810 void SetUp() override {
6811 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556812 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456813
mmenke6ddfbea2017-05-31 21:48:416814 HttpNetworkSession::Params session_params;
6815 session_params.enable_quic = true;
Ryan Hamiltonc84473f2017-11-23 03:18:346816 session_params.quic_allow_remote_alt_svc = true;
zhongyi86838d52017-06-30 01:19:446817 session_params.quic_supported_versions = supported_versions_;
Yixin Wang079ad542018-01-11 04:06:056818 session_params.quic_headers_include_h2_stream_dependency =
6819 client_headers_include_h2_stream_dependency_;
mmenke6ddfbea2017-05-31 21:48:416820
6821 HttpNetworkSession::Context session_context;
bnc359ed2a2016-04-29 20:43:456822
Ryan Hamilton8d9ee76e2018-05-29 23:52:526823 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
mmenke6ddfbea2017-05-31 21:48:416824 session_context.quic_clock = &clock_;
bnc359ed2a2016-04-29 20:43:456825
6826 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:276827 MockCryptoClientStream::CONFIRM_HANDSHAKE);
mmenke6ddfbea2017-05-31 21:48:416828 session_context.quic_crypto_client_stream_factory =
6829 &crypto_client_stream_factory_;
bnc359ed2a2016-04-29 20:43:456830
mmenke6ddfbea2017-05-31 21:48:416831 session_context.quic_random = &random_generator_;
6832 session_context.client_socket_factory = &socket_factory_;
6833 session_context.host_resolver = &host_resolver_;
6834 session_context.cert_verifier = &cert_verifier_;
6835 session_context.transport_security_state = &transport_security_state_;
6836 session_context.cert_transparency_verifier =
6837 cert_transparency_verifier_.get();
6838 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
6839 session_context.socket_performance_watcher_factory =
bnc359ed2a2016-04-29 20:43:456840 &test_socket_performance_watcher_factory_;
mmenke6ddfbea2017-05-31 21:48:416841 session_context.ssl_config_service = ssl_config_service_.get();
Lily Houghton8c2f97d2018-01-22 05:06:596842 session_context.proxy_resolution_service = proxy_resolution_service_.get();
mmenke6ddfbea2017-05-31 21:48:416843 session_context.http_auth_handler_factory = auth_handler_factory_.get();
6844 session_context.http_server_properties = &http_server_properties_;
bnc359ed2a2016-04-29 20:43:456845
mmenke6ddfbea2017-05-31 21:48:416846 session_.reset(new HttpNetworkSession(session_params, session_context));
bnc359ed2a2016-04-29 20:43:456847 session_->quic_stream_factory()->set_require_confirmation(true);
bnc359ed2a2016-04-29 20:43:456848 }
6849
6850 void TearDown() override {
6851 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
6852 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556853 base::RunLoop().RunUntilIdle();
bnc359ed2a2016-04-29 20:43:456854 PlatformTest::TearDown();
6855 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:556856 base::RunLoop().RunUntilIdle();
bnc525e175a2016-06-20 12:36:406857 session_.reset();
bnc359ed2a2016-04-29 20:43:456858 }
6859
zhongyie537a002017-06-27 16:48:216860 void SetQuicAlternativeService(const std::string& origin) {
bnc359ed2a2016-04-29 20:43:456861 HostPortPair destination;
6862 switch (destination_type_) {
6863 case SAME_AS_FIRST:
6864 destination = HostPortPair(origin1_, 443);
6865 break;
6866 case SAME_AS_SECOND:
6867 destination = HostPortPair(origin2_, 443);
6868 break;
6869 case DIFFERENT:
6870 destination = HostPortPair(kDifferentHostname, 443);
6871 break;
6872 }
bnc3472afd2016-11-17 15:27:216873 AlternativeService alternative_service(kProtoQUIC, destination);
bnc359ed2a2016-04-29 20:43:456874 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:216875 http_server_properties_.SetQuicAlternativeService(
bnc359ed2a2016-04-29 20:43:456876 url::SchemeHostPort("https", origin, 443), alternative_service,
zhongyi86838d52017-06-30 01:19:446877 expiration, supported_versions_);
bnc359ed2a2016-04-29 20:43:456878 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:526879 std::unique_ptr<quic::QuicEncryptedPacket>
6880 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6881 quic::QuicStreamId stream_id,
6882 bool should_include_version,
6883 quic::QuicStreamOffset* offset,
6884 QuicTestPacketMaker* maker) {
Yixin Wang7a3f1b8d2018-01-17 21:40:486885 return ConstructClientRequestHeadersPacket(
6886 packet_number, stream_id, should_include_version, 0, offset, maker);
6887 }
bnc359ed2a2016-04-29 20:43:456888
Ryan Hamilton8d9ee76e2018-05-29 23:52:526889 std::unique_ptr<quic::QuicEncryptedPacket>
6890 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6891 quic::QuicStreamId stream_id,
6892 bool should_include_version,
6893 quic::QuicStreamId parent_stream_id,
6894 quic::QuicStreamOffset* offset,
6895 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136896 spdy::SpdyPriority priority =
bnc359ed2a2016-04-29 20:43:456897 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
Ryan Hamilton0239aac2018-05-19 00:03:136898 spdy::SpdyHeaderBlock headers(
6899 maker->GetRequestHeaders("GET", "https", "/"));
bnc359ed2a2016-04-29 20:43:456900 return maker->MakeRequestHeadersPacketWithOffsetTracking(
6901 packet_number, stream_id, should_include_version, true, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:486902 std::move(headers), parent_stream_id, offset);
bnc359ed2a2016-04-29 20:43:456903 }
6904
Ryan Hamilton8d9ee76e2018-05-29 23:52:526905 std::unique_ptr<quic::QuicEncryptedPacket>
6906 ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
6907 quic::QuicStreamId stream_id,
6908 bool should_include_version,
6909 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586910 return ConstructClientRequestHeadersPacket(
bnc359ed2a2016-04-29 20:43:456911 packet_number, stream_id, should_include_version, nullptr, maker);
6912 }
6913
Ryan Hamilton8d9ee76e2018-05-29 23:52:526914 std::unique_ptr<quic::QuicEncryptedPacket>
6915 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6916 quic::QuicStreamId stream_id,
6917 quic::QuicStreamOffset* offset,
6918 QuicTestPacketMaker* maker) {
Ryan Hamilton0239aac2018-05-19 00:03:136919 spdy::SpdyHeaderBlock headers(maker->GetResponseHeaders("200 OK"));
bnc359ed2a2016-04-29 20:43:456920 return maker->MakeResponseHeadersPacketWithOffsetTracking(
bnc086b39e12016-06-24 13:05:266921 packet_number, stream_id, false, false, std::move(headers), offset);
bnc359ed2a2016-04-29 20:43:456922 }
6923
Ryan Hamilton8d9ee76e2018-05-29 23:52:526924 std::unique_ptr<quic::QuicEncryptedPacket>
6925 ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
6926 quic::QuicStreamId stream_id,
6927 QuicTestPacketMaker* maker) {
alyssar2adf3ac2016-05-03 17:12:586928 return ConstructServerResponseHeadersPacket(packet_number, stream_id,
6929 nullptr, maker);
bnc359ed2a2016-04-29 20:43:456930 }
6931
Ryan Hamilton8d9ee76e2018-05-29 23:52:526932 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
6933 quic::QuicPacketNumber packet_number,
6934 quic::QuicStreamId stream_id,
bnc359ed2a2016-04-29 20:43:456935 QuicTestPacketMaker* maker) {
6936 return maker->MakeDataPacket(packet_number, stream_id, false, true, 0,
6937 "hello");
6938 }
6939
Ryan Hamilton8d9ee76e2018-05-29 23:52:526940 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
6941 quic::QuicPacketNumber packet_number,
6942 quic::QuicPacketNumber largest_received,
6943 quic::QuicPacketNumber smallest_received,
6944 quic::QuicPacketNumber least_unacked,
bnc359ed2a2016-04-29 20:43:456945 QuicTestPacketMaker* maker) {
6946 return maker->MakeAckPacket(packet_number, largest_received,
wangyix6444ffe2017-04-25 17:49:496947 smallest_received, least_unacked, true);
bnc359ed2a2016-04-29 20:43:456948 }
6949
Ryan Hamilton8d9ee76e2018-05-29 23:52:526950 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
6951 quic::QuicPacketNumber packet_number,
6952 quic::QuicStreamOffset* offset,
fayang3bcb8b502016-12-07 21:44:376953 QuicTestPacketMaker* maker) {
rch5cb522462017-04-25 20:18:366954 return maker->MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:376955 }
6956
bnc359ed2a2016-04-29 20:43:456957 void AddRefusedSocketData() {
6958 std::unique_ptr<StaticSocketDataProvider> refused_data(
6959 new StaticSocketDataProvider());
6960 MockConnect refused_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
6961 refused_data->set_connect_data(refused_connect);
6962 socket_factory_.AddSocketDataProvider(refused_data.get());
6963 static_socket_data_provider_vector_.push_back(std::move(refused_data));
6964 }
6965
6966 void AddHangingSocketData() {
6967 std::unique_ptr<StaticSocketDataProvider> hanging_data(
6968 new StaticSocketDataProvider());
6969 MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
6970 hanging_data->set_connect_data(hanging_connect);
6971 socket_factory_.AddSocketDataProvider(hanging_data.get());
6972 static_socket_data_provider_vector_.push_back(std::move(hanging_data));
6973 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
6974 }
6975
6976 bool AllDataConsumed() {
6977 for (const auto& socket_data_ptr : static_socket_data_provider_vector_) {
6978 if (!socket_data_ptr->AllReadDataConsumed() ||
6979 !socket_data_ptr->AllWriteDataConsumed()) {
6980 return false;
6981 }
6982 }
6983 return true;
6984 }
6985
6986 void SendRequestAndExpectQuicResponse(const std::string& host) {
6987 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
6988 HttpRequestInfo request;
6989 std::string url("https://");
6990 url.append(host);
6991 request.url = GURL(url);
6992 request.load_flags = 0;
6993 request.method = "GET";
Ramin Halavatib5e433e62018-02-07 07:41:106994 request.traffic_annotation =
6995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:456996 TestCompletionCallback callback;
6997 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:016998 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc359ed2a2016-04-29 20:43:456999
7000 std::string response_data;
robpercival214763f2016-07-01 23:27:017001 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc359ed2a2016-04-29 20:43:457002 EXPECT_EQ("hello", response_data);
7003
7004 const HttpResponseInfo* response = trans.GetResponseInfo();
7005 ASSERT_TRUE(response != nullptr);
7006 ASSERT_TRUE(response->headers.get() != nullptr);
7007 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7008 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:527009 EXPECT_TRUE(response->was_alpn_negotiated);
bnc90be5dd782016-11-09 16:28:447010 EXPECT_EQ(QuicHttpStream::ConnectionInfoFromQuicVersion(version_),
bnc359ed2a2016-04-29 20:43:457011 response->connection_info);
7012 EXPECT_EQ(443, response->socket_address.port());
7013 }
7014
Fan Yang32c5a112018-12-10 20:06:337015 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
7016 return quic::test::GetNthClientInitiatedBidirectionalStreamId(version_, n);
ckrasicbf2f59c2017-05-04 23:54:367017 }
7018
Ryan Hamilton8d9ee76e2018-05-29 23:52:527019 quic::MockClock clock_;
7020 const quic::QuicTransportVersion version_;
Yixin Wang079ad542018-01-11 04:06:057021 const bool client_headers_include_h2_stream_dependency_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527022 quic::QuicTransportVersionVector supported_versions_;
bnc359ed2a2016-04-29 20:43:457023 DestinationType destination_type_;
7024 std::string origin1_;
7025 std::string origin2_;
7026 std::unique_ptr<HttpNetworkSession> session_;
7027 MockClientSocketFactory socket_factory_;
7028 MockHostResolver host_resolver_;
7029 MockCertVerifier cert_verifier_;
7030 TransportSecurityState transport_security_state_;
7031 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:237032 DefaultCTPolicyEnforcer ct_policy_enforcer_;
bnc359ed2a2016-04-29 20:43:457033 TestSocketPerformanceWatcherFactory test_socket_performance_watcher_factory_;
Ryan Sleevib8449e02018-07-15 04:31:077034 std::unique_ptr<SSLConfigServiceDefaults> ssl_config_service_;
Lily Houghton8c2f97d2018-01-22 05:06:597035 std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
bnc359ed2a2016-04-29 20:43:457036 std::unique_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527037 quic::test::MockRandom random_generator_;
bnc359ed2a2016-04-29 20:43:457038 HttpServerPropertiesImpl http_server_properties_;
7039 BoundTestNetLog net_log_;
7040 MockCryptoClientStreamFactory crypto_client_stream_factory_;
7041 std::vector<std::unique_ptr<StaticSocketDataProvider>>
7042 static_socket_data_provider_vector_;
7043 SSLSocketDataProvider ssl_data_;
7044};
7045
Bence Békyce380cb2018-04-26 23:39:557046INSTANTIATE_TEST_CASE_P(VersionIncludeStreamDependencySequence,
bnc359ed2a2016-04-29 20:43:457047 QuicNetworkTransactionWithDestinationTest,
7048 ::testing::ValuesIn(GetPoolingTestParams()));
7049
7050// A single QUIC request fails because the certificate does not match the origin
7051// hostname, regardless of whether it matches the alternative service hostname.
7052TEST_P(QuicNetworkTransactionWithDestinationTest, InvalidCertificate) {
7053 if (destination_type_ == DIFFERENT)
7054 return;
7055
7056 GURL url("https://mail.example.com/");
7057 origin1_ = url.host();
7058
7059 // Not used for requests, but this provides a test case where the certificate
7060 // is valid for the hostname of the alternative service.
7061 origin2_ = "mail.example.org";
7062
zhongyie537a002017-06-27 16:48:217063 SetQuicAlternativeService(origin1_);
bnc359ed2a2016-04-29 20:43:457064
7065 scoped_refptr<X509Certificate> cert(
7066 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247067 ASSERT_FALSE(cert->VerifyNameMatch(origin1_));
7068 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
bnc359ed2a2016-04-29 20:43:457069
7070 ProofVerifyDetailsChromium verify_details;
7071 verify_details.cert_verify_result.verified_cert = cert;
7072 verify_details.cert_verify_result.is_issued_by_known_root = true;
7073 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7074
7075 MockQuicData mock_quic_data;
7076 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
7077 mock_quic_data.AddRead(ASYNC, 0);
7078
7079 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7080
7081 AddRefusedSocketData();
7082
7083 HttpRequestInfo request;
7084 request.url = url;
Ramin Halavatib5e433e62018-02-07 07:41:107085 request.traffic_annotation =
7086 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc359ed2a2016-04-29 20:43:457087
7088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7089 TestCompletionCallback callback;
7090 int rv = trans.Start(&request, callback.callback(), net_log_.bound());
robpercival214763f2016-07-01 23:27:017091 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc359ed2a2016-04-29 20:43:457092
7093 EXPECT_TRUE(AllDataConsumed());
7094}
7095
7096// First request opens QUIC session to alternative service. Second request
7097// pools to it, because destination matches and certificate is valid, even
Ryan Hamilton8d9ee76e2018-05-29 23:52:527098// though quic::QuicServerId is different.
bnc359ed2a2016-04-29 20:43:457099TEST_P(QuicNetworkTransactionWithDestinationTest, PoolIfCertificateValid) {
7100 origin1_ = "mail.example.org";
7101 origin2_ = "news.example.org";
7102
zhongyie537a002017-06-27 16:48:217103 SetQuicAlternativeService(origin1_);
7104 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457105
7106 scoped_refptr<X509Certificate> cert(
7107 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247108 ASSERT_TRUE(cert->VerifyNameMatch(origin1_));
7109 ASSERT_TRUE(cert->VerifyNameMatch(origin2_));
7110 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457111
7112 ProofVerifyDetailsChromium verify_details;
7113 verify_details.cert_verify_result.verified_cert = cert;
7114 verify_details.cert_verify_result.is_issued_by_known_root = true;
7115 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7116
Yixin Wang079ad542018-01-11 04:06:057117 QuicTestPacketMaker client_maker(
Fan Yang32c5a112018-12-10 20:06:337118 version_, quic::EmptyQuicConnectionId(), &clock_, origin1_,
7119 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057120 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337121 QuicTestPacketMaker server_maker(version_, quic::EmptyQuicConnectionId(),
7122 &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527123 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457124
Ryan Hamilton8d9ee76e2018-05-29 23:52:527125 quic::QuicStreamOffset request_header_offset(0);
7126 quic::QuicStreamOffset response_header_offset(0);
bnc359ed2a2016-04-29 20:43:457127
7128 MockQuicData mock_quic_data;
Yixin Wang079ad542018-01-11 04:06:057129 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437130 SYNCHRONOUS,
Yixin Wang079ad542018-01-11 04:06:057131 ConstructInitialSettingsPacket(1, &request_header_offset, &client_maker));
Fan Yang32c5a112018-12-10 20:06:337132 mock_quic_data.AddWrite(
7133 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7134 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7135 &request_header_offset, &client_maker));
7136 mock_quic_data.AddRead(ASYNC,
7137 ConstructServerResponseHeadersPacket(
7138 1, GetNthClientInitiatedBidirectionalStreamId(0),
7139 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437140 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337141 ASYNC,
7142 ConstructServerDataPacket(
7143 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437144 mock_quic_data.AddWrite(SYNCHRONOUS,
7145 ConstructClientAckPacket(3, 2, 1, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457146
Yixin Wang079ad542018-01-11 04:06:057147 client_maker.set_hostname(origin2_);
7148 server_maker.set_hostname(origin2_);
bnc359ed2a2016-04-29 20:43:457149
Zhongyi Shi32f2fd02018-04-16 18:23:437150 mock_quic_data.AddWrite(
7151 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337152 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
7153 GetNthClientInitiatedBidirectionalStreamId(0),
7154 &request_header_offset, &client_maker));
7155 mock_quic_data.AddRead(ASYNC,
7156 ConstructServerResponseHeadersPacket(
7157 3, GetNthClientInitiatedBidirectionalStreamId(1),
7158 &response_header_offset, &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437159 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337160 ASYNC,
7161 ConstructServerDataPacket(
7162 4, GetNthClientInitiatedBidirectionalStreamId(1), &server_maker));
Zhongyi Shi32f2fd02018-04-16 18:23:437163 mock_quic_data.AddWrite(SYNCHRONOUS,
7164 ConstructClientAckPacket(5, 4, 3, 1, &client_maker));
bnc359ed2a2016-04-29 20:43:457165 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7166 mock_quic_data.AddRead(ASYNC, 0); // EOF
7167
7168 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7169
7170 AddHangingSocketData();
7171 AddHangingSocketData();
7172
Fan Yangc9e00dc2018-10-09 14:17:567173 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(&clock_));
7174 QuicStreamFactoryPeer::SetAlarmFactory(
7175 session_->quic_stream_factory(),
7176 std::make_unique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
7177 &clock_));
7178
bnc359ed2a2016-04-29 20:43:457179 SendRequestAndExpectQuicResponse(origin1_);
7180 SendRequestAndExpectQuicResponse(origin2_);
7181
7182 EXPECT_TRUE(AllDataConsumed());
7183}
7184
7185// First request opens QUIC session to alternative service. Second request does
7186// not pool to it, even though destination matches, because certificate is not
7187// valid. Instead, a new QUIC session is opened to the same destination with a
Ryan Hamilton8d9ee76e2018-05-29 23:52:527188// different quic::QuicServerId.
bnc359ed2a2016-04-29 20:43:457189TEST_P(QuicNetworkTransactionWithDestinationTest,
7190 DoNotPoolIfCertificateInvalid) {
7191 origin1_ = "news.example.org";
7192 origin2_ = "mail.example.com";
7193
zhongyie537a002017-06-27 16:48:217194 SetQuicAlternativeService(origin1_);
7195 SetQuicAlternativeService(origin2_);
bnc359ed2a2016-04-29 20:43:457196
7197 scoped_refptr<X509Certificate> cert1(
7198 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247199 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_));
7200 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_));
7201 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457202
7203 scoped_refptr<X509Certificate> cert2(
7204 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:247205 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_));
7206 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:457207
7208 ProofVerifyDetailsChromium verify_details1;
7209 verify_details1.cert_verify_result.verified_cert = cert1;
7210 verify_details1.cert_verify_result.is_issued_by_known_root = true;
7211 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
7212
7213 ProofVerifyDetailsChromium verify_details2;
7214 verify_details2.cert_verify_result.verified_cert = cert2;
7215 verify_details2.cert_verify_result.is_issued_by_known_root = true;
7216 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
7217
Yixin Wang079ad542018-01-11 04:06:057218 QuicTestPacketMaker client_maker1(
Fan Yang32c5a112018-12-10 20:06:337219 version_, quic::EmptyQuicConnectionId(), &clock_, origin1_,
7220 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057221 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337222 QuicTestPacketMaker server_maker1(version_, quic::EmptyQuicConnectionId(),
7223 &clock_, origin1_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527224 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457225
7226 MockQuicData mock_quic_data1;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527227 quic::QuicStreamOffset header_stream_offset1 = 0;
bnc359ed2a2016-04-29 20:43:457228 mock_quic_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437229 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset1,
7230 &client_maker1));
Fan Yang32c5a112018-12-10 20:06:337231 mock_quic_data1.AddWrite(
7232 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7233 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7234 &header_stream_offset1, &client_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437235 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337236 ASYNC,
7237 ConstructServerResponseHeadersPacket(
7238 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437239 mock_quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337240 ASYNC,
7241 ConstructServerDataPacket(
7242 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker1));
Zhongyi Shi32f2fd02018-04-16 18:23:437243 mock_quic_data1.AddWrite(
7244 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker1));
bnc359ed2a2016-04-29 20:43:457245 mock_quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7246 mock_quic_data1.AddRead(ASYNC, 0); // EOF
7247
7248 mock_quic_data1.AddSocketDataToFactory(&socket_factory_);
7249
Yixin Wang079ad542018-01-11 04:06:057250 QuicTestPacketMaker client_maker2(
Fan Yang32c5a112018-12-10 20:06:337251 version_, quic::EmptyQuicConnectionId(), &clock_, origin2_,
7252 quic::Perspective::IS_CLIENT,
Yixin Wang079ad542018-01-11 04:06:057253 client_headers_include_h2_stream_dependency_);
Fan Yang32c5a112018-12-10 20:06:337254 QuicTestPacketMaker server_maker2(version_, quic::EmptyQuicConnectionId(),
7255 &clock_, origin2_,
Ryan Hamilton8d9ee76e2018-05-29 23:52:527256 quic::Perspective::IS_SERVER, false);
bnc359ed2a2016-04-29 20:43:457257
7258 MockQuicData mock_quic_data2;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527259 quic::QuicStreamOffset header_stream_offset2 = 0;
bnc359ed2a2016-04-29 20:43:457260 mock_quic_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437261 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2,
7262 &client_maker2));
Fan Yang32c5a112018-12-10 20:06:337263 mock_quic_data2.AddWrite(
7264 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7265 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7266 &header_stream_offset2, &client_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437267 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337268 ASYNC,
7269 ConstructServerResponseHeadersPacket(
7270 1, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437271 mock_quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:337272 ASYNC,
7273 ConstructServerDataPacket(
7274 2, GetNthClientInitiatedBidirectionalStreamId(0), &server_maker2));
Zhongyi Shi32f2fd02018-04-16 18:23:437275 mock_quic_data2.AddWrite(
7276 SYNCHRONOUS, ConstructClientAckPacket(3, 2, 1, 1, &client_maker2));
bnc359ed2a2016-04-29 20:43:457277 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7278 mock_quic_data2.AddRead(ASYNC, 0); // EOF
7279
7280 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
7281
bnc359ed2a2016-04-29 20:43:457282 SendRequestAndExpectQuicResponse(origin1_);
7283 SendRequestAndExpectQuicResponse(origin2_);
7284
7285 EXPECT_TRUE(AllDataConsumed());
7286}
7287
ckrasicdee37572017-04-06 22:42:277288// crbug.com/705109 - this confirms that matching request with a body
7289// triggers a crash (pre-fix).
7290TEST_P(QuicNetworkTransactionTest, QuicServerPushMatchesRequestWithBody) {
mmenke6ddfbea2017-05-31 21:48:417291 session_params_.origins_to_force_quic_on.insert(
ckrasicdee37572017-04-06 22:42:277292 HostPortPair::FromString("mail.example.org:443"));
7293
7294 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527295 quic::QuicStreamOffset header_stream_offset = 0;
7296 quic::QuicPacketNumber client_packet_number = 1;
Zhongyi Shi32f2fd02018-04-16 18:23:437297 mock_quic_data.AddWrite(
7298 SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
7299 &header_stream_offset));
7300 mock_quic_data.AddWrite(
7301 SYNCHRONOUS,
7302 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337303 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(0),
7304 true, true, GetRequestHeaders("GET", "https", "/"),
7305 &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527306 quic::QuicStreamOffset server_header_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437307 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337308 ASYNC, ConstructServerPushPromisePacket(
7309 1, GetNthClientInitiatedBidirectionalStreamId(0),
7310 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7311 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7312 &server_header_offset, &server_maker_));
Yixin Wangb470bc882018-02-15 18:43:577313 if (client_headers_include_h2_stream_dependency_ &&
Zhongyi Shi7b4f22b2018-08-23 17:22:267314 version_ >= quic::QUIC_VERSION_43) {
Fan Yang32c5a112018-12-10 20:06:337315 mock_quic_data.AddWrite(SYNCHRONOUS,
7316 ConstructClientPriorityPacket(
7317 client_packet_number++, false,
7318 GetNthServerInitiatedUnidirectionalStreamId(0),
7319 GetNthClientInitiatedBidirectionalStreamId(0),
7320 DEFAULT_PRIORITY, &header_stream_offset));
Yixin Wangb470bc882018-02-15 18:43:577321 }
Zhongyi Shi32f2fd02018-04-16 18:23:437322 mock_quic_data.AddRead(
7323 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337324 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437325 GetResponseHeaders("200 OK"), &server_header_offset));
Yixin Wangb470bc882018-02-15 18:43:577326 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437327 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 2, 1, 1));
7328 mock_quic_data.AddRead(
7329 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337330 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7331 false, GetResponseHeaders("200 OK"), &server_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437332 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337333 ASYNC, ConstructServerDataPacket(
7334 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7335 0, "hello!"));
Yixin Wangb470bc882018-02-15 18:43:577336 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437337 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 4, 3, 1));
7338 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337339 ASYNC, ConstructServerDataPacket(
7340 5, GetNthServerInitiatedUnidirectionalStreamId(0), false, true,
7341 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:277342
7343 // Because the matching request has a body, we will see the push
7344 // stream get cancelled, and the matching request go out on the
7345 // wire.
Fan Yang32c5a112018-12-10 20:06:337346 mock_quic_data.AddWrite(SYNCHRONOUS,
7347 ConstructClientAckAndRstPacket(
7348 client_packet_number++,
7349 GetNthServerInitiatedUnidirectionalStreamId(0),
7350 quic::QUIC_STREAM_CANCELLED, 5, 5, 1));
ckrasicdee37572017-04-06 22:42:277351 const char kBody[] = "1";
Zhongyi Shi32f2fd02018-04-16 18:23:437352 mock_quic_data.AddWrite(
7353 SYNCHRONOUS,
7354 ConstructClientRequestHeadersAndDataFramesPacket(
Fan Yang32c5a112018-12-10 20:06:337355 client_packet_number++, GetNthClientInitiatedBidirectionalStreamId(1),
7356 false, true, DEFAULT_PRIORITY,
7357 GetRequestHeaders("GET", "https", "/pushed.jpg"),
7358 GetNthServerInitiatedUnidirectionalStreamId(0), &header_stream_offset,
7359 nullptr, {kBody}));
ckrasicdee37572017-04-06 22:42:277360
7361 // We see the same response as for the earlier pushed and cancelled
7362 // stream.
Zhongyi Shi32f2fd02018-04-16 18:23:437363 mock_quic_data.AddRead(
7364 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337365 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437366 GetResponseHeaders("200 OK"), &server_header_offset));
7367 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337368 ASYNC, ConstructServerDataPacket(
7369 7, GetNthClientInitiatedBidirectionalStreamId(1), false, true,
7370 0, "and hello!"));
ckrasicdee37572017-04-06 22:42:277371
Yixin Wangb470bc882018-02-15 18:43:577372 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437373 SYNCHRONOUS, ConstructClientAckPacket(client_packet_number++, 7, 6, 1));
ckrasicdee37572017-04-06 22:42:277374 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
7375 mock_quic_data.AddRead(ASYNC, 0); // EOF
7376 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7377
7378 // The non-alternate protocol job needs to hang in order to guarantee that
7379 // the alternate-protocol job will "win".
7380 AddHangingNonAlternateProtocolSocketData();
7381
7382 CreateSession();
7383
7384 // PUSH_PROMISE handling in the http layer gets exercised here.
7385 SendRequestAndExpectQuicResponse("hello!");
7386
7387 request_.url = GURL("https://mail.example.org/pushed.jpg");
7388 ChunkedUploadDataStream upload_data(0);
7389 upload_data.AppendData("1", 1, true);
7390 request_.upload_data_stream = &upload_data;
7391 SendRequestAndExpectQuicResponse("and hello!");
7392}
7393
Bence Béky7538a952018-02-01 16:59:527394// Regression test for https://crbug.com/797825: If pushed headers describe a
7395// valid URL with empty hostname, then X509Certificate::VerifyHostname() must
7396// not be called (otherwise a DCHECK fails).
7397TEST_P(QuicNetworkTransactionTest, QuicServerPushWithEmptyHostname) {
Ryan Hamilton0239aac2018-05-19 00:03:137398 spdy::SpdyHeaderBlock pushed_request_headers;
Bence Béky7538a952018-02-01 16:59:527399 pushed_request_headers[":authority"] = "";
7400 pushed_request_headers[":method"] = "GET";
7401 pushed_request_headers[":path"] = "/";
7402 pushed_request_headers[":scheme"] = "nosuchscheme";
7403
7404 session_params_.origins_to_force_quic_on.insert(
7405 HostPortPair::FromString("mail.example.org:443"));
7406
7407 MockQuicData mock_quic_data;
7408
Ryan Hamilton8d9ee76e2018-05-29 23:52:527409 quic::QuicStreamOffset header_stream_offset = 0;
Bence Béky7538a952018-02-01 16:59:527410 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437411 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7412 mock_quic_data.AddWrite(
7413 SYNCHRONOUS,
7414 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337415 2, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
Zhongyi Shi32f2fd02018-04-16 18:23:437416 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
Bence Béky7538a952018-02-01 16:59:527417
Ryan Hamilton8d9ee76e2018-05-29 23:52:527418 quic::QuicStreamOffset server_header_offset = 0;
Fan Yang32c5a112018-12-10 20:06:337419 mock_quic_data.AddRead(
7420 ASYNC, ConstructServerPushPromisePacket(
7421 1, GetNthClientInitiatedBidirectionalStreamId(0),
7422 GetNthServerInitiatedUnidirectionalStreamId(0), false,
7423 std::move(pushed_request_headers), &server_header_offset,
7424 &server_maker_));
7425 mock_quic_data.AddWrite(SYNCHRONOUS,
7426 ConstructClientRstPacket(
7427 3, GetNthServerInitiatedUnidirectionalStreamId(0),
7428 quic::QUIC_INVALID_PROMISE_URL, 0));
Bence Béky7538a952018-02-01 16:59:527429
Zhongyi Shi32f2fd02018-04-16 18:23:437430 mock_quic_data.AddRead(
7431 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337432 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437433 GetResponseHeaders("200 OK"), &server_header_offset));
7434 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 2, 1, 1));
Bence Béky7538a952018-02-01 16:59:527435
Zhongyi Shi32f2fd02018-04-16 18:23:437436 mock_quic_data.AddRead(
7437 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337438 3, GetNthServerInitiatedUnidirectionalStreamId(0), false,
7439 false, GetResponseHeaders("200 OK"), &server_header_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437440 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337441 ASYNC, ConstructServerDataPacket(
7442 4, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7443 0, "hello!"));
Zhongyi Shi32f2fd02018-04-16 18:23:437444 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 4, 3, 1));
Bence Béky7538a952018-02-01 16:59:527445
7446 mock_quic_data.AddRead(ASYNC, 0);
7447 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7448
7449 // The non-alternate protocol job needs to hang in order to guarantee that
7450 // the alternate-protocol job will "win".
7451 AddHangingNonAlternateProtocolSocketData();
7452
7453 CreateSession();
7454
7455 // PUSH_PROMISE handling in the http layer gets exercised here.
7456 SendRequestAndExpectQuicResponse("hello!");
7457
7458 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7459 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7460}
7461
Yixin Wang46a273ec302018-01-23 17:59:567462// Performs an HTTPS/1.1 request over QUIC proxy tunnel.
7463TEST_P(QuicNetworkTransactionTest, QuicProxyConnectHttpsServer) {
7464 session_params_.enable_quic = true;
7465 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497466 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567467
7468 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527469 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567470 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437471 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337472 mock_quic_data.AddWrite(
7473 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7474 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7475 false, ConnectRequestHeaders("mail.example.org:443"),
7476 &header_stream_offset));
7477 mock_quic_data.AddRead(
7478 ASYNC, ConstructServerResponseHeadersPacket(
7479 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7480 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567481
7482 const char get_request[] =
7483 "GET / HTTP/1.1\r\n"
7484 "Host: mail.example.org\r\n"
7485 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437486 mock_quic_data.AddWrite(
7487 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Fan Yang32c5a112018-12-10 20:06:337488 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
7489 1, 1, 1, false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567490 const char get_response[] =
7491 "HTTP/1.1 200 OK\r\n"
7492 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437493 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337494 ASYNC, ConstructServerDataPacket(
7495 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7496 0, quic::QuicStringPiece(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527497
Fan Yang32c5a112018-12-10 20:06:337498 mock_quic_data.AddRead(
7499 SYNCHRONOUS,
7500 ConstructServerDataPacket(
7501 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7502 strlen(get_response), quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437503 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567504 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7505
7506 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337507 SYNCHRONOUS, ConstructClientRstPacket(
7508 5, GetNthClientInitiatedBidirectionalStreamId(0),
7509 quic::QUIC_STREAM_CANCELLED, strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567510
7511 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7512
7513 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7514
7515 CreateSession();
7516
7517 request_.url = GURL("https://mail.example.org/");
7518 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7519 HeadersHandler headers_handler;
7520 trans.SetBeforeHeadersSentCallback(
7521 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7522 base::Unretained(&headers_handler)));
7523 RunTransaction(&trans);
7524 CheckWasHttpResponse(&trans);
7525 CheckResponsePort(&trans, 70);
7526 CheckResponseData(&trans, "0123456789");
7527 EXPECT_TRUE(headers_handler.was_proxied());
7528 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7529
7530 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7531 // proxy socket to disconnect.
7532 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7533
7534 base::RunLoop().RunUntilIdle();
7535 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7536 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7537}
7538
7539// Performs an HTTP/2 request over QUIC proxy tunnel.
7540TEST_P(QuicNetworkTransactionTest, QuicProxyConnectSpdyServer) {
7541 session_params_.enable_quic = true;
7542 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497543 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567544
7545 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527546 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567547 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437548 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337549 mock_quic_data.AddWrite(
7550 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7551 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7552 false, ConnectRequestHeaders("mail.example.org:443"),
7553 &header_stream_offset));
7554 mock_quic_data.AddRead(
7555 ASYNC, ConstructServerResponseHeadersPacket(
7556 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7557 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567558
7559 SpdyTestUtil spdy_util;
7560
Ryan Hamilton0239aac2018-05-19 00:03:137561 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567562 spdy_util.ConstructSpdyGet("https://mail.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:437563 mock_quic_data.AddWrite(
7564 SYNCHRONOUS,
7565 ConstructClientAckAndDataPacket(
Fan Yang32c5a112018-12-10 20:06:337566 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7567 false, 0, quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Ryan Hamilton0239aac2018-05-19 00:03:137568 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567569 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437570 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337571 ASYNC,
7572 ConstructServerDataPacket(
7573 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false, 0,
7574 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567575
Ryan Hamilton0239aac2018-05-19 00:03:137576 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197577 spdy_util.ConstructSpdyDataFrame(1, "0123456789", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437578 mock_quic_data.AddRead(
7579 SYNCHRONOUS,
7580 ConstructServerDataPacket(
Fan Yang32c5a112018-12-10 20:06:337581 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7582 resp_frame.size(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527583 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Zhongyi Shi32f2fd02018-04-16 18:23:437584 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567585 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7586
7587 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437588 SYNCHRONOUS,
Fan Yang32c5a112018-12-10 20:06:337589 ConstructClientRstPacket(5, GetNthClientInitiatedBidirectionalStreamId(0),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527590 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:567591
7592 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7593
7594 SSLSocketDataProvider ssl_data(ASYNC, OK);
7595 ssl_data.next_proto = kProtoHTTP2;
7596 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7597
7598 CreateSession();
7599
7600 request_.url = GURL("https://mail.example.org/");
7601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7602 HeadersHandler headers_handler;
7603 trans.SetBeforeHeadersSentCallback(
7604 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7605 base::Unretained(&headers_handler)));
7606 RunTransaction(&trans);
7607 CheckWasSpdyResponse(&trans);
7608 CheckResponsePort(&trans, 70);
7609 CheckResponseData(&trans, "0123456789");
7610 EXPECT_TRUE(headers_handler.was_proxied());
7611 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
7612
Wez0e717112018-06-18 23:09:227613 // Causes MockSSLClientSocket to disconproxyconnecthttpnect, which causes the
7614 // underlying QUIC proxy socket to disconnect.
Yixin Wang46a273ec302018-01-23 17:59:567615 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7616
7617 base::RunLoop().RunUntilIdle();
7618 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7619 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7620}
7621
7622// Make two HTTP/1.1 requests to the same host over a QUIC proxy tunnel and
7623// check that the proxy socket is reused for the second request.
7624TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseTransportSocket) {
7625 session_params_.enable_quic = true;
7626 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497627 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567628
7629 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527630 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567631 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437632 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337633 mock_quic_data.AddWrite(
7634 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7635 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7636 false, ConnectRequestHeaders("mail.example.org:443"),
7637 &header_stream_offset));
7638 mock_quic_data.AddRead(
7639 ASYNC, ConstructServerResponseHeadersPacket(
7640 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7641 GetResponseHeaders("200 OK")));
Yixin Wang46a273ec302018-01-23 17:59:567642
Ryan Hamilton8d9ee76e2018-05-29 23:52:527643 quic::QuicStreamOffset client_data_offset = 0;
7644 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567645 const char get_request_1[] =
7646 "GET / HTTP/1.1\r\n"
7647 "Host: mail.example.org\r\n"
7648 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437649 mock_quic_data.AddWrite(
7650 SYNCHRONOUS,
7651 ConstructClientAckAndDataPacket(
Fan Yang32c5a112018-12-10 20:06:337652 3, false, GetNthClientInitiatedBidirectionalStreamId(0), 1, 1, 1,
7653 false, client_data_offset, quic::QuicStringPiece(get_request_1)));
Yixin Wang46a273ec302018-01-23 17:59:567654 client_data_offset += strlen(get_request_1);
7655
7656 const char get_response_1[] =
7657 "HTTP/1.1 200 OK\r\n"
7658 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437659 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337660 ASYNC, ConstructServerDataPacket(
7661 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7662 server_data_offset, quic::QuicStringPiece(get_response_1)));
Yixin Wang46a273ec302018-01-23 17:59:567663 server_data_offset += strlen(get_response_1);
7664
Fan Yang32c5a112018-12-10 20:06:337665 mock_quic_data.AddRead(
7666 SYNCHRONOUS,
7667 ConstructServerDataPacket(
7668 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7669 server_data_offset, quic::QuicStringPiece("0123456789")));
Yixin Wang46a273ec302018-01-23 17:59:567670 server_data_offset += 10;
7671
Zhongyi Shi32f2fd02018-04-16 18:23:437672 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567673
7674 const char get_request_2[] =
7675 "GET /2 HTTP/1.1\r\n"
7676 "Host: mail.example.org\r\n"
7677 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437678 mock_quic_data.AddWrite(
Ryan Hamilton8d9ee76e2018-05-29 23:52:527679 SYNCHRONOUS,
Fan Yang32c5a112018-12-10 20:06:337680 ConstructClientDataPacket(
7681 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7682 client_data_offset, quic::QuicStringPiece(get_request_2)));
Yixin Wang46a273ec302018-01-23 17:59:567683 client_data_offset += strlen(get_request_2);
7684
7685 const char get_response_2[] =
7686 "HTTP/1.1 200 OK\r\n"
7687 "Content-Length: 7\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437688 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337689 ASYNC, ConstructServerDataPacket(
7690 4, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7691 server_data_offset, quic::QuicStringPiece(get_response_2)));
Yixin Wang46a273ec302018-01-23 17:59:567692 server_data_offset += strlen(get_response_2);
7693
Ryan Hamilton8d9ee76e2018-05-29 23:52:527694 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337695 SYNCHRONOUS,
7696 ConstructServerDataPacket(
7697 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7698 server_data_offset, quic::QuicStringPiece("0123456")));
Yixin Wang46a273ec302018-01-23 17:59:567699 server_data_offset += 7;
7700
Zhongyi Shi32f2fd02018-04-16 18:23:437701 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 5, 4, 1));
Yixin Wang46a273ec302018-01-23 17:59:567702 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7703
Fan Yang32c5a112018-12-10 20:06:337704 mock_quic_data.AddWrite(SYNCHRONOUS,
7705 ConstructClientRstPacket(
7706 7, GetNthClientInitiatedBidirectionalStreamId(0),
7707 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:567708
7709 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7710
7711 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7712
7713 CreateSession();
7714
7715 request_.url = GURL("https://mail.example.org/");
7716 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7717 HeadersHandler headers_handler_1;
7718 trans_1.SetBeforeHeadersSentCallback(
7719 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7720 base::Unretained(&headers_handler_1)));
7721 RunTransaction(&trans_1);
7722 CheckWasHttpResponse(&trans_1);
7723 CheckResponsePort(&trans_1, 70);
7724 CheckResponseData(&trans_1, "0123456789");
7725 EXPECT_TRUE(headers_handler_1.was_proxied());
7726 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7727
7728 request_.url = GURL("https://mail.example.org/2");
7729 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7730 HeadersHandler headers_handler_2;
7731 trans_2.SetBeforeHeadersSentCallback(
7732 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7733 base::Unretained(&headers_handler_2)));
7734 RunTransaction(&trans_2);
7735 CheckWasHttpResponse(&trans_2);
7736 CheckResponsePort(&trans_2, 70);
7737 CheckResponseData(&trans_2, "0123456");
7738 EXPECT_TRUE(headers_handler_2.was_proxied());
7739 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7740
7741 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7742 // proxy socket to disconnect.
7743 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7744
7745 base::RunLoop().RunUntilIdle();
7746 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7747 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7748}
7749
7750// Make an HTTP/1.1 request to one host and an HTTP/2 request to a different
7751// host over a QUIC proxy tunnel. Check that the QUIC session to the proxy
7752// server is reused for the second request.
7753TEST_P(QuicNetworkTransactionTest, QuicProxyConnectReuseQuicSession) {
7754 session_params_.enable_quic = true;
7755 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497756 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567757
7758 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527759 quic::QuicStreamOffset client_header_stream_offset = 0;
7760 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437761 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7762 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567763
7764 // CONNECT request and response for first request
Fan Yang32c5a112018-12-10 20:06:337765 mock_quic_data.AddWrite(
7766 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7767 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7768 false, ConnectRequestHeaders("mail.example.org:443"),
7769 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437770 mock_quic_data.AddRead(
7771 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337772 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437773 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567774
7775 // GET request, response, and data over QUIC tunnel for first request
7776 const char get_request[] =
7777 "GET / HTTP/1.1\r\n"
7778 "Host: mail.example.org\r\n"
7779 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:437780 mock_quic_data.AddWrite(
7781 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Fan Yang32c5a112018-12-10 20:06:337782 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
7783 1, 1, 1, false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567784 const char get_response[] =
7785 "HTTP/1.1 200 OK\r\n"
7786 "Content-Length: 10\r\n\r\n";
7787 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337788 ASYNC, ConstructServerDataPacket(
7789 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7790 0, quic::QuicStringPiece(get_response)));
7791 mock_quic_data.AddRead(
7792 SYNCHRONOUS,
7793 ConstructServerDataPacket(
7794 3, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
7795 strlen(get_response), quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:437796 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(4, 3, 2, 1));
Yixin Wang46a273ec302018-01-23 17:59:567797
7798 // CONNECT request and response for second request
Zhongyi Shi32f2fd02018-04-16 18:23:437799 mock_quic_data.AddWrite(
7800 SYNCHRONOUS,
7801 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337802 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437803 ConnectRequestHeaders("different.example.org:443"),
Fan Yang32c5a112018-12-10 20:06:337804 GetNthClientInitiatedBidirectionalStreamId(0),
7805 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437806 mock_quic_data.AddRead(
7807 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337808 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437809 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567810
7811 // GET request, response, and data over QUIC tunnel for second request
7812 SpdyTestUtil spdy_util;
Ryan Hamilton0239aac2018-05-19 00:03:137813 spdy::SpdySerializedFrame get_frame =
Yixin Wang46a273ec302018-01-23 17:59:567814 spdy_util.ConstructSpdyGet("https://different.example.org/", 1, LOWEST);
Zhongyi Shi32f2fd02018-04-16 18:23:437815 mock_quic_data.AddWrite(
7816 SYNCHRONOUS,
7817 ConstructClientAckAndDataPacket(
Fan Yang32c5a112018-12-10 20:06:337818 6, false, GetNthClientInitiatedBidirectionalStreamId(1), 4, 4, 1,
7819 false, 0, quic::QuicStringPiece(get_frame.data(), get_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567820
Ryan Hamilton0239aac2018-05-19 00:03:137821 spdy::SpdySerializedFrame resp_frame =
Yixin Wang46a273ec302018-01-23 17:59:567822 spdy_util.ConstructSpdyGetReply(nullptr, 0, 1);
Zhongyi Shi32f2fd02018-04-16 18:23:437823 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337824 ASYNC,
7825 ConstructServerDataPacket(
7826 5, GetNthClientInitiatedBidirectionalStreamId(1), false, false, 0,
7827 quic::QuicStringPiece(resp_frame.data(), resp_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567828
Ryan Hamilton0239aac2018-05-19 00:03:137829 spdy::SpdySerializedFrame data_frame =
Bence Békyd74f4382018-02-20 18:26:197830 spdy_util.ConstructSpdyDataFrame(1, "0123456", true);
Zhongyi Shi32f2fd02018-04-16 18:23:437831 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:337832 ASYNC, ConstructServerDataPacket(
7833 6, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
7834 resp_frame.size(),
7835 quic::QuicStringPiece(data_frame.data(), data_frame.size())));
Yixin Wang46a273ec302018-01-23 17:59:567836
Zhongyi Shi32f2fd02018-04-16 18:23:437837 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(7, 6, 5, 1));
Yixin Wang46a273ec302018-01-23 17:59:567838 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7839
7840 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337841 SYNCHRONOUS, ConstructClientRstPacket(
7842 8, GetNthClientInitiatedBidirectionalStreamId(0),
7843 quic::QUIC_STREAM_CANCELLED, strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:567844 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437845 SYNCHRONOUS,
Fan Yang32c5a112018-12-10 20:06:337846 ConstructClientRstPacket(9, GetNthClientInitiatedBidirectionalStreamId(1),
Ryan Hamilton8d9ee76e2018-05-29 23:52:527847 quic::QUIC_STREAM_CANCELLED, get_frame.size()));
Yixin Wang46a273ec302018-01-23 17:59:567848
7849 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7850
7851 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7852
7853 SSLSocketDataProvider ssl_data(ASYNC, OK);
7854 ssl_data.next_proto = kProtoHTTP2;
7855 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
7856
7857 CreateSession();
7858
7859 request_.url = GURL("https://mail.example.org/");
7860 HttpNetworkTransaction trans_1(DEFAULT_PRIORITY, session_.get());
7861 HeadersHandler headers_handler_1;
7862 trans_1.SetBeforeHeadersSentCallback(
7863 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7864 base::Unretained(&headers_handler_1)));
7865 RunTransaction(&trans_1);
7866 CheckWasHttpResponse(&trans_1);
7867 CheckResponsePort(&trans_1, 70);
7868 CheckResponseData(&trans_1, "0123456789");
7869 EXPECT_TRUE(headers_handler_1.was_proxied());
7870 EXPECT_TRUE(trans_1.GetResponseInfo()->proxy_server.is_quic());
7871
7872 request_.url = GURL("https://different.example.org/");
7873 HttpNetworkTransaction trans_2(DEFAULT_PRIORITY, session_.get());
7874 HeadersHandler headers_handler_2;
7875 trans_2.SetBeforeHeadersSentCallback(
7876 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7877 base::Unretained(&headers_handler_2)));
7878 RunTransaction(&trans_2);
7879 CheckWasSpdyResponse(&trans_2);
7880 CheckResponsePort(&trans_2, 70);
7881 CheckResponseData(&trans_2, "0123456");
7882 EXPECT_TRUE(headers_handler_2.was_proxied());
7883 EXPECT_TRUE(trans_2.GetResponseInfo()->proxy_server.is_quic());
7884
7885 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
7886 // proxy socket to disconnect.
7887 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
7888
7889 base::RunLoop().RunUntilIdle();
7890 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7891 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7892}
7893
7894// Sends a CONNECT request to a QUIC proxy and receive a 500 response.
7895TEST_P(QuicNetworkTransactionTest, QuicProxyConnectFailure) {
7896 session_params_.enable_quic = true;
7897 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497898 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567899
7900 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527901 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567902 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437903 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Ryan Hamilton8d9ee76e2018-05-29 23:52:527904 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:337905 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7906 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7907 false, ConnectRequestHeaders("mail.example.org:443"),
7908 &header_stream_offset));
7909 mock_quic_data.AddRead(
7910 ASYNC, ConstructServerResponseHeadersPacket(
7911 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7912 GetResponseHeaders("500")));
7913 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
7914 mock_quic_data.AddWrite(SYNCHRONOUS,
7915 ConstructClientAckAndRstPacket(
7916 3, GetNthClientInitiatedBidirectionalStreamId(0),
7917 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:567918
7919 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7920
7921 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
7922
7923 CreateSession();
7924
7925 request_.url = GURL("https://mail.example.org/");
7926 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7927 HeadersHandler headers_handler;
7928 trans.SetBeforeHeadersSentCallback(
7929 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7930 base::Unretained(&headers_handler)));
7931 TestCompletionCallback callback;
7932 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7933 EXPECT_EQ(ERR_IO_PENDING, rv);
7934 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, callback.WaitForResult());
7935 EXPECT_EQ(false, headers_handler.was_proxied());
7936
7937 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7938 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7939}
7940
7941// Sends a CONNECT request to a QUIC proxy and get a UDP socket read error.
7942TEST_P(QuicNetworkTransactionTest, QuicProxyQuicConnectionError) {
7943 session_params_.enable_quic = true;
7944 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497945 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567946
7947 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527948 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:567949 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:437950 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337951 mock_quic_data.AddWrite(
7952 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7953 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7954 false, ConnectRequestHeaders("mail.example.org:443"),
7955 &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:567956 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
7957
7958 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
7959
7960 CreateSession();
7961
7962 request_.url = GURL("https://mail.example.org/");
7963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
7964 HeadersHandler headers_handler;
7965 trans.SetBeforeHeadersSentCallback(
7966 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
7967 base::Unretained(&headers_handler)));
7968 TestCompletionCallback callback;
7969 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
7970 EXPECT_EQ(ERR_IO_PENDING, rv);
7971 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
7972
7973 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
7974 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
7975}
7976
7977// Sends an HTTP/1.1 request over QUIC proxy tunnel and gets a bad cert from the
7978// host. Retries request and succeeds.
7979TEST_P(QuicNetworkTransactionTest, QuicProxyConnectBadCertificate) {
7980 session_params_.enable_quic = true;
7981 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:497982 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:567983
7984 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:527985 quic::QuicStreamOffset client_header_stream_offset = 0;
7986 quic::QuicStreamOffset server_header_stream_offset = 0;
Zhongyi Shi32f2fd02018-04-16 18:23:437987 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
7988 1, &client_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337989 mock_quic_data.AddWrite(
7990 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
7991 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7992 false, ConnectRequestHeaders("mail.example.org:443"),
7993 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:437994 mock_quic_data.AddRead(
7995 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:337996 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:437997 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:337998 mock_quic_data.AddWrite(SYNCHRONOUS,
7999 ConstructClientAckAndRstPacket(
8000 3, GetNthClientInitiatedBidirectionalStreamId(0),
8001 quic::QUIC_STREAM_CANCELLED, 1, 1, 1));
Yixin Wang46a273ec302018-01-23 17:59:568002
Zhongyi Shi32f2fd02018-04-16 18:23:438003 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338004 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8005 4, GetNthClientInitiatedBidirectionalStreamId(1), false,
8006 false, ConnectRequestHeaders("mail.example.org:443"),
8007 GetNthClientInitiatedBidirectionalStreamId(0),
8008 &client_header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438009 mock_quic_data.AddRead(
8010 ASYNC, ConstructServerResponseHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338011 2, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
Zhongyi Shi32f2fd02018-04-16 18:23:438012 GetResponseHeaders("200 OK"), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568013
8014 const char get_request[] =
8015 "GET / HTTP/1.1\r\n"
8016 "Host: mail.example.org\r\n"
8017 "Connection: keep-alive\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:438018 mock_quic_data.AddWrite(
8019 SYNCHRONOUS, ConstructClientAckAndDataPacket(
Fan Yang32c5a112018-12-10 20:06:338020 5, false, GetNthClientInitiatedBidirectionalStreamId(1),
8021 2, 2, 1, false, 0, quic::QuicStringPiece(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:568022 const char get_response[] =
8023 "HTTP/1.1 200 OK\r\n"
8024 "Content-Length: 10\r\n\r\n";
Zhongyi Shi32f2fd02018-04-16 18:23:438025 mock_quic_data.AddRead(
Fan Yang32c5a112018-12-10 20:06:338026 ASYNC, ConstructServerDataPacket(
8027 3, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8028 0, quic::QuicStringPiece(get_response)));
Ryan Hamilton8d9ee76e2018-05-29 23:52:528029
Fan Yang32c5a112018-12-10 20:06:338030 mock_quic_data.AddRead(
8031 SYNCHRONOUS,
8032 ConstructServerDataPacket(
8033 4, GetNthClientInitiatedBidirectionalStreamId(1), false, false,
8034 strlen(get_response), quic::QuicStringPiece("0123456789")));
Zhongyi Shi32f2fd02018-04-16 18:23:438035 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(6, 4, 3, 1));
Yixin Wang46a273ec302018-01-23 17:59:568036 mock_quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read
8037
8038 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338039 SYNCHRONOUS, ConstructClientRstPacket(
8040 7, GetNthClientInitiatedBidirectionalStreamId(1),
8041 quic::QUIC_STREAM_CANCELLED, strlen(get_request)));
Yixin Wang46a273ec302018-01-23 17:59:568042
8043 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8044
8045 SSLSocketDataProvider ssl_data_bad_cert(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8046 socket_factory_.AddSSLSocketDataProvider(&ssl_data_bad_cert);
8047
8048 SSLSocketDataProvider ssl_data(ASYNC, OK);
8049 socket_factory_.AddSSLSocketDataProvider(&ssl_data);
8050
8051 CreateSession();
8052
8053 request_.url = GURL("https://mail.example.org/");
8054 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8055 HeadersHandler headers_handler;
8056 trans.SetBeforeHeadersSentCallback(
8057 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8058 base::Unretained(&headers_handler)));
8059 TestCompletionCallback callback;
8060 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8061 EXPECT_EQ(ERR_IO_PENDING, rv);
8062 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, callback.WaitForResult());
8063
8064 rv = trans.RestartIgnoringLastError(callback.callback());
8065 EXPECT_EQ(ERR_IO_PENDING, rv);
8066 EXPECT_EQ(OK, callback.WaitForResult());
8067
8068 CheckWasHttpResponse(&trans);
8069 CheckResponsePort(&trans, 70);
8070 CheckResponseData(&trans, "0123456789");
8071 EXPECT_EQ(true, headers_handler.was_proxied());
8072 EXPECT_TRUE(trans.GetResponseInfo()->proxy_server.is_quic());
8073
8074 // Causes MockSSLClientSocket to disconnect, which causes the underlying QUIC
8075 // proxy socket to disconnect.
8076 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
8077
8078 base::RunLoop().RunUntilIdle();
8079 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8080 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8081}
8082
8083// Checks if a request's specified "user-agent" header shows up correctly in the
8084// CONNECT request to a QUIC proxy.
8085TEST_P(QuicNetworkTransactionTest, QuicProxyUserAgent) {
8086 session_params_.enable_quic = true;
8087 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498088 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568089
8090 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528091 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568092 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438093 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568094
Ryan Hamilton0239aac2018-05-19 00:03:138095 spdy::SpdyHeaderBlock headers = ConnectRequestHeaders("mail.example.org:443");
Yixin Wang46a273ec302018-01-23 17:59:568096 headers["user-agent"] = "Chromium Ultra Awesome X Edition";
Fan Yang32c5a112018-12-10 20:06:338097 mock_quic_data.AddWrite(
8098 SYNCHRONOUS, ConstructClientRequestHeadersPacket(
8099 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8100 false, std::move(headers), &header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568101 // Return an error, so the transaction stops here (this test isn't interested
8102 // in the rest).
8103 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8104
8105 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8106
8107 CreateSession();
8108
8109 request_.url = GURL("https://mail.example.org/");
8110 request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8111 "Chromium Ultra Awesome X Edition");
8112 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8113 HeadersHandler headers_handler;
8114 trans.SetBeforeHeadersSentCallback(
8115 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8116 base::Unretained(&headers_handler)));
8117 TestCompletionCallback callback;
8118 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8119 EXPECT_EQ(ERR_IO_PENDING, rv);
8120 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8121
8122 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8123 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8124}
8125
Yixin Wang00fc44c2018-01-23 21:12:208126// Makes sure the CONNECT request packet for a QUIC proxy contains the correct
8127// HTTP/2 stream dependency and weights given the request priority.
8128TEST_P(QuicNetworkTransactionTest, QuicProxyRequestPriority) {
8129 session_params_.enable_quic = true;
8130 proxy_resolution_service_ = ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498131 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang00fc44c2018-01-23 21:12:208132
8133 const RequestPriority request_priority = MEDIUM;
8134
8135 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528136 quic::QuicStreamOffset header_stream_offset = 0;
Yixin Wang00fc44c2018-01-23 21:12:208137 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438138 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8139 mock_quic_data.AddWrite(
8140 SYNCHRONOUS,
8141 ConstructClientRequestHeadersPacket(
Fan Yang32c5a112018-12-10 20:06:338142 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8143 request_priority, ConnectRequestHeaders("mail.example.org:443"), 0,
Zhongyi Shi32f2fd02018-04-16 18:23:438144 &header_stream_offset));
Yixin Wang00fc44c2018-01-23 21:12:208145 // Return an error, so the transaction stops here (this test isn't interested
8146 // in the rest).
8147 mock_quic_data.AddRead(ASYNC, ERR_CONNECTION_FAILED);
8148
8149 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8150
8151 CreateSession();
8152
8153 request_.url = GURL("https://mail.example.org/");
8154 HttpNetworkTransaction trans(request_priority, session_.get());
8155 TestCompletionCallback callback;
8156 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
8157 EXPECT_EQ(ERR_IO_PENDING, rv);
8158 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback.WaitForResult());
8159
8160 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8161 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8162}
8163
Yixin Wang46a273ec302018-01-23 17:59:568164// Test the request-challenge-retry sequence for basic auth, over a QUIC
8165// connection when setting up a QUIC proxy tunnel.
8166TEST_P(QuicNetworkTransactionTest, QuicProxyAuth) {
8167 const base::string16 kBaz(base::ASCIIToUTF16("baz"));
8168 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
Ryan Hamilton0239aac2018-05-19 00:03:138169 const spdy::SpdyPriority default_priority =
Yixin Wang46a273ec302018-01-23 17:59:568170 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
8171
8172 std::unique_ptr<QuicTestPacketMaker> client_maker;
8173 std::unique_ptr<QuicTestPacketMaker> server_maker;
8174
8175 // On the second pass, the body read of the auth challenge is synchronous, so
8176 // IsConnectedAndIdle returns false. The socket should still be drained and
8177 // reused. See http://crbug.com/544255.
8178 for (int i = 0; i < 2; ++i) {
Fan Yang32c5a112018-12-10 20:06:338179 client_maker.reset(new QuicTestPacketMaker(
8180 version_, quic::EmptyQuicConnectionId(), &clock_,
8181 kDefaultServerHostName, quic::Perspective::IS_CLIENT,
8182 client_headers_include_h2_stream_dependency_));
8183 server_maker.reset(new QuicTestPacketMaker(
8184 version_, quic::EmptyQuicConnectionId(), &clock_,
8185 kDefaultServerHostName, quic::Perspective::IS_SERVER, false));
Yixin Wang46a273ec302018-01-23 17:59:568186
8187 session_params_.enable_quic = true;
8188 proxy_resolution_service_ =
8189 ProxyResolutionService::CreateFixedFromPacResult(
Ramin Halavatica8d5252018-03-12 05:33:498190 "QUIC proxy.example.org:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Yixin Wang46a273ec302018-01-23 17:59:568191
8192 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528193 quic::QuicStreamOffset client_header_stream_offset = 0;
8194 quic::QuicStreamOffset server_header_stream_offset = 0;
8195 quic::QuicStreamOffset client_data_offset = 0;
8196 quic::QuicStreamOffset server_data_offset = 0;
Yixin Wang46a273ec302018-01-23 17:59:568197
Zhongyi Shi32f2fd02018-04-16 18:23:438198 mock_quic_data.AddWrite(SYNCHRONOUS,
8199 client_maker->MakeInitialSettingsPacket(
8200 1, &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568201
8202 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438203 SYNCHRONOUS,
Yixin Wang46a273ec302018-01-23 17:59:568204 client_maker->MakeRequestHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338205 2, GetNthClientInitiatedBidirectionalStreamId(0), true, false,
8206 default_priority,
Yixin Wang46a273ec302018-01-23 17:59:568207 client_maker->ConnectRequestHeaders("mail.example.org:443"), 0,
8208 &client_header_stream_offset));
8209
Ryan Hamilton0239aac2018-05-19 00:03:138210 spdy::SpdyHeaderBlock headers =
Yixin Wang46a273ec302018-01-23 17:59:568211 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8212 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8213 headers["content-length"] = "10";
8214 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438215 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338216 1, GetNthClientInitiatedBidirectionalStreamId(0), false,
8217 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568218
8219 if (i == 0) {
Zhongyi Shi32f2fd02018-04-16 18:23:438220 mock_quic_data.AddRead(
8221 ASYNC, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338222 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
8223 false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568224 } else {
Zhongyi Shi32f2fd02018-04-16 18:23:438225 mock_quic_data.AddRead(
8226 SYNCHRONOUS, server_maker->MakeDataPacket(
Fan Yang32c5a112018-12-10 20:06:338227 2, GetNthClientInitiatedBidirectionalStreamId(0),
8228 false, false, server_data_offset, "0123456789"));
Yixin Wang46a273ec302018-01-23 17:59:568229 }
8230 server_data_offset += 10;
8231
Zhongyi Shi32f2fd02018-04-16 18:23:438232 mock_quic_data.AddWrite(SYNCHRONOUS,
8233 client_maker->MakeAckPacket(3, 2, 1, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568234
8235 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338236 SYNCHRONOUS,
8237 client_maker->MakeRstPacket(
8238 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8239 quic::QUIC_STREAM_CANCELLED, client_data_offset));
Yixin Wang46a273ec302018-01-23 17:59:568240
8241 headers = client_maker->ConnectRequestHeaders("mail.example.org:443");
8242 headers["proxy-authorization"] = "Basic Zm9vOmJheg==";
8243 mock_quic_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338244 SYNCHRONOUS, client_maker->MakeRequestHeadersPacketWithOffsetTracking(
8245 5, GetNthClientInitiatedBidirectionalStreamId(1),
8246 false, false, default_priority, std::move(headers),
8247 GetNthClientInitiatedBidirectionalStreamId(0),
8248 &client_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568249
8250 // Response to wrong password
8251 headers =
8252 server_maker->GetResponseHeaders("407 Proxy Authentication Required");
8253 headers["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
8254 headers["content-length"] = "10";
8255 mock_quic_data.AddRead(
Zhongyi Shi32f2fd02018-04-16 18:23:438256 ASYNC, server_maker->MakeResponseHeadersPacketWithOffsetTracking(
Fan Yang32c5a112018-12-10 20:06:338257 3, GetNthClientInitiatedBidirectionalStreamId(1), false,
8258 false, std::move(headers), &server_header_stream_offset));
Yixin Wang46a273ec302018-01-23 17:59:568259 mock_quic_data.AddRead(SYNCHRONOUS,
8260 ERR_IO_PENDING); // No more data to read
8261
Fan Yang32c5a112018-12-10 20:06:338262 mock_quic_data.AddWrite(
8263 SYNCHRONOUS,
8264 client_maker->MakeAckAndRstPacket(
8265 6, false, GetNthClientInitiatedBidirectionalStreamId(1),
8266 quic::QUIC_STREAM_CANCELLED, 3, 3, 1, true));
Yixin Wang46a273ec302018-01-23 17:59:568267
8268 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8269 mock_quic_data.GetSequencedSocketData()->set_busy_before_sync_reads(true);
8270
8271 CreateSession();
8272
8273 request_.url = GURL("https://mail.example.org/");
8274 // Ensure that proxy authentication is attempted even
8275 // when the no authentication data flag is set.
8276 request_.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
8277 {
8278 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
8279 HeadersHandler headers_handler;
8280 trans.SetBeforeHeadersSentCallback(
8281 base::BindRepeating(&HeadersHandler::OnBeforeHeadersSent,
8282 base::Unretained(&headers_handler)));
8283 RunTransaction(&trans);
8284
8285 const HttpResponseInfo* response = trans.GetResponseInfo();
8286 ASSERT_TRUE(response != nullptr);
8287 ASSERT_TRUE(response->headers.get() != nullptr);
8288 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8289 response->headers->GetStatusLine());
8290 EXPECT_TRUE(response->headers->IsKeepAlive());
8291 EXPECT_EQ(407, response->headers->response_code());
8292 EXPECT_EQ(10, response->headers->GetContentLength());
8293 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8294 const AuthChallengeInfo* auth_challenge = response->auth_challenge.get();
8295 ASSERT_TRUE(auth_challenge != nullptr);
8296 EXPECT_TRUE(auth_challenge->is_proxy);
8297 EXPECT_EQ("https://proxy.example.org:70",
8298 auth_challenge->challenger.Serialize());
8299 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8300 EXPECT_EQ("basic", auth_challenge->scheme);
8301
8302 TestCompletionCallback callback;
8303 int rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
8304 callback.callback());
8305 EXPECT_EQ(ERR_IO_PENDING, rv);
8306 EXPECT_EQ(OK, callback.WaitForResult());
8307
8308 response = trans.GetResponseInfo();
8309 ASSERT_TRUE(response != nullptr);
8310 ASSERT_TRUE(response->headers.get() != nullptr);
8311 EXPECT_EQ("HTTP/1.1 407 Proxy Authentication Required",
8312 response->headers->GetStatusLine());
8313 EXPECT_TRUE(response->headers->IsKeepAlive());
8314 EXPECT_EQ(407, response->headers->response_code());
8315 EXPECT_EQ(10, response->headers->GetContentLength());
8316 EXPECT_EQ(HttpVersion(1, 1), response->headers->GetHttpVersion());
8317 auth_challenge = response->auth_challenge.get();
8318 ASSERT_TRUE(auth_challenge != nullptr);
8319 EXPECT_TRUE(auth_challenge->is_proxy);
8320 EXPECT_EQ("https://proxy.example.org:70",
8321 auth_challenge->challenger.Serialize());
8322 EXPECT_EQ("MyRealm1", auth_challenge->realm);
8323 EXPECT_EQ("basic", auth_challenge->scheme);
8324 }
8325 // HttpNetworkTransaction is torn down now that it's out of scope, causing
8326 // the QUIC stream to be cleaned up (since the proxy socket cannot be
8327 // reused because it's not connected).
8328 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8329 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8330 }
8331}
8332
Yixin Wang385652a2018-02-16 02:37:238333TEST_P(QuicNetworkTransactionTest, QuicServerPushUpdatesPriority) {
8334 // Only run this test if HTTP/2 stream dependency info is sent by client (sent
8335 // in HEADERS frames for requests and PRIORITY frames).
Zhongyi Shi7b4f22b2018-08-23 17:22:268336 if (version_ < quic::QUIC_VERSION_43 ||
Yixin Wang385652a2018-02-16 02:37:238337 !client_headers_include_h2_stream_dependency_) {
8338 return;
8339 }
8340
8341 session_params_.origins_to_force_quic_on.insert(
8342 HostPortPair::FromString("mail.example.org:443"));
8343
Fan Yang32c5a112018-12-10 20:06:338344 const quic::QuicStreamId client_stream_0 =
8345 GetNthClientInitiatedBidirectionalStreamId(0);
8346 const quic::QuicStreamId client_stream_1 =
8347 GetNthClientInitiatedBidirectionalStreamId(1);
8348 const quic::QuicStreamId client_stream_2 =
8349 GetNthClientInitiatedBidirectionalStreamId(2);
8350 const quic::QuicStreamId push_stream_0 =
8351 GetNthServerInitiatedUnidirectionalStreamId(0);
8352 const quic::QuicStreamId push_stream_1 =
8353 GetNthServerInitiatedUnidirectionalStreamId(1);
Yixin Wang385652a2018-02-16 02:37:238354
8355 MockQuicData mock_quic_data;
Ryan Hamilton8d9ee76e2018-05-29 23:52:528356 quic::QuicStreamOffset header_stream_offset = 0;
8357 quic::QuicStreamOffset server_header_offset = 0;
Yixin Wang385652a2018-02-16 02:37:238358 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438359 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238360
8361 // Client sends "GET" requests for "/0.png", "/1.png", "/2.png".
Zhongyi Shi32f2fd02018-04-16 18:23:438362 mock_quic_data.AddWrite(SYNCHRONOUS,
8363 ConstructClientRequestHeadersPacket(
8364 2, client_stream_0, true, true, HIGHEST,
8365 GetRequestHeaders("GET", "https", "/0.jpg"), 0,
8366 &header_stream_offset));
8367 mock_quic_data.AddWrite(SYNCHRONOUS,
8368 ConstructClientRequestHeadersPacket(
8369 3, client_stream_1, true, true, MEDIUM,
8370 GetRequestHeaders("GET", "https", "/1.jpg"),
8371 client_stream_0, &header_stream_offset));
8372 mock_quic_data.AddWrite(SYNCHRONOUS,
8373 ConstructClientRequestHeadersPacket(
8374 4, client_stream_2, true, true, MEDIUM,
8375 GetRequestHeaders("GET", "https", "/2.jpg"),
8376 client_stream_1, &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238377
8378 // Server replies "OK" for the three requests.
Zhongyi Shi32f2fd02018-04-16 18:23:438379 mock_quic_data.AddRead(
8380 ASYNC, ConstructServerResponseHeadersPacket(
8381 1, client_stream_0, false, false, GetResponseHeaders("200 OK"),
8382 &server_header_offset));
8383 mock_quic_data.AddRead(
8384 ASYNC, ConstructServerResponseHeadersPacket(
8385 2, client_stream_1, false, false, GetResponseHeaders("200 OK"),
8386 &server_header_offset));
8387 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(5, 2, 1, 1));
8388 mock_quic_data.AddRead(
8389 ASYNC, ConstructServerResponseHeadersPacket(
8390 3, client_stream_2, false, false, GetResponseHeaders("200 OK"),
8391 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238392
8393 // Server sends two push promises associated with |client_stream_0|; client
8394 // responds with a PRIORITY frame after each to notify server of HTTP/2 stream
8395 // dependency info for each push promise stream.
Zhongyi Shi32f2fd02018-04-16 18:23:438396 mock_quic_data.AddRead(ASYNC,
8397 ConstructServerPushPromisePacket(
8398 4, client_stream_0, push_stream_0, false,
8399 GetRequestHeaders("GET", "https", "/pushed_0.jpg"),
8400 &server_header_offset, &server_maker_));
Yixin Wang385652a2018-02-16 02:37:238401 mock_quic_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438402 SYNCHRONOUS,
8403 ConstructClientAckAndPriorityFramesPacket(
8404 6, false, 4, 3, 1,
8405 {{push_stream_0, client_stream_2,
8406 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)}},
8407 &header_stream_offset));
8408 mock_quic_data.AddRead(ASYNC,
8409 ConstructServerPushPromisePacket(
8410 5, client_stream_0, push_stream_1, false,
8411 GetRequestHeaders("GET", "https", "/pushed_1.jpg"),
8412 &server_header_offset, &server_maker_));
8413 mock_quic_data.AddWrite(
8414 SYNCHRONOUS,
Yixin Wang385652a2018-02-16 02:37:238415 ConstructClientPriorityPacket(7, false, push_stream_1, push_stream_0,
8416 DEFAULT_PRIORITY, &header_stream_offset));
8417
8418 // Server sends the response headers for the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438419 mock_quic_data.AddRead(
8420 ASYNC, ConstructServerResponseHeadersPacket(
8421 6, push_stream_0, false, false, GetResponseHeaders("200 OK"),
8422 &server_header_offset));
8423 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(8, 6, 5, 1));
8424 mock_quic_data.AddRead(
8425 ASYNC, ConstructServerResponseHeadersPacket(
8426 7, push_stream_1, false, false, GetResponseHeaders("200 OK"),
8427 &server_header_offset));
Yixin Wang385652a2018-02-16 02:37:238428
8429 // Request for "pushed_0.jpg" matches |push_stream_0|. |push_stream_0|'s
8430 // priority updates to match the request's priority. Client sends PRIORITY
8431 // frames to inform server of new HTTP/2 stream dependencies.
Zhongyi Shi32f2fd02018-04-16 18:23:438432 mock_quic_data.AddWrite(
8433 SYNCHRONOUS,
8434 ConstructClientAckAndPriorityFramesPacket(
8435 9, false, 7, 7, 1,
8436 {{push_stream_1, client_stream_2,
8437 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY)},
8438 {push_stream_0, client_stream_0,
8439 ConvertRequestPriorityToQuicPriority(HIGHEST)}},
8440 &header_stream_offset));
Yixin Wang385652a2018-02-16 02:37:238441
8442 // Server sends data for the three requests and the two push promises.
Zhongyi Shi32f2fd02018-04-16 18:23:438443 mock_quic_data.AddRead(
8444 ASYNC, ConstructServerDataPacket(8, client_stream_0, false, true, 0,
8445 "hello 0!"));
8446 mock_quic_data.AddRead(
8447 SYNCHRONOUS, ConstructServerDataPacket(9, client_stream_1, false, true, 0,
8448 "hello 1!"));
8449 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(10, 9, 8, 1));
8450 mock_quic_data.AddRead(
8451 ASYNC, ConstructServerDataPacket(10, client_stream_2, false, true, 0,
8452 "hello 2!"));
8453 mock_quic_data.AddRead(
8454 SYNCHRONOUS, ConstructServerDataPacket(11, push_stream_0, false, true, 0,
8455 "and hello 0!"));
8456 mock_quic_data.AddWrite(SYNCHRONOUS, ConstructClientAckPacket(11, 11, 10, 1));
8457 mock_quic_data.AddRead(
8458 ASYNC, ConstructServerDataPacket(12, push_stream_1, false, true, 0,
8459 "and hello 1!"));
Yixin Wang385652a2018-02-16 02:37:238460
Yixin Wang385652a2018-02-16 02:37:238461 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
8462 mock_quic_data.AddRead(ASYNC, 0); // EOF
8463 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
8464
8465 // The non-alternate protocol job needs to hang in order to guarantee that
8466 // the alternate-protocol job will "win".
8467 AddHangingNonAlternateProtocolSocketData();
8468
8469 CreateSession();
8470
8471 request_.url = GURL("https://mail.example.org/0.jpg");
8472 HttpNetworkTransaction trans_0(HIGHEST, session_.get());
8473 TestCompletionCallback callback_0;
8474 EXPECT_EQ(ERR_IO_PENDING,
8475 trans_0.Start(&request_, callback_0.callback(), net_log_.bound()));
8476 base::RunLoop().RunUntilIdle();
8477
8478 request_.url = GURL("https://mail.example.org/1.jpg");
8479 HttpNetworkTransaction trans_1(MEDIUM, session_.get());
8480 TestCompletionCallback callback_1;
8481 EXPECT_EQ(ERR_IO_PENDING,
8482 trans_1.Start(&request_, callback_1.callback(), net_log_.bound()));
8483 base::RunLoop().RunUntilIdle();
8484
8485 request_.url = GURL("https://mail.example.org/2.jpg");
8486 HttpNetworkTransaction trans_2(MEDIUM, session_.get());
8487 TestCompletionCallback callback_2;
8488 EXPECT_EQ(ERR_IO_PENDING,
8489 trans_2.Start(&request_, callback_2.callback(), net_log_.bound()));
8490 base::RunLoop().RunUntilIdle();
8491
8492 // Client makes request that matches resource pushed in |pushed_stream_0|.
8493 request_.url = GURL("https://mail.example.org/pushed_0.jpg");
8494 HttpNetworkTransaction trans_3(HIGHEST, session_.get());
8495 TestCompletionCallback callback_3;
8496 EXPECT_EQ(ERR_IO_PENDING,
8497 trans_3.Start(&request_, callback_3.callback(), net_log_.bound()));
8498 base::RunLoop().RunUntilIdle();
8499
8500 EXPECT_TRUE(callback_0.have_result());
8501 EXPECT_EQ(OK, callback_0.WaitForResult());
8502 EXPECT_TRUE(callback_1.have_result());
8503 EXPECT_EQ(OK, callback_1.WaitForResult());
8504 EXPECT_TRUE(callback_2.have_result());
8505 EXPECT_EQ(OK, callback_2.WaitForResult());
8506
8507 CheckResponseData(&trans_0, "hello 0!"); // Closes stream 5
8508 CheckResponseData(&trans_1, "hello 1!"); // Closes stream 7
8509 CheckResponseData(&trans_2, "hello 2!"); // Closes strema 9
8510 CheckResponseData(&trans_3, "and hello 0!"); // Closes stream 2, sends RST
8511
8512 mock_quic_data.Resume();
8513 base::RunLoop().RunUntilIdle();
8514 EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
8515 EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
8516}
8517
[email protected]61a527782013-02-21 03:58:008518} // namespace test
8519} // namespace net